c语言的申明,指针和数组的学习总结

c语言的申明的总结:
这周复习了一下c语言,下面是一些学习心得

首先是申明:
比如:extern char *( *hander)(int a);
那么这个申明该怎么理解呢?

A  申明按照它的名字开始读取,然后按照优先级顺序读取。
B  B1.括号
   B2:后缀操作符:包括()和[],()表示函数,[]表示数组
C  前缀操作符,*表示指向...的指针
D  有时含有const 关键字或valatile关键字

拿上面的例子来说吧,首先是hander这是名字,然后是括号(*hander),它表示的是一个指针,
然后是后缀(*hander)(int a),(int a)它表示的是函数的参数,所以(*hander)(int a)表示的
是函数指针,最后的char *,所以,整个就表示的是返回值为char *,参数为int a的函数指针。

以后遇到较为复杂的申明就按照上诉的顺序进行分析:
A- >B1->B2->C->D

有时候,如果含有const关键字,则分析如下:

(1)const char * a;
(2)char * const b;

则,(1)表示的是a指向的类容不可以修改,而a本身可以修改,
   (2)表示的是b本身不可以修改,而b指向的类容可以修改。

(2)其次是:指针和数值并不是一回事,而我们在大多数情况下总把他们当成是一样的呢
一般在下面3种情况下他们可以等同
1,在作为函数的参数的上下文的条件下,数组名就是指针
2,“在表达式中”,数组名就是指针
3,把数组的下标作为指针的偏移量

为什么在作为函数参数时把数组名当做指针呢?
是因为在函数的其他类型的参数调用都是值传递(把调用函数实参的做一个拷贝,函数不能修改实参,只能修改实参的拷贝),而如果数组也采用这种方法,无论是在时间上还是在空间上
都有很大的开销,而实际上,我们更多的时候只是在某一个时刻对某一数感兴趣,如果把数组名当做指针,让其指向数组的首地址,
而其他的参数传递都采用值传递,则可以简化编译器。

下面是数组指针不能当成一回事的情况之一:
(1)现在我们来看申明为数组时,对数据的访问过程
比如:
extern char a[i];
假设a的地址为7000,则读到地址7000,然后在7000上加上i,即地址7000+i,然后读出该地址的数
(2);如果我们申明为指针时呢?
比如extern int *b ;
则访问吧(b+i)的地址所代表的数是怎样一个过程呢?
同样假设b的地址是7000
根据地址b,读到7000,然后读出7000里的数,假设是4000,然后4000+i;最后读出地址(4000+i)里的数;

试想一下,如果我们定义为数组,申明为指针时,会放生什么情况?(实际相当的危险)
如果我们定义为指针,而申明为数组,则可以正常访问,只是访问的路径不同而已
而实际上,不管我们定义为数组还是指针,只要申明为指针,就按第二种方法访问的。
所以,我们最好是定义为啥就申明为啥,这时指针和数组不是一回事的。
c语言博大精深,慢慢遨游吧!!!

 

你可能感兴趣的:(c,BI,语言,编译器)