8.1 指针变量
8.1.1 变量的指针和指针变量
1.内存地址
- 内存是由字节构成的一片连续存储的空间,每个字节都有一个编号。
- 字节的编号就是内存地址,简称地址。
-
CPU是通过内存地址来访问内存,进行数据的存取(读写)的。
2.变量的地址
- 在C语言程序中定义一个变量,系统根据变量的类型为变量分配一定长度的存储单元。
-
一个存储单元手字节的编号称为该存储单元的地址,也就是相应变量的地址,在一个地址所标记的存储单元中存放的数据称为该存储单元的内容。
3.指针、变量的指针和指针变量
- 一个存储单元的地址唯一指向一个内存单元,这个地址也称为指针。指针就是内存单元的地址,指针指向一个内存单元,变量的指针就是变量的地址。
- 变量的指针指向一个变量对应的内存单元。
- 指针(地址)也是数据,可以保存在一个变量中。保存指针(地址)的变量称为指针白能量。
-
因此,一个指针变量的值就是某个内存单元的地址(指针)。
一个指针是一个地址,是一个常量,而一个指针变量可以被赋予不同的指针值,是变量。8.1.2指针变量的定义和初始化
1.定义一个指针变量包括3个内容
- 指针说明,即定义的变量为一个指针变量
- 指针变量名
-
指针变量所指向的对象的数据类型
2.定义指针变量的一般形式
-
类型标识符 *指针变量名
例如int *ip; // ip是指向整型变量的指针变量
char *cp; // cp是指向字符型变量的指针变量
double *fp; // fp是指向实型变量的指针变量8.1.3指针变量的引用
1.指针运算符
- 取地址运算符&
- 取地址运算符&是单目运算符,结合性为右结合性,功能是取变量的内存地址,一般形式为:&变量名。
- 例如,&a表示a的地址,&b表示变量b的地址
- 取内容运算符*
- 取内容运算符*是单目运算符,结合性为右结合性,在*运算符之后必须紧跟指针变量名,一般形式为:*指针变量名
- 例如,*ip表示指针变量ip所指向的变量(*和指针变量名之间不允许有空格)。
- 注意,取内容运算符*和指针变量蒂尼中的指针类型说明符*是不同的。
在指针变量定义中,*是指针类型说明符,表示其后的变量是指针类型。
而表达式中出现的*则是一个运算符,用以表示指针变量所指向的变量。
-
关于指针运算符的说明
已知定义语句int a, *pa = &a, *pb;
- &*pa等价于&a
&*pa即&(*pa),即先进行*运算,得到变量a,再进行&运算(取a的地址)。 -
*&a等价于a
*&a即*(&a),即先进行&运算,得到a的地址,再进行*运算,得到变量a。2.对指针变量的赋值操作
- 可以通过赋值语句将一个内存地址赋给已定义的指针变量,通过赋值运算可以改变指针变量的指向。
```
// 把整型变量a的地址赋予整型指针变量,通过赋值运算可以改变指针变量的指向。
int a, pa;
pa = &a;
// 把指针变量pa的值赋予指针变量pb,使得pa和pb均指向变量a
int a, pa = &a, pb;
pb = pa;
// 将空指针赋给指针变量
int p; -
-
p = NULL; // p = 0;
```8.2数组指针变量
-
-
C语言规定数组名代表数组的首地址,即第0个元素的地址,是一个指针常量。人们将数组的首地址即数组第0元素的地址称为数组的指针,数组元素的地址称为数组元素的指针。
8.2.1数组指针变量的定义和引用
1. 数组指针变量的定义
-
一般形式:类型标识符 *指针变量名
int a[6], *pa;
pa = a; // 数组名a是数组的首地址
pa = &a[0]; // &a[0]为数组第0个元素的地址2. 数组指针变量的引用
- 数组指针变量与整数的加减算术运算
对于指向数组的指针变量,可以加上或减去一个整数n,含义是把指针指向的当前位置(指向某数组元素)向前或向后移动n个位置。指针变量加1,表示指针变量指向下一个数组元素的地址,而不是在原地址基础上加1。
- 两数组指针变量的减运算
如果两个指针指向同一个数组,那么它们可以想见,其结果再减1为两个指针之间数组元素的个数。
-
数组指针变量的关系运算
如果两个指针指向同一个数组,那么它们的关系运算表示它们所指向数组元素位置之间的关系。3. 数组元素的引用
- 访问一维数组元素有两种方法
下标法,即用a[i]或pa[i]的形式访问数组元素;
指针法,即采用*(pa+i)或*(a+i)的形式访问数组元素。 - 如果要输出某个指定的数组元素a[i][j],则应该事先计算出该元素在内存中存储的位置(即相对于数组起始位置的相对位移量)。
-
计算a[i][j]在数组中的相对位置的计算公式为:i*m+j
m为二维数组的列数(二维数组大小为n*m)8.2.2二维数组的指针
1.二维数组的指针
- aa[i] == *(aa+i)
- *(aa[i]) == aa[i][0]
-
aa[i]+j == *(aa+i)+j
2.指向二维数组的指针变量
- 行指针的定义形式如下:
类型标识符 (*指针变量名)[长度]; -
访问二维数组元素的两种方法
(1)下标法,即用a[i][j]或pa[i][j]的形式访问数组元素。
(2)指针法,即采用*(*(pa+i)+j)或*(*(aa+i))或*(pa[i]+j)或*(aa[i]+j)的形式访问数组元素。8.2.3指针与字符串
1.字符串的表示形式
- 用一维字符数组表示字符串
-
用字符型指针变量表示字符串
2.字符指针变量与字符数组小结
- 存储内容不同
字符数组存储的是字符串本身,每个数组元素存放一个字符,而字符指针变量存放的是字符串的首地址。
- 赋值方式不同
对字符数组只能对各个元素赋值。
-
字符指针变量值是可以改变的,而字符数组名代表字符数组的起始位置,是一个常量,不能改变。
8.3指针数组和二级指针变量
8.3.1指针数组
指针数组的定义形式为:
类型标识符 *数组名[常量表达式];8.3.2二级指针变量
定义二级指针变量的一般形式为:类型标识符 **指针变量名;