指针是否支持“数组样式索引"? [英] Do pointers support "array style indexing"?

查看:23
本文介绍了指针是否支持“数组样式索引"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(自我回答的问答 - 这个问题不断出现)

我假设读者知道指针算法的工作原理.

I assume that the reader is aware of how pointer arithmetic works.

int arr[3] = {1,2,3};
int* ptr = arr;
...
*(ptr + i) = value;

老师/C 书籍一直告诉我我不应该像上面的例子那样使用 *(ptr + i),因为指针支持数组样式索引"我应该使用 ptr[i] = value; 代替.没有争论 - 更容易阅读.

Teachers/C books keep telling me I shouldn't use *(ptr + i) like in the above example, because "pointers support array style indexing" and I should be using ptr[i] = value; instead. No argument there - much easier to read.

但是查看 C 标准,我发现没有什么叫做数组样式索引".事实上,操作符 [] 并不期望任何一个操作数是一个数组,而是一个指针或一个整数!

But looking through the C standard, I find nothing called "array style indexing". In fact, the operator [] is not expecting either operand to be an array, but instead a pointer or an integer!

6.5.2.1 数组下标

约束

其中一个表达式的类型应该是''pointer to complete object type'',另一个表达式应该是整数类型,结果类型是''type''.

One of the expressions shall have type ‘‘pointer to complete object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.

为什么 array 下标运算符不期望数组?标准错了吗?我的老师/C书糊涂了吗?

Why does the array subscripting operator not expect an array? Is the standard wrong? Is my teacher/C book confused?

推荐答案

出于可读性原因,您确实应该使用 ptr[i] 而不是 *(ptr + i).但除此之外,[] 运算符,严格来说,实际上从未与数组操作数一起使用.

You should indeed be using ptr[i] over *(ptr + i) for readability reasons. But apart from that, the [] operator is, strictly speaking, actually never used with an array operand.

数组在表达式中使用时,总是衰减"为指向第一个元素的指针(有一些例外).C17 6.3.2.1/3,强调我的:

Arrays, when used in an expression, always "decay" into a pointer to the first element (with some exceptions). C17 6.3.2.1/3, emphasis mine:

除非是sizeof运算符的操作数,或者一元&运算符,或者是用于初始化数组的字符串文字,类型为类型数组"的表达式将转换为类型为类型指针"的表达式,该表达式指向数组的初始元素数组对象并且不是左值.

Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

这意味着无论何时键入 arr[i],操作数 arr 都会被指向该数组中第一个元素的指针替换.这被非正式地称为数组衰减".更多信息:什么是数组衰减?

Meaning that whenever you type arr[i], the operand arr gets replaced by a pointer to the first element inside that array. This is informally referred to as "array decaying". More info here: What is array decaying?

因此,无论何时使用 [] 运算符,都可以在指针上使用它.总是.

So whenever you use the [] operator, you use it on a pointer. Always.

C 标准说这个操作符保证等价于指针算法(C17 6.5.2.1/2):

The C standard says that this operator is guaranteed to be equivalent to the pointer arithmetic (C17 6.5.2.1/2):

下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2))).

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

因此,每当我们输入 arr[i] 时,它实际上都会被 *(arr+i) 默默替换.其中 arr 仍然是指向第一个元素的指针.

So whenever we type arr[i], it actually gets silently replaced by *(arr+i). Where arr is still a pointer to the first element.

这就是为什么您引用的描述告诉您任一操作数可以是指针而另一个是整数的原因.因为很明显,我们输入 *(arr+i) 还是 *(i+arr) 并不重要——这是等效的代码.

And this is why the description you quoted tells you that either operand could be a pointer and the other an integer. Because obviously it doesn't matter if we type *(arr+i) or *(i+arr) - that's equivalent code.

这反过来又允许我们编写像 i[arr] 这样的混淆笑话"代码,它实际上是有效的 C 并且完全等同于 arr[i].但是不要在实际应用中编写这样的代码.

Which in turn allows us to write obfuscated "joke" code like i[arr], which is actually valid C and fully equivalent to arr[i]. But don't write such code in real applications.

这篇关于指针是否支持“数组样式索引"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆