事实上,我知道指针的字符串内容不可修改。但是考虑下面的代码。这是否意味着cf已更改为“字符数组”类型(其内容是可修改的)。
#include <stdio.h>
int main()
{
char line[100];
char *cf;
cf = line; //cf (of type pointer-to-pointer-to-char) is converted?
*cf = 's';
*cf = 'g';
printf("%c", *cf);
}
以下内容不起作用。
int main()
{
char *cf;
*cf = 's';
*cf = 'g';
printf("%c", *cf);
}
答案 0 :(得分:3)
在第一个代码段中,cf
不是数组,而是指向一个数组。因此,您可以使用它来访问数组的值。您甚至可以使用cf[1]
之类的数组访问语法。
在第二个摘录中,cf
仍然是char*
。它尚未初始化,因此分配给它所指向的位置是未定义的行为。
您只是在读写一个字节,所以它可能会按您预期的那样工作...但是由于访问冲突,它也可能崩溃,由于您更改了其他人使用的内存或其他东西而导致数据损坏完全可能会发生。
答案 1 :(得分:3)
这是否意味着cf已更改为“字符数组”类型
不。无论您为变量分配什么类型,变量的类型都不会与声明的类型保持不变。
第一个代码段将一个指向数组第一个元素的指针分配给cf
。有人说将数组decays放入一个指针。
以下功能无效。
取消引用未初始化的指针将导致未定义的行为。您尚未确保*cf
指向适当的位置,因此您尝试写不应该的内容。也许你会成功。也许程序将被杀死。也许奇怪的事情会开始发生。无论如何,这是您必须避免的事情。
答案 2 :(得分:2)
我知道一个指针的字符串内容是不可修改的。
那只是部分正确...
最后,指针只是一些内存的地址。类型为char
的指针可以指向某个单个字符,也可以指向某个数组的开头,甚至指向该数组的中间,或者指向该数组末尾的一个字符(嗯,但是您需要为指针分配一个有效的地址。在使用它之前-main
函数中不是这种情况:“不起作用”)。您可以通过指针修改任何此类数组,只要该数组本身不是const
。
与C字符串完全相同;实际上,这些不过是存储在内存中某个地方的数组而已。能够将此数组中的数据解释为“字符串”的要求是,实际字符串数据的最后一个字符部分为空字符(不必一定是整个数组中的最后一个字符),并且您可以使用指向该数组的指针(char*
或char const*
)。
现在有字符串 literals 的特殊情况,即i。 e。您用双引号定义的任何字符串:"hello world"
。实际上,这些数组也包含定义的内容以及终止的空字符。 这些数组是不可变的,尽管不是常量。
通常,它们应该为const
(就像在C ++中一样),但是字符串文字在const
之前存在–并且出于兼容性的原因,保留了它们的类型最终引入新关键字后,其名称为char*
,而不是char const*
。
仍然我建议始终仅将字符串常量分配给const指针,以避免由于修改的字符串常量导致未定义的行为。
答案 3 :(得分:1)
在您的第一个代码部分中,表达式从数组类型隐式转换为指针类型。据我所知,当编译器看到数组表达式时,它将表达式的类型(在您的情况下为char array
)从“ 100
-元素数组char
”转换为“指针到char
”,并将表达式的值设置为数组第一个元素的地址。
在第二个代码部分中,cf
指向一个随机的内存地址,或者可能是NULL
,但不能保证。在这种情况下,您很幸运,因为您不在内核级别。也就是说,您正在尝试将数据写入可能很高的随机位置。称为UB。