为什么C中不允许使用此指针算法?

时间:2016-08-09 04:59:19

标签: c arrays pointers

char arr[] = "Hello";
arr = arr + 1;  // error occurs

据我所知,具有数组类型的表达式将转换为指向数组初始元素的指针类型。因此,我期望arr = arr + 1(指向数组的第一个元素(arr)的指针成为指向数组的第二个元素的指针)。为什么这不适用于C?

6 个答案:

答案 0 :(得分:55)

<script type="text/javascript"> $("#<?php echo $rows['itemname']; ?>").click(function(e){ //to prevent click return false; }); </script> 确实是指向数组第二个元素的指针(即arr + 1)。

但是,这并不意味着您可以以某种方式将指针值写回&arr[1]。至少有两个原因你不能这样做。

首先,arrarr元素的数组,而不是指针。这里有明显的类型不匹配。

其次,作为一个数组,char一个不可修改的左值。你不能改变arr本身,你只能改变它的元素(这种区别有点难以掌握,但它就在那里)。

最后,如果我们忽略更深层次的错综复杂,并专注于顶层正式发生的事情,由于 array type decay ,你的表达相当于

arr

由于左侧是[隐式]类型转换的结果,因此无法进行分配。在C类型转换中,始终生成rvalues。您无法分配给右值。

换句话说,不是这里不允许的“指针算术”。指针算术很好。这是你用指针算法导致错误的结果。

答案 1 :(得分:23)

数组是不可修改的左值。它们不能是赋值运算符的左操作数。

C11-§6.3.2.1:

  

可修改的左值是一个左值   没有数组类型,没有不完整的类型,[...]

§6.5.16/ 2:

  

赋值运算符应具有可修改的左值作为其左操作数。

声明

ShellFolder

arr = arr + 1; arr运算符的左操作数,属于数组类型。它无法修改 因此,它不是指针算术,而是由赋值运算符上的语言约束,这是语法错误的原因。

请注意,在某些上下文中,数组会衰减为指向其第一个元素的指针,尽管指针和数组是不同的类型。 数组不是指针。它只是指针算术和数组索引是等价的。例如

=

答案 2 :(得分:10)

这是因为数组与指针类似,只是它们无法修改。但是,您可以修改指向数组的指针。对于上面的示例,您可以这样做:

char arr[]="Hello";
char *ptr=arr;
ptr=ptr+1;

最初,指针ptr将指向数组的第一个字符,即'H',并且在修改该值之后,它将指向第二个字符,即'e'。您还可以执行以下操作:

char arr[]="Hello";
char *ptr=arr;
ptr=arr+1;

两者都产生相同的效果,表明arr+1确实是指针算术。但是,您无法修改arr的值,因为它的类型是字符数组的类型而不是指向字符数组的指针。

答案 3 :(得分:8)

  

据我所知,具有数组类型的表达式将转换为指向数组的初始元素的指针类型。

在大多数情况下都是如此。在以下情况中并非如此:

  1. 使用addressof运算符(&arr)时。 &arr的类型为char (*)[6]。它不是char**

  2. 使用sizeof运算符时。 sizeof(arr)6。如果它是一个指针,它将是指针的大小(在大多数常见平台中为4或8)。

  3. 用作赋值运算符的LHS时。数组类型的变量不可修改。

  4.   

    因此,我期望arr = arr + 1(指向数组的第一个元素(arr)的指针成为指向数组的第二个元素的指针)。为什么这不适用于C?

    表达式的RHS求值为指向arr的第二个元素的指针。但是,由于上述(3),该行不起作用。 arr不是可修改的值。它不能用作赋值运算符的LHS。

答案 4 :(得分:4)

char[]不是指针,而char*是指针。 这有效,但这是错误的解决方案:

int main()
{
    char *arr = "Hello";
    arr = arr + 1;  // Wrong!
    printf("%s\n", arr); // Output: ello
}

如果arrmalloc进行堆分配,如果free内存开始arr+1而不是arr,则可能会导致内存泄漏。

但你可以这样做:

int main()
{
    char arr[] = "Hello";
    char *wordFromSecondLetter = &arr[0] + 1;
    printf("%s\n", wordFromSecondLetter); // Output: ello
}

或者像这样

int main()
{
    char arr[] = "Hello";
    printf("%s\n", &arr[1]); // Output: ello
}

答案 5 :(得分:3)

因为arr不是指针而是char数组。您可以通过选中sizeof arr来验证这一点。要获取指向char的指针,您应该使用char *arr = "Hello";

指针和数组之间的最大区别在于,您可以直接为指针赋值,但不能对数组执行此操作。

事实上,当你写arr + 1arr&#34;衰退&#34;指向其第一个元素的指针,即arr == &arr[0]。所以arr + 1是合法的指针算术,但将其值赋给arr,这是一个数组,是非法的。