| 指针浅尝 (原创),希望大家批评指正,谢谢!
1.内存中每个位置都由一个独一无二的地址标识。 2.内存中每个位置都包含一个值(内容)。 对于变量也是如此.
地址内容:
100 104 108 112 116 | ̄ ̄ ̄ ̄| ̄ ̄ ̄ ̄| ̄ ̄ ̄ ̄ ̄| ̄ ̄ ̄ ̄| ̄ ̄ ̄| | 3 | -1 | 10769582 | 160 | 6 |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 图1
可以根据存储地址(100,104,108 。。。)找到其所处的内存位置,并提取它的内容(3,-1,10769582。。。)。即根据一个地址可提取其中的内容(值)。 但让人去记忆一个存储地址是不实际的,因此为了简化,高级语言提供了名字,代替地址来访问内存的位置。于是,下图出现了。
a b c d e | ̄ ̄ ̄| ̄ ̄ ̄| ̄ ̄ ̄ ̄ ̄| ̄ ̄ ̄ ̄| ̄ ̄ ̄| | 3 | -1 | 10769582 | 160 | 6 |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 图2
这些名字即是通常我们说的变量。(当然,图2的这些关联由编译器实现,而硬件依然通过地址访问内存位置)。
说到此,我们知道了,所有的变量都有2个重要属性: 1. 地址 (这就是在c语言中,‘&变量’(’&a’)可以得到变量地址的根本原因。) 2. 内容 (即值图中3,-1,10769582。。。)。
得到变量的地址我们用 int a; &a时得到a的地址。
引用变量时,如 int a,b; a=3; 即通过变量名得到或改变变量的内容。
而这里所说的变量包括: 普通变量、指针变量。
指针变量:
指针变量是包含 一个变量地址 的变量。 除此外,符合变量的特点。
定义时为了和定义普通变量区别开来,在指针变量名前加了* (此处的*号仅仅是一个指针变量的标记而已,表明这是一个指针变量,别无他意。不作‘*’运算解释。)
定义时:
int *a; //定义时,*号是一个指针变量的标记而已,不作‘*’运算解释 或 int b; int *a=&b; //定义时,*号是一个指针变量的标记而已,不作‘*’运算解释
注意:定义后的指针变量名是a,而不是*a。 *只是一个标记,为了区别普通的变量定义而设。
因此,指针变量和普通变量区别仅仅在于它们存储内容。 指针变量是一个变量地址。 
除了在定义时,指针变量和普通变量有些不同(指针变量前加个*号),在其他使用中和普通变量的表意相同。如: int a; 那么&a 表意是取a变量本身的地址; a=3; 让a的值(内容)变成‘3’ ;
int *b; 那么&b表意是取指针变量b本身的地址; b= &a ; 让指针变量b的值(内容)变成‘a的地址’ ;
单目操作符* (*运算):
*取出或改变其后地址中存储的内容(值)。 int a=3; int *p=&a; //定义时,*号是一个指针变量的标记而已,不作‘*’运算解释 *p=6;
第三行语句 p的内容值为a的地址, *p Û *(p) Û *(&a) Û a
注:*运算时,可作如下的形式变换,更清晰明了: *指针变量名 Û *(指针变量名)
[] 变址运算符:
为避免混乱,将所有的[]运算,转换为*运算,有如下关系: a[i] Û *(a+i) //等量代换
注1:此时的a[i]为使用时的,而非定义时的
定义时 int a[3]; 使用时 a[0] a[1] a[2] // 而没有a[3]这个数组元素
注2:二位数组a[i][j] a[i][j] Û *(*(a+i)+j) 行列(式) 行 列(式)
此时的i为一个单位行,即一行为一个单位的移动,j为一个单位列,即一行为一个单位的移动。 j=1 j=2 j=3 i=1|¯¯¯¯¯¯|¯¯¯¯¯¯|¯¯¯¯¯¯| i=2|¯¯¯¯¯¯|¯¯¯¯¯¯|¯¯¯¯¯¯| i=3|¯¯¯¯¯¯|¯¯¯¯¯¯|¯¯¯¯¯¯| ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
注3:数组名是表示数组首地址的地址常量 int a[]=, *p=a; 则下面: p++,p-- (ok) a++,a-- (´ ) //a是地址常量。不能变。 a+1, *(a+2) (ok)
指针的算术运算:
p±i Û p ±c´d
解释: P为一指针变量,i=c 。 c是整型数,d为p指向的变量所占字节数。 i 是p指向的变量所占字节数的单位的个数,即i=1时是p指向的变量所占字节数的单位。
|