Jin*_*Jin 39 c arrays pointers
char arr[] = "Hello";
arr = arr + 1; // error occurs
Run Code Online (Sandbox Code Playgroud)
据我所知,具有数组类型的表达式将转换为指向数组初始元素的指针类型.因此,我期望arr = arr + 1(指向数组的第一个元素(arr)的指针成为指向数组的第二个元素的指针).为什么这不适用于C?
AnT*_*AnT 55
arr + 1确实是指向数组的第二个元素的指针(即&arr[1]).
但是,这并不意味着您可以以某种方式将指针值写回arr.至少有两个原因你不能这样做.
首先,arr是一个阵列的char元件,而不是一个指针.这里有明显的类型不匹配.
其次,作为一个数组,arr一个不可修改的左值.你不能改变arr自己,你只能改变它的元素(这种区别有点难以掌握,但它就在那里).
最后,如果我们忽略更深层次的复杂性并关注顶层正式发生的事情,由于数组类型衰减,你的表达式相当于
(char *) arr = (char *) arr + 1;
Run Code Online (Sandbox Code Playgroud)
分配是不可能的,因为左侧是[隐式]类型转换的结果.在C类型转换中,始终生成rvalues.您无法分配到右值.
换句话说,它不是这里不允许的"指针算术".指针算术很好.这是你用导致错误的指针算法的结果.
hac*_*cks 23
数组是不可修改的左值.它们不能是赋值运算符的左操作数.
C11-§6.3.2.1:
甲修改的左值是不具有阵列型左值,不具有不完整的类型,[...]
§6.5.16/ 2:
赋值运算符应具有可修改的左值作为其左操作数.
在声明中
arr = arr + 1;
Run Code Online (Sandbox Code Playgroud)
arr是运算=符的左操作数,是数组类型.它无法修改.
因此,它不是指针算术,而是由赋值运算符上的语言约束,这是语法错误的原因.
请注意,在某些上下文中,数组会衰减为指向其第一个元素的指针,尽管指针和数组是不同的类型.数组不是指针.它只是指针算术和数组索引是等价的.例如
char *ptr = &arr[0] + 1 => &(*(arr + 0)) + 1 => &(*arr) + 1 => arr + 1 // * and & nullify each other
Run Code Online (Sandbox Code Playgroud)
Nat*_*ina 10
这是因为数组与指针类似,只是它们无法修改.但是,您可以修改指向数组的指针.对于上面的示例,您可以这样做:
char arr[]="Hello";
char *ptr=arr;
ptr=ptr+1;
Run Code Online (Sandbox Code Playgroud)
最初,指针ptr将指向数组的第一个字符,即'H'在修改值之后,它将指向第二个字符即'e'.您还可以执行以下操作:
char arr[]="Hello";
char *ptr=arr;
ptr=arr+1;
Run Code Online (Sandbox Code Playgroud)
两者都产生相同的效果,表明它arr+1确实是指针算术.但是,您无法修改其值,arr因为其类型是字符数组的类型而不是指向字符数组的指针.
据我所知,具有数组类型的表达式将转换为指向数组的初始元素的指针类型.
在大多数情况下都是如此.在以下情况下并非如此:
使用addressof运算符(&arr)时.类型&arr是char (*)[6].事实并非如此char**.
使用sizeof运营商时.sizeof(arr)是6.如果它是一个指针,它将是指针的大小(在大多数常见平台中为4或8).
用作赋值运算符的LHS时.数组类型的变量不可修改.
因此,我期望
arr = arr + 1(指向数组的第一个元素(arr)的指针成为指向数组的第二个元素的指针).为什么这不适用于C?
表达式的RHS求值为指向第二个元素的指针arr.但是,由于上述(3),该行不起作用.arr不是可修改的值.它不能用作赋值运算符的LHS.
| 归档时间: |
|
| 查看次数: |
4083 次 |
| 最近记录: |