2016-09-25 9 views
-1

У меня есть эта крошечная программа, которую я написал для упражнения с указателями C. Я просто беру массив символов и печатаю его в обратном порядке с помощью указателя. Оно работает. Однако я не понимаю, почему это работает. Поскольку я начинаю цикл for в элементе 9, не должен ли он печатать 5 неопределенных элементов (обычно случайных символов нежелательной почты, по моему опыту), прежде чем он попадет в «sdrow»? Я чувствую, что должен фильтровать выход больше.C - Печать неопределенных элементов массива не дает мне мусора

int main(void) 
{ 
    char sentence[10] = "words"; 
    char *ptr = sentence; 

    for(int i=9;i>=0;i--) 
    { 
     printf("%c", *(ptr+i)); 
    } 
    puts(""); 
    return 0; 
} 

Выход:

sdrow 
+2

Как вы узнали бы «неопределенный элемент», если бы встретили его на улице? –

+0

Несколько советов: вместо 'printf («% c », c)', вы можете использовать 'fputc (c, stdout)', а вместо 'puts (" ")' вы могли бы использовать 'fputc ('\ n ', stdout) '. Замены проще и более прямо выражают, что вы хотите напечатать символ. Первый случай избегает синтаксического разбора строки формата, когда вы уже знаете ответ статически. –

+0

@Kerrek SB Хороший компилятор будет генерировать один и тот же код с помощью 'printf ("% c ", c);', а также 'fputc (c, stdout);', а также 'puts (" "); 'fputc ('\ n', stdout);'. Лучше всего использовать контекст и стиль. – chux

ответ

2

При инициализации массива и инициализатор обеспечивает меньше элементов, чем в массиве, остальные элементы инициализируются к нулю:

int a[3] = { 1 }; // same as { 1, 0, 0 } 

char s[4] = "ab"; // same as { 'a', 'b', 0, 0 } 

В другими словами, ваш код печатает пять нулевых байтов перед печатью пяти букв.

(Вы можете увидеть это легко перенаправив вывод в файл и глядя на размер файла.)

+0

ОК, поэтому автоматически инициализированный 0 в массиве char просто равен нулю? Я хочу пояснить это, потому что, если бы я должен был напечатать целочисленный массив, состоящий, например, из кодов ASCII для вышеуказанных символов, он все равно распечатает автоматически инициализированные 0s. – Pen275

1

При инициализации массива фиксированного размера, с автоматически заполняет любые неуказанные элементы нулями. Строки в стиле C обрабатывают эти нули как нулевой символ, который также является символом завершения строки. Итак, первая группа итераций печатает нулевой символ, затем они начинают печатать фактические символы.

0

Остальная часть массива инициализируется компилятором нулями, вот почему вы ничего не видите:

int main(void) 
{ 
    char sentence[10] = "words"; 
    char *ptr = sentence; 

    for(int i=9;i>=0;i--) 
    { 
     printf("%02x", *(ptr+i)); 
    } 
    puts(""); 
    return 0; 
} 

Однако вы не должны полагаться на это, так как поведение не определено. Если вы используете указатели, вы увидите что-то другое:

int main(void) 
{ 
    char *sentence = "words"; 
    char *other ="more"; 
    char *ptr = sentence; 


    for(int i=9;i>=0;i--) 
    { 
     printf("%c", *(ptr+i)); 
    } 
    puts(""); 
    return 0; 
}