C初级指针复习
内存:
内存中的每一个位置都由一个独一无二的地址标识
每一个内存位置都包含一个值
值和类型:
不能简单地通过检查一个值的位来判断它的类型,为了判断值的类型(以及它的值),必须观察程序中这个值的使用方式,值的类型并非值本身所固有的一种特性,而是取决于它的使用方式
NULL指针:
NULL指针提供了一种方法:可以通过NULL指针表示一个特定的指针目前并未指定任何内容,这一方法可以使得程序返回两个信息:是否存在指定元素?指定元素的位置?但是对NULL指针进行解引用是非法的
指针、间接访问和左值:
间接访问操作符所需要的操作数是个右值,但这个操作符所产生的结果是一个左值
指针常量:
*地址=值
这是非法的,因为地址的数据类型是整数,无法作为左值,需要将其为转为指向整型的指针类型,即int*强转类型,但这种做法是有缺陷的,
左值和右值:
左值标识了一个可以储存结果值的地点,它是指向内存区域的对象,右值则是指定了一个值,它则是内存区域中存储的值,左值意味着一个位置,而右值则意味着一个值,所以在需要使用右值的地方可以使用左值,但反之则不行,左值一般为基本数据类型、指针、数组下标访问成员、枚举类型、结构体类型,右值一般为常量、表达式、const修饰的数据成员、函数名(地址常量)
*操作符具有从右向左的结合性,
指针表达式:
char ch
char* cp
&ch:只能作为右值,作为右值时,表示ch的地址,不能作为左值的原因是ch的地址不确定,不能指定一个特定的位置,或者是不能访问该位置的区域,所以左值不合法
cp:左值和右值均可,左值指的是cp所指的内存位置,右值则是cp的值
&cp:只能作为右值,作为右值时,表示cp的地址值,其类型是指向字符的指针的指针,但是作为左值时,因为其指向的地址位置不确定,所以是非法的
*cp:左值和右值均可,左值指向的位置是cp所指遍历的内存区域,也就是ch,右值则是ch变量的值
*cp+1:解引用操作符优先级高于加号,因此先间接访问cp的值,然后加一得到字符b,因此该表达式的结果只能作为右值使用,而不能作为左值,因为是非法的
*(cp+1):该表达式的含义是间接访问cp指向地址加一的位置,其结果既可以作为左值,也可作为右值
cp++与++cp:只能作为右值使用,作为右值的结果是cp所指内存位置加一的区域,但是作为左值时,因为其结果是一个地址常量,并没有进行访问,所以是非法的
*cp++:解引用操作符和自增运算符结合性相同,都是从右向左,所以先执行后置自增,因此先拷贝cp后自增,结果可作为左值和右值使用
*++cp:与上一个内容同理,这个是先自增后拷贝,结果可作为左值和右值使用,但它访问的位置和内容与上一个不同
++*cp:先执行解引用运算符,访问内存内容,后自增,结果为字符常量,因此只能用于右值
(*p)++:与上一个同理
++*++cp:结合性自右向左,因此最终结果还是字符常量,只能作为右值使用
++*cp++:同理
指针运算:
指针与整数发生加法运算时,会根据指针所指数据类型调整大小,例如定义float*p,p+3其实是相当于加12个字节
(1)算术运算:
指针+(-)整数,这一表达式的结果仍然是指针形式
指针-指针:这一表达式只能应用于指向同一数组的两个指针之间,表达式结果为有符号整数,反映的是两指针之间的距离,因为其结果是通过两指针的差值除于所指向数据类型的大小得到的
(2)关系运算:
关系操作符可以对两个指针值进行比较,不过其前提依然是两个指针指向同一数组,这将用于表示指向数组更前或更后的元素,当然不指向同一数组也是可以的,那么其结果只能体现是否指向同一地址
下面举一例子:
此代码应用了for。for循环的判断条件是合法的,因为p和&array[5]指向同一数组,事实上&array[5]这一指针常量所指向的是数组最后一个元素后面的那一个内存位置,尽管p指针最终也会指向这一位置,但p并没有间接访问此地址,所以是安全合法的
总结:
计算机内存中的每个位置都由一个地址标识,通常邻近的内存位置合成一组,这样就可以存储更大范围的值
不能通过值的位模式来判断值的类型,类型是通过其使用方式来隐式确定的,编译器能够保证值的声明与使用方式是绑定的,从而保证可以通过值的使用方式来确定值的类型
指针变量的值并非是它所指向的内存位置所存储的值,必须通过间接访问来获得其所指向的内存位置所存储的值,一个指向整型的指针进行间接访问操作后得到的是整型值 声明一个指针变量并不会自动分配任何内存,在对指针进行间接访问时,要对指针进行初始化,要么指向现有内存,要么分配动态内存
NULL指针就是不指向任何东西的指针,赋值指针意味着此指针不指向任何值,对其间接访问结果因编译器而异
除了NULL指针,再也没有任何内建方法的记法来表示指针常量,因为程序员通常无法预知编译器会把变量放在内存中的什么位置,在极少见的情况,需要使用指针常量,这时要强制类型转换为指针类型来创建它
最后,指针可以进行算术和关系运算,不过是一般用于两个指针指向同一数组
·