2010-04-18 3 views
7

Мне любопытно, почему это ошибка и что означает сообщение об ошибке. Вот код:Что происходит с указателями в этом фрагменте?

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, почему типы различны?

+10

Почему вы храните символьные строки в массивах, содержащих целые указатели? –

+0

Вы проверили номер строки? – SLaks

ответ

5

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

+2

Я очень хочу, чтобы этот мем погиб. Массивы не являются постоянными указателями - они не являются каким-либо указателем, они являются массивами (непустая непрерывная последовательность объектов того же типа). – caf

+1

Переменная, тип которой представляет собой массив в C, следует семантике, очень похожей на константные указатели. Это та же самая сделка с гравитацией - конечно, она не постоянна по всему миру, и это не действительно нисходящая сила. Тем не менее, полезно рассмотреть оба аспекта, справедливые для подавляющего большинства видов использования. –

3

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

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

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

0

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

2

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

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

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

(«контекст lvalue» означает, в значительной степени, один из: левая сторона оператора присваивания (откуда и происходит название), субъект оператора sizeof или субъект оператора &) ,

0

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

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

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

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

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

Спасибо за ваш ответ.