C : Проблема с зубчатыми массивами

У меня есть следующий код:

int *edges[500];
char arr[] = {'c','d'};
edges[0] = arr;
printf("%c - %c", edges[0][0],edges[0][1]);

То, что я хочу отобразить, это c - d, но на самом деле отображается c -
Итак, как вы можете видеть выше, отображается первый элемент, а не второй.

Почему не отображается второй элемент массива?


person Andreas Grech    schedule 19.10.2009    source источник
comment
Вы уверены, что - должен быть там?   -  person Jacob    schedule 19.10.2009
comment
@Jacob, он оказывается там, потому что edges[0][0] и edges[0][1] в конечном итоге получают доступ к неинициализированной памяти. На моем компьютере программа печатает c "   -  person Sinan Ünür    schedule 19.10.2009
comment
Правильно, попался. Но разве OP не должен отображать c d, а не c - d?   -  person Jacob    schedule 19.10.2009
comment
извините, код был немного изменен из идеи в вопрос; я исправил это сейчас   -  person Andreas Grech    schedule 19.10.2009


Ответы (6)


Поскольку int и char имеют разные размеры, попробуйте char *edges[500]

person Jacob    schedule 19.10.2009
comment
Превосходно; в этом была проблема. - person Andreas Grech; 19.10.2009

Несоответствие типов. edges — это массив из 500 указателей на int, и вы назначаете указатель на два символа его первому элементу.

person dirkgently    schedule 19.10.2009

Ну,

t.c:6: warning: assignment from incompatible pointer type

сообщение может иметь какое-то отношение к этому.

В C 'c' — это (маленькое) целое число. Вы сохраняете их как char в arr. Однако, обращаясь к arr как edges[0], который является int *, вы фактически извлекаете (на большинстве платформ) arr[0], arr[1], arr[2] и arr[3] как целое число.

person Sinan Ünür    schedule 19.10.2009

edges[0] интерпретируется как массив int с элементами {(int)'cd' , 0} (на самом деле второй элемент может содержать любой хлам).

printf со спецификатором %c принимает первый байт edges[0][0] (то есть 'c') и первый байт edges[0][1] (который оказался равным 0).

изменить тип edges на char* edgeds[500].

person elder_george    schedule 19.10.2009

строка 3

edges[0] = arr;

несовместимые типы в назначении: arr — это char *, а edges[0] — это int *.

Происходит следующее:

int *edges[500];
char arr[] = {'c','d'};

arr[0] — это «c», а arr[1] — это «d»

edges[0] = arr;

Игнорируя совместимость типов, edge[0] указывает на int по адресу, где находятся 'c' и 'd' (и, возможно, еще два неуказанных символа).

printf("%c %c", edges[0][0],edges[0][1]);

ребра[0][0] — первое целое число в ребрах[0]: это сочетание 'c', 'd' (и, возможно, еще двух неуказанных символов). Это значение преобразуется в unsigned char, в результате чего выводится символ 'c'.
edge[0][1] указывает на целое число сразу после сочетания 'c', 'd' (и, возможно, еще двух неуказанных символов). . Эта ячейка памяти не была инициализирована и вполне может находиться за пределами диапазона, к которому может получить доступ ваш процесс.

если вы печатаете int вместо 2 символов

printf("%d\n", edges[0][0]);

вы увидите смесь «c», «d» (и, возможно, два неуказанных символа).

Лучшее, что можно сделать, — правильно подобрать типы.

person pmg    schedule 19.10.2009

edges — это массив указателей на int. Выражение edges[0] дает указатель на int, а не на char. Обработка его как массива символов приводит к вычислению неправильного смещения байтов, в результате чего отображается значение неожиданного фрагмента памяти, а не памяти, содержащей значение char 'd'.

Смещения массива вычисляют смещение в байтах на основе размера типа, на который указывает:

foo_t * x;
ptrdiff_t difference = x[1] - x[0];

Значение difference будет sizeof(foo_t) байт. sizeof(char) определяется как 1, а sizeof(int) обычно равно 4, что означает, что ваш код будет разыменовывать значение 4 байта в массиве символов, а не 1 байт в массиве символов.

person Tim Martin    schedule 19.10.2009