C缺陷与陷阱 — 4 指针与数组进阶-4 指针与字符串

时间:2024-11-20 07:14:29

4.1 通过指针修改字符串

C语言中一个常见的“陷阱”:混淆指针与指针所指向的数据,对于字符串的情形更是经常犯这种错误。例如下面的语句:

char *p, *q;
p = "xyz";
q = p;

第2行代码将字符串 "xyz" 的地址赋给指针变量 p,P的值是一个指向由'x'、'y'、'z'和'\0'这4个字符组成的数组的起始元素的指针。因此,如果我们第3行代码,可以用下图来表示这种情况:

 因此,当我们执行完下面的语句之后:

q[1]='Y':

 q所指向的内存现在存储的是字符串xYz。因为p和q所指向的是同一块内存,所以p指向的内存中存储的当然也是字符串xYz。

4.2 空指针并非空字符串

空字符串是一个以空字符(\0)结尾的字符串字面量,它的长度为0。空字符串在内存中占用一个字符的空间,即空字符本身。

在C语言中将一个整数转换为一个指针,最后得到的结果都取决于具体的C编译器实现。但是常数0是一个特殊情况,编译器保证由0转换而来的指针不等于任何有效的指针。常数0这个值经常用一个符号来代替:

#define NULL 0

需要记住的重要一点是,当常数0被转换为指针使用时,这个指针绝对不能被解除引用。换句话说,当我们将0赋值给一个指针变量时,绝对不能使用该指针所指向的内存中存储的内容。下面的写法是完全合法的:

if(p == (char*) 0);

但是如果要写成这样:

if (strcmp(p, (char *0)) == 0);

就是非法的了,原因在于库函数stremp的实现中会包括查看它的指针参数所指向内存中的内容的操作。

如果P是一个空指针,下面的的行为也是未定义的。而且,与此类似的语句在不同的计算机上会有不同的效果。

printf(p);
printf("&s",p);

相关文章