4.2 指针与数组
4.2.1 指针与一维数组
1.一维数组元素的地址
如果知道一个数组元素的地址,就可以通过取内容运算符得到数组元素的内容。
对于一个数组元素a[i],其地址有以下三种表示方式:
(1)下标法
&a[0]表示数组第一个元素的地址,&a[3]表示数组的第四个元素的地址,&a[i]表示数组元素a[i]的地址。
(2)指针法
这种方法要先定义指向数组元素的指针。例如:
int a[10];
int *p;
p = a;
此时指针p被称为指向数组a的元素的指针,p的值为数组a的起始地址,即&a[0];则p+i表示元素a[i]的地址,即p+i等价于&a[i]。
需注意,若执行的赋值语句不是p = a,而是p = &a[k],则p就指向a[k],而不是数组a的起始地址,p + i表示元素a[k + i]的地址。
(3)地址法
例如,a + 1表示&a[1],这里a + 1的值与执行 p = a; p = p + 1之后的值相同。同理,a + i 表示数组元素 a[i] 的地址,即a+i等价于&a[i]。
2. 一维数组元素的引用方法
与上述三种数组元素地址表示法相对应,一维数组元素的引用也有三种方法。
(1)下标法
例如,a[i]
(2)指针法
int a[10];
int *p;
p = a;
则*(p+i)将得到下标为 i 的元素的值,即*(p+i) 与a[i]等价。
(3)地址法
因为a+i表示数组元素a[i]的地址,所以*(a+i)表示数组元素a[i]的值。
在使用指针变量时,要注意以下几点:
- 指针变量可以自增、自减,而数组名不可以自增、自减。
- 要注意指针变量的当前值。
- 使用指针或地址法访问数组元素时,要注意防止下标越界。
指针与二维数组和指针与一维数组类似。
4.3 指针与字符串
4.3.1 用字符指针指向字符串常量
将字符型指针变量指向字符型常量有两种方法,即初始化和赋值。如:
char *p = "Do you know?"; /* 用字符串初始化字符型指针变量 */
或
char *p;
p = "Do you know?"; /* 将字符串赋值给字符型指针变量 */
用字符串初始化字符型指针变量,实际上是用字符串第一个字符的地址初始化字符型指针变量。将字符串赋值给字符型指针变量也是将字符串第一个字符的地址赋值给字符型指针变量。 此时字符型指针变量p取得字符串的首地址,即*p的值为‘D’。
4.3.2 字符串的引用方式
字符串通常存储在字符数组中,可以通过字符数组名或指向字符串的字符指针两种方式引用字符串。
【例】通过字符数组名引用字符串。
#include<stdio.h>
#include<string.h>
void main()
{
char c1[30] = "Do you know?", c2[] = "Yes!";
strcat(c1, c2);
puts(c1); /* 输出字符数组c1中的字符串 */
printf("%s\n", c1); /* 使用%s格式输出字符数组c1中的字符串 */
}
运行结果为:
Do you know?Yes!
Do you know?Yes!
【例】通过字符指针指向字符串的方式引用字符串。
#include<stdio.h>
void main()
{
char *str1 = "Do you know?", *str2; /* str1为字符指针,不是字符数组 */
str2 = "Yes!"; /* 字符型指针变量str2存放字符串的起始地址 */
printf("%s %s\n", str1, str2); /* 使用%s格式输出字符指针所指字符串 */
puts(str1);
puts(str2);
}
运行结果:
Do you know? Yes!
Do you know?
Yes!
有兴趣的可自己跑一下这个程序~
4.3.3 字符型指针变量与字符数组
字符型指针变量可以指向单个的字符变量,也可以指向字符串,还可以指向字符数组。我们需比较透彻地了解字符型指针变量的用法:
(1)字符数组定义时,无论是否初始化,都将分配一块确定的存储空间用于存放数组内容。字符型指针变量则不然,若其在说明时未初始化,则只在内存中为其分配一个存储单元,用于以后存放指针;如果初始化,则在内存的数据区中分配一块连续存储单元存放用于初始化字符型指针变量的字符串,并把该字符串的起始地址赋给字符型指针变量。
数组一经定义,使用的存储单元就不再变化,任何时刻都可用数组名访问数组元素;但字符型指针变量则不同,它的值一旦改变,表示它的指向发生了移动,它就不再指向原来的内容。
(2)要改变字符数组的内容,可以使用函数strcpy()、strcat()等,或者指针变量法和下标变量法,只要数组下标不越界就不会造成系统的致命错误。而要改变字符型指针变量的内容,只要给它赋值就行。但这样很容易出错,需特别小心。
4.4 指针的指针
指针变量也要分配内存空间,指针变量的地址称为指针的指针。存放指针变量地址的指针变量是指向指针的指针变量。而指针的指针则是多级指针最简单、最常用的形式。
如下图,在多级间接寻址中,一个指针中存放的是另一个指针的地址,直到最后一级指针才存放指向变量的地址。这种多级间接寻址可以延伸到任何一级,但在实际编程中很少用到超过二级间接寻址(指针的指针)的多级指针。因为多级间接寻址降低了程序的可读性,容易出错。
欢迎大家提问或补充~