Do pointers support “array style indexing”?

喜夏-厌秋 提交于 2019-11-27 03:40:56

问题


(Self-answered Q&A - this matter keeps popping up)

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

int arr[3] = {1,2,3};
int* ptr = arr;
...
*(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.

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

6.5.2.1 Array subscripting

Constraints

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’’.

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


回答1:


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.

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:

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.

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.

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

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

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

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.

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.



来源:https://stackoverflow.com/questions/55747822/do-pointers-support-array-style-indexing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!