Рассмотрим следующую программу:

#include <stdio.h>
int main(void)
{
    int a[] = {1, 2, 3};

    for (size_t i = 0; i < 3; i++)
        printf ("%i\n", a[0, i]);

    return 0;
}

Очевидно, что доступ к одномерному массиву a осуществляется как к двумерному массиву, например, в Python. Однако этот код компилируется с предупреждением unused-value. Я ожидал, что это приведет к ошибке, потому что я всегда думал, что это многоиндексирование просто неправильно в C (см. K&R стр. 112). К моему удивлению, приведенный выше код действительно распечатывает элементы массива.

Если вы измените a[0, i] в шестой строке на a[i, 0], первый элемент массива будет напечатан три раза. Если вы используете a[i, 1], второй элемент будет напечатан три раза.

Как синтаксически неправильный мультииндекс в одномерном массиве транслируется в арифметику указателя и какое значение результата a[i, 0] не используется?

И да, я знаю, как многоиндексировать в C.

0
MaxPowers 22 Авг 2019 в 16:51

2 ответа

Лучший ответ

Запятая здесь - это оператор запятых. Это не мультииндексация (которая в идеале имела бы вид [0][i] или [i][0]).

Цитата C11, глава §6.5.17 ( выделение мое )

Левый операнд оператора запятой оценивается как пустое выражение; Eсть Точка последовательности между его оценкой и оценкой правого операнда. Тогда право операнд оценивается; Результат имеет тип и значение.

Итак, в вашем случае

a[0, i]

Такой же как

a[i]

А также

a[i, 0]

Такой же как

a[0]
4
Sourav Ghosh 22 Авг 2019 в 13:59

0, i является допустимым выражением в C. Запятая - это оператор, который оценивает оба операнда и отбрасывает результат левого операнда. При использовании в a[0, i] он эквивалентен a[i]. И a[i, 0] эквивалентен a[0].

(Обратите внимание, что в вызовах функций, таких как f(a, b, c), запятая является разделителем аргументов. Это другая часть грамматики Си, и запятая не является оператором в этом контексте.)

8
Eric Postpischil 22 Авг 2019 в 13:53