使用字符数组和指针变量都能实现字符串的存储和运算,但它们两者之间是有区别的,不应混为一谈,主要有一下几点:
(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串中第一个字符的地址),绝不是将字符串放到字符指针变量中。
(2)赋值方式。可以对字符指针变量赋值,但不能对数组名赋值。
可以采用下面方法对字符指针变量赋值:
char *a; //a为字符指针变量
a="I love China!"; //将字符串首元素地址赋给指针变量合法。但赋给a的不是字符串,
//而是字符串第一个元素的地址
不能用以下办法对字符数组名赋值:
char str[14];
str[0]='I'; //对字符数组元素赋值,合法
str="I love China!"; //数组名是地址,是常量,不能被赋值,非法
(3)初始化的含义。对字符指针变量赋初值:
char *a="I love China!"; //定义字符指针变量a,并把字符串第一个元素的地址赋给a
等价于
char *a; //定义字符指针变量a
a="I love China!"; //把字符串第一个元素的地址赋给a
而对于数组的初始化:
char str[14]="I love China!"; //定义字符数组str,并把字符串赋给数组中各元素
不等价于
char str[14]; //定义数组str
str[]="I love China!"; //企图把字符串赋给数组中各元素,错误
数组可以在定义时对各元素赋初值,但不能用赋值语句对字符数组中全部元素整体赋值。
(4)存储单元的内容。编译时为字符数组分配若干存储单元,以存放各元素的值,而对字符指针变量,只分配一个存储单元。
如果定义了字符数组,但未对它赋值,这时数组中的元素的值是不可预料的。可以输出这些值,结果显然是无意义的。
如果定义了字符指针变量,应当及时把一个字符变量(或字符数组元素)的地址给它,使它指向一个字符型数据,如果未对它赋予一个地址值,它并未指向一个确定的对象。此时如果向该指针变量所指的对象中输入数据,可能会出现严重后果。如下面这个错误做法:
char *a; //定义字符指针变量a
scanf("%s",a); //企图从键盘输入一个字符串,使a指向该字符串,错误。
这种方法是危险的,因为编译时给指针变量a分配了存储单元,变量a的地址(即&a)是已经指定了,但a并未被赋值,在a的存储单元中是一个不可预料的值。应当在定义指针变量后,及时指定其指向。如:
char *a, str[10]; //定义了字符指针变量a和字符数组str
a=str; //使a指向str数组的首元素
scanf("%s",a); //从键盘输入一个字符串存放到a所指向的一段存储单元中,正确
先使a中有确定值,使a指向一个数组元素,然后输入一个字符串,把它存放在以该地址开始的若干单元中。
(5)指针变量的值是可以改变的,而数组名代表一个固定的值(数组首元素的地址),不能改变。
例1:改变指针变量的值
#include<stdio.h>
int main()
{ char *a=”I love China!”;
a=a+7; //改变指针变量的值,即改变指针变量的指向
printf(“%s\n”,a); //输出从a指向的字符开始的字符串
return 0;
}
运行结果:
China!
程序分析:指针变量a的值是可以变化的。printf函数输出字符串时,从指针变量a当时指向的元素开始,逐个输出各个字符,直到遇'\0'为止。而数组名虽然代表地址,但它是常量,值不能改变。
char str[]={"I love China!"};
str=str+7; //错误!
printf("%s",str);
(6)字符数组中各元素的值是可以改变的(可以对它们再赋值),但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能给它们再赋值)。如:
char a[] = "House"; //字符数组a初始化
char *b = "House"; //字符指针变量b指向字符串常量的第一个字符
a[2] = 'r'; //合法,r取代a数组元素a[2]的原值u
b[2] = 'r'; //非法,字符串常量不能改变
(7)引用数组元素。对字符数组可以用下标法(用数组名和下标)引用一个数组元素(如a[5]),也可以用地址法(如*(a+5))引用数组元素a[5]。如果定义了字符指针变量p,并使它指向数组a的首元素,则可以用指针变量带下标的形式引用数组元素(如p[5]),同样,可以用地址法(如*(a+5))引用数组元素a[5]。
如有:
char *a="I love China!"; //定义指针变量a,指向字符串常量
则a[5]的值是字母'e'。
虽然并未定义数组a,但字符串在内存中是以字符数组形式存储的。a[5]按*(a+5)处理。
(8)用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。
例如:
char *format;
format="a=%d,b=%f\n"; //使format指向一个字符串
printf(format,a,b);
因此只要改变指针变量format所指向的字符串,就可以改变输入输出的格式。这种printf函数称为可变格式输出函数。
也可以利用字符数组实现。例如:
char format[]="a=%d,b=%f\n";
printf(format,a,b);
但使用字符数组时,只能采用在定义数组时初始化或逐个对元素赋值的方法,而不能采用赋值语句对数组整体赋值,例如:
char format[];
format="a=%d,b=%f\n"; //非法
因此使用指针变量指向字符串的方法更为方便。