2

为什么这很好:

char a[2];
a[0]='a';
const char* b;
b=a;
printf("%s\n",b);
a[0]='b';
printf("%s",b);

为什么指向常量字符串的指针可以指向非常量字符串?将字符串常量分配给变量时,它们是如何工作的?为什么你可以这样做:

const char* b="hello";
b="test";

或者

char* b="hello";
b="test";

但是如果它是一个数组,你只能做第一行吗?恒定与否?

4

2 回答 2

3

为什么我可以const char *指向一个可变char数组?

这里const的 with限制b了它的使用。它不允许一些新的使用,但可能更少。所以这里没有打开潘多拉魔盒

char a[2];
const char* b = a;

b具有对数组的读取权限。数组a[]可能仍会通过a.

a[0]='y'; // OK
b[0]='z'; // leads to error like "error: assignment of read-only location "

将字符串常量分配给变量时,它们是如何工作的?恒定与否?

"hello"是类型的字符串文字char [6]。通过const char* b1 = "hello"声明和初始化,b1分配了一个类型为 的指针char *。这可能是const char *,但出于历史原因1它是char *。既然是char*char* b2 = "hello";也OK。

const char* b1 = "hello";
char* b2 = "hello";

将字符串常量分配给变量时,它们是如何工作的?

b="test";

作为赋值的一部分,字符串字面量(一个char数组)被转换为其第一个元素 a 的地址和类型char *。该指针被分配给b.


1 const在早期的 C 中不可用,因此为了不破坏现有的代码库,字符串文字仍然没有const.

于 2020-02-20T21:39:39.733 回答
0

您始终可以将 const-ness 添加到类型中。这是一件好事,因为它允许您编写做出一些保证的函数。

//Here we know *str is const, so the function will not change what's being pointed to.
int strlength(const char *str) {
    int length = 0;
    while (*str++)
        ++length;
    return length;
}

int main(void) {
    char a[2] = "a"; //a[0] and a[1] are mutable in main(), but not in strlength().
    printf("%d", strlength(a));
}

请注意,抛弃 const-ness 会导致未定义的行为:

void capitalize(char *str) {
    if (isalpha(*str))
        *str = toupper(*str);
}

int main(void) {
    const char *b = "hello";
    capitalize((char*) b); //undefined behavior. Note: without the cast, this may not compile.
}

至于您的第二个问题,您的第一个示例是正确的,因为 C 中字符串文字的类型(即双引号之间的任何字符序列)是 type const char*。这是有效的:

const char *b = "hello"; //"hello" is of type const char*
b = "text"; //"text" is of type const char*

因为抛弃 const 会导致未定义的行为,所以这段代码是无效的:

char *b = "hello"; //undefined behavior; "hello" is const char*
b = "text"; //undefined behavior; "text" is const char*

数组的情况更复杂一些。在表达式中使用时,数组充当指针,但数组是与指针根本不同的类型:

char a[10];
a = "hello"; //does not compile - "hello" is a const char*; a is a char[10]

但是,当在初始化语句中使用时,规则规定 aconst char*可用于初始化字符数组:

char a[10] = "hello"; //initialization - a is a char[10], "hello" is a const char*
                      //a will contain {'h','e','l','l','o',0,0,0,0,0}

另外,不要忘记您可以使用 strcpy 将字符串文字分配给数组:

char a[10];
strcpy(a, "hello");
assert(strcmp(a, "hello") == 0);
//a will contain {'h','e','l','l','o',0,x,x,x,x}
//here x's mean uninitialized
于 2020-02-20T21:32:44.250 回答