Что происходит с указателями в этом отрывке?

Мне любопытно относительно того, почему это - ошибка и что означает сообщение об ошибке. Вот некоторый код:

int *x[] = {"foo", "bar", "baz"};
int *y[] = {"foo", "bar", "baz"};

x = y;

Я пытаюсь скомпилировать, и я получаю это:

error: incompatible types when assigning to type ‘char *[3]’ from type ‘char **’

Вопрос № 1, почему это - ошибка? и Вопрос № 2, почему типы отличаются?

7
задан Stephen 23 August 2011 в 00:18
поделиться

5 ответов

по какой-то причине я не могу использовать ту же учетную запись, с которой опубликовал вопрос.

Фишка с "int" была с моей стороны опечаткой, я действительно имел в виду, что это "char". Извините за путаницу.

Однако, думаю, кафе ответило на мой вопрос.

«Это ошибка, потому что массив является неизменяемым lvalue - это означает, что вы не можете назначать ему напрямую. Вы можете изменять только члены массива индивидуально».

Я просто пытаюсь понять как работают указатели в c, поэтому я пробую эти случайные вещи, которые вы, вероятно, обычно не делаете. Я думал, что это может сработать, так как я думал, что массивы = указатели, поэтому я могу просто указать x на y. Думаю, нет?

Спасибо за все ваши ответы, ребята.

0
ответ дан 7 December 2019 в 01:18
поделиться

Как написано, проблем довольно много. Во-первых, литералы массива имеют тип char * [] , а x и y имеют тип int * [] . Во-вторых, вы не можете назначать массивы напрямую, поскольку они фактически являются постоянными указателями.

5
ответ дан 7 December 2019 в 01:18
поделиться

Я бы порекомендовал начать с хорошего руководства по указателям и массивам. Похоже, вы пришли с интерпретируемого языка, такого как JavaScript или PHP. В C все обстоит иначе, и вам нужно разобраться с понятиями стековой памяти, памяти кучи, указателей и т. Д. Как только вы это сделаете, все обретет смысл, и вы полюбите C.

{{1} }
0
ответ дан 7 December 2019 в 01:18
поделиться

Возникла ошибка несовместимости типов, поскольку вы назначаете массивы строк (тип char * в C) массивам указателей на целые числа (например, int * x [] ). Сообщение об ошибке, выдаваемое компилятором, немного сбивает с толку, потому что C многое делает за кулисами, пытаясь преобразовать переменные из одного типа в другой.

Поскольку символы представлены внутри как числа (буквы соответствуют их значениям ASCII), C может преобразовывать символы в целые числа, поэтому он пытается рассматривать переменные x и y как массивы указателей на символы вместо целых чисел, следовательно, символ * [3] . Он видит {"foo", "bar", "baz"} как тип char ** , потому что строки имеют тип char * , а массивы по существу хранятся как указатели в C, поэтому указатель на char * или char ** .

Хотя это не полностью относится к вашему вопросу, мне также интересно, что вы пытаетесь сделать с x = y; Как написано, это заставит x указывать на тот же массив, что и y, оставляя массив, на который x указывал, недоступным. Чтобы проверить, равны ли две переменные в C, вы должны использовать оператор ==. Проверить равенство не так просто для массивов или строк, но это полностью выходит за рамки этого вопроса.

3
ответ дан 7 December 2019 в 01:18
поделиться

Это ошибка, потому что массив является неизменяемым lvalue, то есть вы не можете присвоить ему напрямую. Вы можете изменять только элементы массива по отдельности.

Типы различаются, потому что, если массив используется в контексте, где lvalue не требуется, он оценивается как указатель на его первый элемент ( somearray становится фактически & somearray [0] ).

Поскольку в таком контексте используется массив y , он оценивается как адрес своего первого элемента, имеющего тип int ** . Поскольку массив x равен в контексте lvalue, он оценивается как массив ( int * [3] ). (Ваше сообщение об ошибке на самом деле не соответствует вашему коду - я подозреваю, что ваши массивы на самом деле являются массивами char * ).

(«lvalue context» в значительной степени означает одно из: левой части оператора присваивания (отсюда и название); предмета оператора sizeof ; или предмета оператора & ).

2
ответ дан 7 December 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: