为什么我可以将const char指针指向可变的char数组?

时间:2020-02-20 21:05:27

标签: c string pointers constants string-constant

为什么这样:

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";

但是如果它是数组,则只能执行第一行?是否恒定?

2 个答案:

答案 0 :(得分:3)

为什么我有const char *指向可变的char数组的点?

此处带有const的{​​{1}}对其使用施加了限制。它不允许某些新用法,但可能会更少。因此,Pandora's Box此处没有打开。

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 *,但是由于历史原因 1 ,它是const char *。由于它是char *,所以char*也可以。

char* b2 = "hello";

在将字符串常量分配给变量时,字符串常量又如何工作?

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

作为赋值的一部分,字符串文字(一个b="test"; 数组)将转换为其第一个元素char的地址和类型。该指针已分配给char *


1 b在早期的C语言中不可用,因此为了不破坏现有的代码基础,字符串文字仍然没有const。 / p>

答案 1 :(得分:0)

您始终可以为类型添加常数。这是一件的事情,因为它允许您编写可以保证某些功能的函数。

//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));
}

请注意,丢弃常数会导致不确定的行为:

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语言中的字符串文字的类型(即双引号之间的任意字符序列)的类型为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]

但是,在初始化语句中使用时,规则指出const 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
相关问题