杂言
对它简单处理,它就简单;
对它复杂处理,它就复杂;
复杂难以把控,无法预测;
可预测的程度,关系成败;
指针的基本概念
指针和链表在c和c++语言是很基本的概念和功能。在其它语言也是重要的部分,只不过是退化了指针功能,封装起来进行管理用户不需要关心。
c语言是比较底层的语言,比汇编高级点。要能透彻的理解指针的运行原理最好能够简单了解下计算机的组成原理和主要过程,下图简单介绍了一个简单的计算程序是怎么运行的
通过上图中可以看出来,基本上所有的数据计算都是放在内存里面。内存通过一个个地址编号进行寻址。
指针就是为了描述地址而生的,所谓指针就是某个内存单元里面存储的是一个地址,而不是一个普通的数据值。我们以下面程序来说明指针变量和一般变量的内存里面存储的区别
int a, *p;
a = 1; p = &a; *p = 2;
printf("a=%d\n", a); 输出a=2
如下图:有几点说明
- 指针p是一个变量,它也有内存存储它,这里地址是001
- 指针p地址的存储的内容还是一个地址,指向的是一个地址004,这就是指针特殊的地方
- *p的运算是针对它指向地址里面的值的运算
- p=p+1 = 005 是指针本身值的运算,原来p=004,所以+1 = 005,具体要跳一个类型的长度
- &p = 001 只的是取的存储指针p的地址,也就是所谓的指针的指针**,所有的变量都有一个地方的存储
总结:
指针和一般其它的变量一样,有存储它的地方,它唯一区别是它存储的是一个地址
常见指针类型
结构体指针
typedef struct __aa {
int data;
int index;
}aa, *paa;
aa aa_test;
aa_test.data = aa_test.index = 1;
aa* p_aa_test = &aa_test;
p_aa_test是一个结指向aa_test的一个结构体指针,和一般的指针没有啥区别也是占一个地址,然后后面指向了一个结构体地址,这个结构体占8个字节
数组指针
int *p[3]; //定义一个数组指针
int a, b, c;
a = b = c = 1;
p[0] = &a; //给指针赋值
p[1] = &b;
p[2] = &c;
数组指针p有3个元素,每个元素是一个指针,每个元素存的值是一个地址,其它的和一般的数组基本一样。
多维指针
int a = 1;
int *p = &a; //一维指针
int **pp = &p; //二维指针
pp 是一个二维指针,是一个一维指向p的指针,p指向的a的地址,p=*pp。 三维等等都一样的理解
指针本身的运算
指针本身的运算和一般类型运算稍微有点区别,我们知道指针事实上就是存储了一个地址,那么它的运算肯定要和地址有关系,那是什么样的关系呢,对于 一个指针 p 那么 p++ 之后 p=?多少呢
看下面的代码和分析图就很清楚了
typedef struct __cc {
int data;
int index;
}cc, *pcc;
char a;
char *pa = &a; //定义一个字符指针
pa = pa+4;
int b;
int *pb = &b; //定义一个整形指针
pb = pb+1;
cc c;
cc *pc = &c; //定义一个结构体指针
pc = pc+1;
int *d;
int **pd; //定义一个整形二维指针
pd = pd+1;
如下图是上面指针 pa pb pc pd 执行加法操作后的结果,其中pa是加了4
总结一下,上面说了指针的运算是和地址有关系的,那么加1,理论上应该要指向下一个有效地址,因为每种类型的占用的地址宽不一样,所以下一个有效地址要在原基础上加上该类型的地址宽度,那么char占用地址宽度是1 ,int占用4,结构体cc占用8,一个一维指针占用4, 所以得到以上结果
总结
指针就是一个变量,只不过它只是执行地址的一个变量,它自己也有存储的地方,多维指针就是取指针的地址组合而成,后面再讨论指针用法的各个场景和注意点
版权归原作者 X-道至简 所有, 如有侵权,请联系我们删除。