1、内存与地址
对于C程序员来说:1)内存中的每个位置由一个独一无二的地址标识;2)内存中的每个位置都包含一个值。所以只要记住地址——硬件仍然可以通过地址访问内存位置。当然了,不能简单的通过检查一个值来判断它的类型,要看看是整型算数指令还是其他指令去判断
2、指针的初始化与NULL指针
如果指针变量是静态的,它会被初始化为0;但如果变量是自动的,它根本不会被初始化。无论那种情况,声明一个指针都不会“创建”用于存储的内存空间。所以,在声明一个指针时最好将其初始化为NULL。
那么什么是NULL指针呢?
NULL指针是一个特殊的指针变量,表示不指向任何东西,NULL的值为“0”。
3、指针的使用
指针变量可以作为左值,并不是因为它们是指针,而是因为它们是变量。
指针的间接访问:*&a = 25;什么意思?它把值25赋给变量a。那么与表达式 a = 25有啥区别?功能上说,没区别。但是*&a = 25 的额外操作很多,可读性变差。
4、指针的指针
啊!有点恶心~~记住和二维数组的原来相似~~
5、指针表达式
声明如下:
char ch = 'a';
char *cp = &ch; |
下面看看具体的指针表达式相关内容:(关于表达式左右值,参见:
第四章 语句&第五章 操作符和表达式)
1)、
&ch:代表刚才声明的字符‘a’的地址,所用它可以作为表达式的右值;但是,由于这个地址是编译器分配的,程序员无法知道它的具体地址,所以不能作为表达式的左值。
2)、
cp:作为右值,cp代表指针变量cp指向的ch的地址;作为左值,cp代表指针变量的内容。所以对于指针变量cp来说,作为表达式的左右值均可。
3)、
&cp:与&ch类型,不过这个代表指针变量的地址。这个结果的类型是指向字符指针的指针。同样,这个值的存储位置并未清晰定义,所以这是一个不合法的左值。
4)、
*cp:这个表达是指针的间接访问操作。作为右值,它的值为字符‘a’;作为左值,就相当于变量ch。
下面介绍点稍难的表达式:
5)、
*cp+1:首先,‘*’的优先级高于‘+’,所以先执行间接访问操作,其值为‘a’+1,为‘b’。这个表达式的最终存储位置是不明确的,所以不能够作为左值。
6)、
*(cp+1):和上一个相似,但有本质区别:因为“()”的原因,这个表达式首先计算cp+1,即ch变量的后一个地址,这个地址的值是什么?不知道!但是作为右值,它是合法的。现在来看看这个表达式能不能作为左值:尽管cp+1本身是非法的左值,但是执行了间接访问操作,这个含义与*cp是类似的,所以作为左值是合法的。
7)、
++cp:这个和cp+1有啥区别?看看
第四章 语句&第五章 操作符和表达式。那么作为右值,它代表什么:它指向字符变量ch的后一个地址。但是其存储位置不明确,是非法的左值。
8)、
cp++:这玩意和++cpp又有啥区别?简单:前缀++先增加它的操作数再返回这个结果,而后缀++是先返回cp值的拷贝然后在增加cp的值。所以作为右值,它表示指向ch的字符指针,即‘a’;和上一个例子一样,作为左值它是非法的。
9)、
*++cp:这里,间接访问操作符作用于增值后的指针拷贝上,所以它的右值是ch后面的那个内存地址,而它的左值就位于那个位置本身。
10)、
*cp++:使用后缀++操作符所产生的结果不同,他的右值和左值分别是变量ch的值和ch的内存位置,而cp则指向了ch后一个内存位置。事实上,这里涉及3个步骤:a、++操作符产生cp的一个拷贝,b、++操作符增加cp的值,c、在cp的拷贝上执行间接访问操作。
11)、
++*cp:在这个表达式中,由于这两个操作符的结合性都是从右向左,所以首先执行的是间接访问操作,然后cp所指向的位置的值增加1,表达式的结果是这个增值后的值的一份拷贝。
12)、(*cp)++:使用后缀++操作符,必须加上括号,使它首先执行间接访问操作。这个表达式与前一个相似,但是它的结果值是ch增值前的原先值。
看明白了?再来点恶心的~~~
13)、
++*++cp:诡异吗?很诡异!但如果上面12个你都弄明白的话,这个不是很复杂:这个表达式有3个操作符,都是从右向左结合的。所以先执行++cp,执行后cp指向ch后一个内存地址;再指向间接访问,即cp指向地址存的值,是多少?鬼知道!但是合法!最后计算前缀++,表达式的结果为鬼知道的值加1。当然了,作为左值是非法的。
14)、
++*cp++:这个和上一个的区别在于第一个++操作符是后缀形式而不是前缀形式。由于它的优先级高,所以先执行它。间接访问操作所访问的是cp所指向的位置而不是cp所指向的后面那个位置。
6、指针运算:当指针和整数量进行计算时,整数在执行运算前会根据合适的大小进行调整。
1)算术运算(加减运算)
指针和整数间的运算,如:
float values[NUMBER];
float *vp;
for(vp = &values[0];vp < &values[NUMBER];)
*vp++ = 0; |
这个例子中的指针运算是用++操作符完成的,每增加1,增加值1都会与float的长度相乘,其结果加到指针vp上。
指针和指针间的运算:
如果两个指针都指向同一个数组中的元素,表达式"p1-p2"就是合法的。表达式的值为(p1地址值-p2地址值)/数组类型长度。
2)关系运算(< <= > >=)原理同算术运算,不再赘述。
阅读(1264) | 评论(0) | 转发(0) |