C和指针自己的理解记录

1:
const int n=5;
int const m=10;
上述两个变量n和m其实是同一种类型的??都是const int(整形恒量)。因为C 标准规定,const要害字放在类型或变量名之前等价的
2:
const int *p;//const int 类型的指针 不能通过*p修改去变量的值
int const *q;//但是q p的指针内容可以修改
3:
int类型的const指针应该这样声明:
int * const r= &n; //*r的值可以改变 r不可改变
4:
“右左法则”是一个简单的法则,但能让你准确理解所有的声明。这个法则运用如下:从最内部的括号开始阅读声明,向右看,然后向左看。当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围
5:
以自加( + + ) 为例. 自加形式有 i + + 和 +
+ i 两种 ,为了说明它们的区别 ,先分析两种情况.
第一种情况 ,当这两种形式中任何一种单独
作为一个 C 语句存在时 , 两者可以看作没有差
别 ,都等价于 i = i + 1. 如 :
①int i = 1 ; ②int i = 1 ; ③int i = 1 ;
i + + ; + + i ; i = i + 1 ;
这三个程序段分别运行的结果是一样的 ,i 的值都
为 2.
第二种情况 ,当两种形式中任何一种和其他
的运算符相结合一起构成一个复合表达式或此类
的表达式语句存在时 ,两者的运算规则就有很大
的差别. 这个很大的差别可归纳为一句口决 :“名
前先取 ,名后先增”. 理解并记住这一口诀 ,问题就
可迎刃而解.
无论是 i + + 还是 + + i 的操作都可分解为两
步 :
1) 取变量 i 的值参加其他运算 ;
2) 变量 i 自身的值增 1.
两步的执行 :若变量名在前就先作第一步 ,若
变量名在后就先作第二步.

6:
注意前缀运算和后缀运算的区别
仍以自增运算符为例 ,该运算符可作用在变
量之前 ,如 + + i 称为前缀运算 ;也可作用在变量
之后 ,如 i + + 称为后缀运算. 在这两种运算中 ,表
达式的值不同 :前缀运算后 ,表达式的值为原变量
值加 1 ;后缀运算后 ,表达式的值仍为原变量值 ;
而变量值不论前缀运算还是后缀运算都加 1. 自
减运算符与自增运算符类似 ,只要将加 1 改为减
1 即可. 即前缀运算是“先变后用”,而后缀运算是
“先用后变”. 如 :
int i = 5 ;
i + + ;
y = i ;
与
int i = 5 ;
+ + i ;
y = i ;
两段程序执行的结果 i 的值都为 6 ,y 的值也都为
6. 但是把它们引用在表达式中就表现出区别. 如 :
int i = 5 ;
x = i + + ;
y = i ;
的执行结果 x 为 5 ,y 为 6. 即后缀方式是“先用后
变”. 而
int i = 5 ;
x = + + i ;
y = i ;
的执行结果 x 为 6 ,y 为 6. 即前缀方式是“先变后
用”.
7:数组名永远都不会是指针,数组名是一个地址,一个符号地址常量,不是一个变量更不是一个作为变量的指针。用来存放数组的区域是一块在栈中静态分配的内存,数组名是这跨内存的代表,它被定义为这块内存的首地址,数组名只是个地址而是还是个不可修改的常量,数组名这个符号,就代表了那块内存的首地址,数组名这个符号本身就代表了首地址这个地址值,他就是个地址,这个就是数组名属于符号常量的意义所在。
下面是自己的摘抄:

  

首先,C 语言之所以把作为形参的数组看作指针,并非因为数组名可以转换为指针,
而是因为当初 ANSI 委员会制定标准的时候,从 C 程序的执行效率出发,不主张参数传递时
复制整个数组,而是传递数组的首地址,由被调函数根据这个首地址处理数组中的内容。那
么谁能承担这种“转换”呢?这个主体必须具有地址数据类型,同时应该是一个变量,满足这
两个条件的,非指针莫属了。要注意的是,这种“转换”只是一种逻辑看法上的转换,实际当
中并没有发生这个过程,没有任何数组实体被转换为指针实体。另一方面,大家不要被“转
换”这个字眼给蒙蔽了,转换并不意味着相同,实际上,正是因为不相同才会有转换,相同
的话还转来干吗?这好比现在社会上有不少人“变性”,一个男人可以“转换”为一个女人,那
是不是应该认为男人跟女人是相同的?这不是笑话么。
第二,函数参数传递的过程,本质上是一种赋值过程。C89 对函数调用是这样规定的:
函数调用由一个后缀表达式(称为函数标志符,function designator)后跟由圆括号括起来的赋
值表达式列表组成,在调用函数之前,函数的每个实际参数将被复制,所有的实际参数严格
地按值传递。因此,形参实际上所期望得到的东西,并不是实参本身,而是实参的值或者实
参所代表的值!举个例来说,对于一个函数声明:
void fun(int i);
我们可以用一个整数变量 int n 作实参来调用 fun,就是 fun(n);当然,也正如大家所熟悉的
那样,可以用一个整数常量例如 10 来做实参,就是 fun(10);那么,按照第二个疑问的看法,
由于形参是一个整数变量,而 10 可以作为实参传递给 i,岂不就说明 10 是一个整数变量吗?
这显然是谬误。实际上,对于形参 i 来说,用来声明 i 的类型说明符 int,所起的作用是用来
说明需要传递给 i 一个整数,并非要求实参也是一个整数变量,i 真正所期望的,只是一个
整数,仅此而已,至于实参是什么,跟 i 没有任何关系,它才不管呢,只要能正确给 i 传递

一个整数就 OK 了。当形参是指针的时候,所发生的事情跟这个是相同的。指针形参并没有
要求实参也是一个指针,它需要的是一个地址,谁能给予它一个地址?显然指针、地址常量
和符号地址常量都能满足这个要求,而数组名作为符号地址常量正是指针形参所需要的地
址,这个过程就跟把一个整数赋值给一个整数变量一样简单!

 





  

posted @ 2012-12-13 19:50  Linux、Mongo、Php、Shell、Python、C  阅读(301)  评论(0编辑  收藏  举报