char arr[] = "Hello";
arr = arr + 1; // error occurs
据我所知,具有数组类型的表达式将转换为指向数组初始元素的指针类型。因此,我期望arr = arr + 1
(指向数组的第一个元素(arr)的指针成为指向数组的第二个元素的指针)。为什么这不适用于C?
答案 0 :(得分:55)
<script type="text/javascript">
$("#<?php echo $rows['itemname']; ?>").click(function(e){
//to prevent click
return false;
});
</script>
确实是指向数组第二个元素的指针(即arr + 1
)。
但是,这并不意味着您可以以某种方式将指针值写回&arr[1]
。至少有两个原因你不能这样做。
首先,arr
是arr
元素的数组,而不是指针。这里有明显的类型不匹配。
其次,作为一个数组,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)
据我所知,具有数组类型的表达式将转换为指向数组的初始元素的指针类型。
在大多数情况下都是如此。在以下情况中并非如此:
使用addressof运算符(&arr
)时。 &arr
的类型为char (*)[6]
。它不是char**
。
使用sizeof
运算符时。 sizeof(arr)
是6
。如果它是一个指针,它将是指针的大小(在大多数常见平台中为4或8)。
用作赋值运算符的LHS时。数组类型的变量不可修改。
因此,我期望
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
}
如果arr
与malloc
进行堆分配,如果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 + 1
,arr
&#34;衰退&#34;指向其第一个元素的指针,即arr == &arr[0]
。所以arr + 1
是合法的指针算术,但将其值赋给arr
,这是一个数组,是非法的。