【C++常识】C/C++指针

  1.何为指针:

  程序运行时,任何变量都是存放在内存中的,通过将内存以字节的大小划分,为每个字节增添索引,某一变量的地址就是该变量在内存中所占的第一个字节的索引。此时,定义一变量用来存放开始第一个字节的索引,这个变量就被称为指针,通过该变量的值可以间接的访问该指针所指向的变量。在32位系统中,指针的大小都是4字节,可以索引最大4G的内存。

  2.指针定义

int a = 10;
int *p = &a;int b[3] = {1,2,4};int *p = b;

  

  3.常见指针类型的识别

// *的优先级最低,当类型比较复杂时,一步一步的进行分析,还可以将某一部分看作整体进行简化分析
int        p;
int        *p;                // p与*结合,说明p是一个指针,再与int结合,说明p是一个指向int的指针
int        p[3];            // p与[]结合,说明P是数组,再与int结合,说明p是一个存放int变量的数组
int        *p[3];            // p与[]结合,说明p是一个数组,再与*结合,说明数组中存放的是指针,指针类型是int,说明p是一个指向存放int型指针数组的指针
int        (*p)[3];        // p与*结合,说明p是指针,再与[]结合,说明p指向一个数组,该数组里存放int
int        **p;            // p是一个只想int指针的指针
int        p(int);            // p是一个函数,该函数参数为int,返回类型为int
int        (*p)(int);        // p是一个指针,该指针指向一个函数,函数参数为int,返回类型为int
int   *(*p(int))[3];    // p是一个函数,该函数参数为int,返回类型为一个指针,该返回类型的指针指向一个数组,次数组中存放的是int的指针

  4.指针基本概念

    指针的类型:把指针名去掉后的类型就是指针的类型,比如int *prt的类型就是int *

    指针指向的类型:去掉指针名和*之后的类型,比如int *prt指向的类型就是int。

    指针的值:指针所指向的内存,也是指针变量所在内存中存放的值,在32位系统中指针是一个32位的变量,该值被当作一个地址,而不是简单的字面值

    指针的地址:指针本身在内存中的地址,该地址是不可改变的

  5.指针运算

    指针可以加上或减去一个整数,计算时,以指针所指向的类型大小为单位。

 例如:

typeA *ptr;
unsigned int addrA = (usigned int)ptr;
unsigned int addrB = (usigned int)(ptr + 1);
unsigned int ret = addrB - addrA;

  则ret的大小实际是sizeof(typeA)的大小,也就是ptr +1时,编辑器在ptr所指向内存的地方往后移动了sizeof(typeA)个字节。

分析以下打印的结果:

char a[20] = " You_are_a_girl";
char *p = a;
char **ptr = &p;

printf("**ptr=%c\n", **ptr);// Y
ptr++;
printf("**ptr=%c\n", **ptr);// 未定义

ptr为二级指针,*ptr等同于p,p指向a[0],则**ptr = ‘Y’

ptr为二级指针,*ptr指向p,也就是ptr存放的是p的地址,对ptr自增,相当于&p + sizeof(char *),并不指向a中的任何数据,行为未定义

  6.指针表达式

  如果一个表达式的结果是一个指针,则这个表达式称为指针表达式。 

  例:

char *str[3] = {
    "Hello,thisisasample!",
    "Hi,goodmorning.",
    "Helloworld"
};
chars[80];
strcpy(s, str[0]); //也可写成 strcpy(s,*str);
strcpy(s, str[1]); //也可写成 strcpy(s,*(str+1));

指针类型转换:

  不同的指针之间可以强制转换,也可以将整形当作一个地址强制转换为某一类型的指针。类型强制转换时需要保证源指针指向的类型所占字节不比转换后的类型小,否则可能造成越界。

struct st_type {
    int a;
    int b;
    int c;
};

struct st_type st = { 5,4,3 };
struct st_type *stptr = &st;
int *p = (int *)stptr;
(*p) = 1;    // 给a重新赋值
*(p + 1) = 3;  // 给b重新赋值
*(p + 2) = 5;  // 给c重新赋值

  在使用时,可能会由于字节对齐的原因导致通过上述方式存取是发生错误,使用前必须人为指定字节对齐的大小,比如:

#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐

struct st_aaaa{
    int a;
    int b;
    char c;
    long d;
};

#pragma pack(pop)//恢复对齐状态

  

时间: 2024-11-05 02:32:57

【C++常识】C/C++指针的相关文章

Linux下编程学习一

本篇主要记录一些在学习LINUX下编程时,, C和C++语言的一些基础的常识, 一. 函数指针 void MyFun(int x); 函数声明 void (*FunP)(int ); 函数指针声明 下面是C和C++中的指针定义  int (*pt2Function)(float, char, char) = NULL; // C普通函数指针 int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++中指向静态函数的指针 int (TM

C#网络程序设计(1)网络编程常识与C#常用特性

    网络程序设计能够帮我们了解联网应用的底层通信原理!     (1)网络编程常识: 1)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网络编程. 2)网络编程的层次 现实中的互联网是按照"TCP/IP分层协议栈"的体系结构构建的,因此程序员必须搞清楚自己要做的是哪个层次上的编程工作. TCP/IP协议体系的实现情况: 其中,网络接口层已经被大多数计算机生产厂家集成在了主板上,也就是经常所说的网卡(NIC).windows操

C++智能指针(3.30)

一.问题引入 关于C++中的new和delete操作符, 我们知道这两个操作符必须成对存在,才能避免内存泄漏. 这一点在学习的时候被认为是常识,然而,在实际编写代码的过程中,却常常很难做到. 下面有3种情况: 1.代码很长. 当需要用到delete的地方离使用与之对应的new操作符距离非常远时,我们很容易忘记delete.当然,这种情况是完全可以避免的. 2.如下面代码: void Test() { int *pi = new int(1); if(1) { return; } delete p

声明返回数组指针的函数

时间:2014.05.18 地点:基地 ------------------------------------------------------------------------ 一.基本知识 常识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. typedet int arr[10]; //arr是类型别名,表示的类型含有10个整数的数组 上述语句等效于 using arr=int[10] 在来复习几个基础知识 int arr[10]; //arr是一个含有10个整数的数

python入门常识

Django开发心得: filter方法可以使用count(),update().get方法不可以使用. 密码重置功能和修改功能.项目链接功能.(前端模板表单向后台传输数据时,有post和get两种方式:以action的属性值调用后台函数:在获取前端模板表单数据时,以name属性来获取,获取其中的value值.) 日志邮件提醒功能和项目到期提醒功能.(单独写一个python脚本,遍历数据库的信息,从而完成此项功能.主要采用python的SMTP和Email模块.) python入门常识: pyt

彻底搞定C语言指针详解

1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ 6 7 8 9 10 11 12 13 ----------------------------------------------------------------- ... | | | | | | | |.. ------------------------------- ---------------------------

指针数组,数组指针,指针函数,函数指针,二级指针详解

先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[]是一个数组,暂时把p[]看成是q,也就是char *(q),定义了一个指针q,只不过q是一个数组罢了,故定义了一个数组,数组里面的数据是char *的,所以数组里面的数据为指针类型.所以char *p[4]是四个指针,这四个指针组成了一个数组,称为指针数组,既有多个指针组成的数组. char(*p

函数指针玩得不熟,就不要自称为C语言高手(函数指针是解耦对象关系的最佳利器,还有signal)

记得刚开始工作时,一位高手告诉我说,longjmp和setjmp玩得不熟,就不要自称为C语言高手.当时我半信半疑,为了让自己向高手方向迈进,还是花了一点时间去学习longjmp和setjmp的用法.后来明白那不单是跳来跳去那样简单,而是一种高级的异常处理机制,在某些情况下确实很有用. 事实上,longjmp和 setjmp玩得熟不熟与是不是C语言高手,不是因果关系.但是,如果可以套用那位高手的话,我倒想说如果函数指针玩得不熟,就不要自称为C语言高手.为什么这么说呢,函数指针有那么复杂吗?当然不是

图解多级指针与“多维”数组

指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的.其中,多级指针与“多维”数组更是让很多人云里雾里,其实,只要掌握一定的方法,理解多级指针和“多维”数组完全可以像理解一级指针和一维数组那样简单. 首先,先声明一些常识,如果你对这些常识还不理解,那么你先去弥补一下基础知识: 1.实际上并不存在多维数组,所谓的多维数组本质上是用一维数组模拟的. 2.数组名是一个常量(意味着不允许对其进行赋值操作),其代表数组首元素的首地址. 3.数组与指针的关系是因为数组下标操作符[],比如,int