[转]对于C语言中指针和数组的认识和看法
[红字之间部分---对我自己的指引]
最重要的最具启发性的部分:指针和数组。
对经典话语的摘抄在此:
对于数组int a[5]; int b[3][6];
a是个const的type为array of 5 ints变量,
&a为取出array of 5 ints的首地址,但a的值在C中规定是数组首地址,不要乱联系。
&a在进行运算的时候取出的是类型array of ints的首地址,所以类型是pointer of array of ints.
a在进行运算的时候取出的是类型int的首地址,所以类型是pointer of int.
*p-----第一步取出存在p中地址,判断存在p中的当前的地址是指向的什么类型的变量,用*操作符将对应类型的值取出。
比如*a取出即为1个int。
比如*b取出的类型是:array of 6 ints
sizeof()-----是一个关键字,静态的判断该类型的大小。
比如sizeof(a)是静态的判断a为array of 5 ints类型,所以打印5*4=20。
sizeof(&a)是静态的判断&a,这个由运算得来的地址,是取得的array of 5 ints的地址,所以打印4。
如果传递a的值给函数作为参数,需要用int* p类型的变量。
如果传递&a的值给函数作为参数,需要用int (*p)[5]作为参数。
指针变量没有那么神秘,指针变量只是一个普通变量
假设指针pi存储的是q的地址。pi和q没有任何直接的关系。只有*pi才和q有直接的关系。
C语言只有一种函数参数传递方式:按值传递
[红字之间部分---对我自己的指引]
4. 指针与数组
4.1 数组名的类型
在C语言中,指针与数组千丝万缕的联系.看下面的例子:
int a[5];
int b[3][5];
int *pa1[5];
int (*pa2)[5];
那么a,b,pa1,pa2的类型到底是什么呢?
很多人将a的类型误解成为一级指针,即const pointer to int,
而将b的类型误解成为二级指针,即const pointer to the pointer to int;
a不是const pointer to int类型的,我们是可以从下面这个事实推出来的:
sizeof(a)跟sizeof(int*)是不同的.
只能说,a是array of 5 ints类型的
而b则是array of 3 arrays of 5 ints类型的
这里之所以把pa1和pa2列出来,主要是给大家区别一下:
pa1是array of 5 int pointers类型的,
而pa2是pointer to array of 5 ints类型的
4.2 数组名的运算
大家经常会遇到关于数组名的运算问题,比如
int a[5]={1, 2, 3, 4, 5};
int b[3][5]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}};
printf("%d", *(a+2));
printf("%d, %d\n", **(b+2), *(*b+2));
在进行上面的运算时,有下面的似非而是的结论:
&a可以看作是pointer to array of 5 ints类型的
所以&a+1,这里的“1”是指5*sizeof(int)
a是array of 5 ints类型的,但是a的值是什么呢?a的值其实是一个
pointer to int
*a的值则是一个int,即a[0];
&b可以看作是pointer to array of 3 arrays of 5 ints类型的
所以&b+1,这里的“1”是指3*5*sizeof(int)
b是array of 3 arrays of 5 ints类型的,但是b的值却是一个
pointer to array of 5 ints
*b是array of 5 ints类型的,但是*b的值却是pointer to int类型的
**b的值则是int类型的,即b[0][0];
4.3 一种常见错误
int b[3][5];
int **p=b;
有些人误认为p+1的值和b+1是相同的,其实不然
类似于
T1 b1;
T2* b2=(T2*)(&b1); //T1,T2为两种不同的类型
这样的话,b2+1是按sizeof(T2)进行增加的
而&b1+1是按照sizeof(T1)进行增加的
指针进行类型转换后,其运算跟他自身的类型有关,而与他指向的东东无关