[转]对于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)进行增加的
指针进行类型转换后,其运算跟他自身的类型有关,而与他指向的东东无关

posted @ 2011-09-02 23:39  Jack204  阅读(449)  评论(0编辑  收藏  举报