Смущающий вывод двух разных Char Array - PullRequest
0 голосов
/ 04 февраля 2019

enter image description here

Хотя я объявил две строки символов, содержимое которых одинаково, выходные данные различны.

#include <stdio.h>
int main(){

int i;
char arr1[10]={'0','1','2','3','4','5','6','7','8','9'};
char arr2[10]="0123456789";

for(i=0 ; i<11 ;++i){

    printf("arr1[%d] is %c \t\t",i,arr1[i]);
    printf("arr2[%d] is %c\n",i,arr2[i]);

        if(arr1[i]=='\0')
        printf("%d . character is \\0 of arr1 \n",i);

        if(arr2[i]=='\0')
        printf("%d . character is \\0 of arr2 \n",i);
}

    return(0);
}

Я ожидал, что оба оператора ifистина для любого значения «i». Неважно, что такое «i».

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Оба случая вызывают неопределенное поведение, обращаясь к массиву за пределами.Вы не можете получить доступ к индексу 10 массива с элементами, расположенными от индекса 0 до 9. Поэтому вам нужно изменить цикл на i<10, иначе может произойти что-либо.Просто оказалось, что напечатаны разные значения - потому что у вас нет никаких гарантий того, что будет напечатано для байта с индексом 10.

В обоих примерах нет нулевого терминатора, поэтому ониэквивалентны.Из-за тонкого, странного правила в языке C (C17 6.7.9 / 14 выделено мое):

Массив символьного типа может быть инициализирован символьным строковым литералом или строковым литералом UTF-8опционально заключены в фигурные скобки.Последовательные байты строкового литерала (, включая завершающий нулевой символ, если есть место или массив неизвестного размера), инициализируют элементы массива.

Обычно при попыткечтобы сохранить слишком много инициализаций внутри массива, мы получаем ошибку компилятора.Но не в этом очень специфическом случае со строковым литеральным инициализатором, который является своего рода «языковой ошибкой».Измените на char arr2[9]="0123456789";, и он не скомпилируется.Измените значение на char arr2[11]="0123456789";, и оно будет работать нормально, даже при переборе 11 элементов.

0 голосов
/ 04 февраля 2019

Есть несколько мелких ошибок в вашем коде и предположениях, которые вы, похоже, делаете по этому поводу.

1.Эти два объявления не совпадают

char arr1[10]={'0','1','2','3','4','5','6','7','8','9'};
char arr2[10]="0123456789";

Вторая строка равна этому:

char arr2[10]={'0','1','2','3','4','5','6','7','8','9', 0x00};

... который определяет массив, содержащий 11 элементов.Проверьте неявное нулевое завершение для строковых литералов.

РЕДАКТИРОВАТЬ: Я получил довольно много отрицательных голосов специально для этого пункта.Пожалуйста, смотрите комментарий Lundin ниже, который проясняет проблему.

2.Ваш цикл for выполняет итерации по 11 элементам

for(i=0 ; i<11 ;++i)

Вышеприведенный цикл проходит через i = 0..10, то есть 11 элементов .... но вы только хотелисравнивать первые 10 правильно?

Вы можете изменить свой цикл, чтобы сравнивать только первые десять элементов [for(i = 0; i < 10; ++i)], и это заставит вашу программу работать так, как вы ожидаете.

Из-за того, что вы предполагаете, я бы порекомендовал прочитать строки в C, индексы массивов и неопределенное поведение.

...