Пройдите 2-мерный массив в C - PullRequest
0 голосов
/ 17 марта 2012

Я хочу напечатать значение двумерного массива, одно за другим. Но мой код показывает один элемент много раз :(

#include<stdio.h>
#include<conio.h>

void main()
{
    char words[][5]={"Hiii","Hello"};
    int size;
    char *cp,*p;
    p=words;
    clrscr();
    printf("%p ",p);
    size=sizeof(words);
    printf("Size %d\n",size);
    for(cp=p;cp<(p+size);cp++)
        printf("%s ",cp);
    getch();
}

Ожидаемое о / п
Hiii
Привет

Неожиданно, о / п
Hiii
III
II
я

Hello
ELLO
LLO
л
о

Ответы [ 3 ]

2 голосов
/ 17 марта 2012

Прежде всего, массив words располагается в памяти как

Hiii\0Hello

Кроме того, поскольку cp является указателем на char, выражение cp++ увеличивает cp точно на байт. Это вы печатаете "Hiii", затем "iii", затем "ii" и "i". Для правильности cp++ следует изменить на cp += 5.

Наконец, массив имеет неправильный размер. Длина "Hiii" равна 5, а длина "Hello" равна 6, поскольку в конце каждой строки имеется неявный нулевой терминатор \0. Таким образом, words должен быть объявлен как char words[][6]={"Hiii","Hello"};. Это также означает, что cp теперь должно увеличиваться на 6 каждый раз.

С внесенными исправлениями петля for становится

for(cp=p;cp<(p+size);cp+=6)
  printf("%s ",cp);

Чтобы упростить вам жизнь, поскольку вы работаете с массивом, вы можете использовать индексы, а не полагаться на арифметику указателей:

int strCount = size / 6; // since each element of words is 6 characters long
for(int i = 0; i < strCount; i++)
    printf("%s ", cp);
0 голосов
/ 17 марта 2012
 char words[][5]={"Hiii", "Hello"};

Строковый литерал Hello имеет длину 6 символов (включая нулевой символ), но он инициализирует массив типа char[5] (запомните words - это массив 2 из массива 5 из char).

Когда строковый литерал используется для инициализации массива фиксированного размера (здесь массив char[5]), для инициализации массива используется только количество элементов, которые помещаются в массив.

То есть структура памяти words:

Hiii\0Hello

завершающий нулевой символ "Hello" не копируется, поскольку он не помещается в объект char[5].

(Обратите внимание, что это верно для C, в C ++ было бы неправильно инициализировать массив строковым литералом с большим количеством символов, чем количество элементов в массиве).

В вашем случае, вы хотите освободить место для завершенного нулевого символа "Hello", поэтому вы должны объявить words как:

 char words[][6]={"Hiii", "Hello"};
              ^ instead of 5
0 голосов
/ 17 марта 2012

Вы используете ("% s", cp) - печатает начальную форму строки с нулевым символом в конце cp, когда вы хотите напечатать символ cp, на который указывает.

...