等效常量数组和指针

时间:2018-06-08 13:02:46

标签: c arrays pointers

等同于

是真的吗?
const char arr[2] = {0, 0};

const char *const arr = "\0\0";

但不是

const char * arr = "\0\0";

数组是否有秘密const?我的直觉是肯定的,因为你不能将数组分配给另一个。 (arr = arr2; error: assignment to expression with array type

我问,因为我将使用全局数组常量。

2 个答案:

答案 0 :(得分:1)

案例1: - 声明

const char arr[2] = {0, 0}; 

此处arr是两个字符的数组,arr[0]arr[1]都使用0初始化。 const表示您无法更改arr[0]& arr[1]。例如

 int main(void) {
        const char arr[2] = {0, 0};
        arr[0] = 'a';/* not possible, by putting const in front you made arr[0] as read only */
        return 0;
}

案例2: - 声明

  const char *const arr = "\0\0"; 

此处,arr[0]arr[1]也会使用\0进行初始化。但语法含义是arr 常量指针&它指出数据也只读,即你无法修改arr[0]&你无法修改arr。例如

int main(void) {
        const char *const arr = "\0\0"; 
        arr = "hello"; /*not possible, read only arr */
        *arr = 'a'; /* not possible, can't change the arr[0] */ 
        return 0;
}

案例3: - 声明

const char * arr = "\0\0";

这里arr是一个字符指针&它指向那个存储位置上的任何数据,即只读虽然它会导致未定义的行为,但您可以更改arrarr现在指向{ {1}},它也可以指向其他内存位置。例如

"\0\0"

数组是否有秘密常量?不,数组不是指针,而是常量指针,因为数组名称代表基地址&这是不变的,即你无法修改它。例如

int main(void) {
        const char * arr = "\0\0";
        arr++; /* possible bcz arr is not constant pointer */
        *arr = 'a'; /* not possible, can't change the arr[0] */
        return 0;
}

在这里你不能char arr1[] = "hello",arr2[10]; ,因为arr1 = arr2是常量指针,即无法更改地址,但您可以更改其元素值。

请注意,arr1const char arr[10];都不同。

答案 1 :(得分:1)

不,不是。数组和指针是不同的动物。数组表示相同类型的多个连续元素,并且具有 size ,其是单个项目的大小乘以其元素的数量。它将在其整个生命周期内始终代表相同的内存区域

另一方面,指针是数组的第一个元素的指示符或引用 - 单个变量被同化为该点的大小为1的数组。它没有指向其指向数组的大小的概念,并且指针的大小正是实现需要表示内存地址的大小。如果T是一个类型,并且int_ptr在实现中有效,则以下等式为真:

sizeof(T *) == sizeof(int_ptr)

指针通常可以在其生命周期内指向不同的变量或内存区域。当然它可以是const,在这种情况下,改变它的值将调用未定义的行为,但编译器可以允许它,而你永远不能改变数组的位置。

现在举例来说:

const char arr[2] = {0, 0};

arr是一个真正的数组:arr = x;会引发编译错误,sizeof(arr)为2

const char *const arr = "\0\0";

arr是指向const char的const指针。 arr = x;将被拒绝,但(const char *) arr = x;将在编译时被接受(并将在运行时调用UB)。但除了16位环境外,sizeof(arr)不是2,而是指针的大小(32位环境中为4,64位环境中为8)

const char *arr = "\0\0";

arr是指向const char的指针。 arr = "abcd";是合法的,并且arr指向不同大小的不同字符串文字。它的大小仍然是指针的大小。

与此问题无关,但在非const用例中数组和指针之间存在另一个重要区别:

char arr[2] = "a";

此处arr是一个数组已初始化,其中包含字符' a'和' \ 0'。 arr[0] = 'b';是合法的

char *arr = "a";

此处arr是指向文字字符串的指针。由于文字字符串是const,arr[0] = 'b';调用UB。 (现代编译器应该发出char *arr = "a";的警告,但出于兼容性原因,它们不是必需的)

顺便说一句,数组和指针之间的混淆是当你使用它们的值时,数组可以自动转换为指针:

   char arr[] = "abc";    // array of size 4 

   f(arr);                // the f function receives a pointer to the first element of arr