这是我读《C和指针》第6章做的笔记,过一遍指针知识点,希望能对你有所帮助。
-
内存
每个字节(byte)包含8个位,可以存储无符号值0至255,或有符号值-128至127。每个字节通过地址来标识。
为了存储更大的值,我们把两个或更多个字节合在一起作为一个更大的内存单位。例如四个字节的字,由于它们包含了更多的位,每个字可以容纳的无符号整数的范围是从0至429496729(232-1),可以容纳的有符号整数的范围是从-2147483648(-231)至2147483647(231-1)。
尽管一个字包含了4个字节,它仍然只有一个地址。至于它的地址是它最左边那个字节的位置还是最右边那个字节的位置,不同的机器有不同的规定。
- 内存中的每个位置由一个独一无二的地址标识。
- 内存中的每个位置都包含一个值。
名字与内存位置之间的关联并不是硬件所提供的,它是由编译器为我们实现的。所有这些变量给了我们一种更方便的方法记住地址——硬件仍然通过地址访问内存位置。
-
NULL指针
在你对指针进行间接访问之前,必须非常小心,确保它们已被初始化。
标准定义了NULL指针,它作为一个特殊的指针变量,表示不指向任何东西。要使一个指针变量为NULL,你可以给它赋一个零值。为了测试一个指针变量是否为NULL,你可以将它与零值进行比较。
对一个NULL指针进行解引用操作是非法的。在对指针进行解引用操作之前,你首先必须确保它并非NULL指针。
-
指针常量
答案是把值25赋值给变量a:
&操作符产生变量a的地址,它是一个指针常量,*操作符访问其操作数所表示的地址。在这个表达式中,操作数是a的地址,所以值25就存储于a中。
间接访问操作只能作用于指针类型表达式:
强制类型转换把值100从“整型”转换为“指向整型的指针”,这个技巧唯一有用之处是你偶尔需要通过地址访问内存中某个特定的位置,它并不是用于访问某个变量,而是访问硬件本身。
在那些极其罕见的需要使用指针常量的时候,它们通常写成整型字面值的形式,并通过强制类型转换转换成适当的类型。
-
指向指针的指针
c就是一个指向指针的指针。
*操作符具有从右向左的结合性,所以这个表达式相当于*(*c),我们必须从里向外逐层求值。
-
指针表达式
*p+1:
*的优先级高于+,因此先执行间接访问获取p指向的值,然后对值进行加一。
*(p+1):
间接访问p的值(地址)的下一位。
++p:
增值后的指针的一份拷贝,因为前缀++先增加它的操作数的值再返回这个结果。
*++p:
这两个操作符的结合性都是从右向左,间接访问增值后的指针的拷贝。
p++:
后缀++操作符同样增加p的值,但它先返回p值的一份拷贝然后再增加p的值。这样,这个表达式的值就是p原来的值的一份拷贝。
*p++:
(1)++操作符产生p的一份拷贝,(2)然后++操作符增加p的值,(3)最后,在p的拷贝上执行间接访问操作。
++*p:
首先执行的是间接访问操作,表达式的结果是:指针所指向的值,增值后的一份拷贝。
(*p)++:
p所指向的值加一之前的拷贝。
++*++p:
p的值(地址)的下一位所指向的值,加一以后的拷贝。
++*p++:
p的值(地址)加一前的拷贝(也就是原地址)所指向的值,加一以后的拷贝。