在C语言中,可以在这样的声明中使用字符串字面值:
char s[] = "hello";
或者像这样:
char *s = "hello";
那么有什么不同呢?我想知道在编译和运行时,在存储持续时间方面实际发生了什么。
在C语言中,可以在这样的声明中使用字符串字面值:
char s[] = "hello";
或者像这样:
char *s = "hello";
那么有什么不同呢?我想知道在编译和运行时,在存储持续时间方面实际发生了什么。
当前回答
举个例子来说明区别:
printf("hello" + 2); //llo
char a[] = "hello" + 2; //error
在第一种情况下,指针算术是有效的(传递给函数的数组衰减为指针)。
其他回答
补充一点:它们的大小也会有不同的值。
printf("sizeof s[] = %zu\n", sizeof(s)); //6
printf("sizeof *s = %zu\n", sizeof(s)); //4 or 8
如上所述,对于数组'\0'将被分配为最后一个元素。
在下列情况下:
char *x = "fred";
X是左值,它可以被赋值给。但在这种情况下:
char x[] = "fred";
X不是一个左值,它是一个右值——你不能给它赋值。
根据这里的注释,应该很明显:char * s = "hello"; 是一个坏主意,应该在非常狭窄的范围内使用。
这可能是指出“const正确性”是一件“好事”的好机会。无论何时何地,你可以使用“const”关键字来保护你的代码,不受“宽松”的调用者或程序员的影响,当指针开始发挥作用时,它们通常是最“宽松”的。
这就是用“const”修饰指针所能达到的效果。 (注意:必须从右向左阅读指针声明。) 以下是在使用指针时保护自己的3种不同方法:
const DBJ* p means "p points to a DBJ that is const"
-也就是说,DBJ对象不能通过p改变。
DBJ* const p means "p is a const pointer to a DBJ"
-也就是说,你可以通过p改变DBJ对象,但你不能改变指针p本身。
const DBJ* const p means "p is a const pointer to a const DBJ"
-也就是说,你不能改变指针p本身,也不能通过p改变DBJ对象。
与尝试常量突变相关的错误在编译时被捕获。const没有运行时空间或速度损失。
(当然,假设你使用的是c++编译器?)
——日本
另外,考虑到对于只读目的,两者的使用是相同的,您可以通过使用[]或*(<var> + <index>)索引来访问一个char。 格式:
printf("%c", x[1]); //Prints r
And:
printf("%c", *(x + 1)); //Prints r
很明显,如果你试图这么做
*(x + 1) = 'a';
你可能会得到一个分割错误,因为你试图访问只读内存。
char s[] = "hello";
声明s为一个char数组,其长度足以容纳初始化式(5 + 1个字符),并通过将给定字符串文字的成员复制到数组中来初始化数组。
char *s = "hello";
声明为指向一个或多个(在本例中是多个)字符的指针,并将其直接指向一个包含文字“hello”的固定(只读)位置。