Нужна помощь в понимании странного поведения C - PullRequest
2 голосов
/ 11 апреля 2010

Эта часть моего кода работает нормально:

#include <stdio.h>

int main(){
    //char somestring[3] = "abc";
    int i, j; 
    int count = 5;

    for((i=0) && (j=0); count > 0; i++ && j++){
        printf("i = %d  and j = %d\n", i, j);
        count--;
    }

    return 0;
}

Выход, как и ожидалось:

i : 0 and j : 0
i : 1 and j : 1
i : 2 and j : 2
i : 3 and j : 3
i : 4 and j : 4

Все становится странно, когда я раскомментирую объявление строки символов в первой строке тела функции.

#include <stdio.h>

int main(){
    char somestring[3] = "abc";
    ...
}

Выход:

i : 0 and j : 4195392
i : 1 and j : 4195393
i : 2 and j : 4195394
i : 3 and j : 4195395
i : 4 and j : 4195396

Какая логика стоит за этим? Я использую gcc 4.4.1 в Ubuntu 9.10.

Ответы [ 5 ]

18 голосов
/ 11 апреля 2010

j никогда не инициализируется из-за короткого замыкания из &&. Поскольку (i=0) оценивается как ложное, (j=0) никогда не выполняется и, следовательно, j получает случайное значение. В первом примере это просто ноль.

Вы должны сказать i=0, j=0, чтобы достичь того, что вы хотите.

У i++ && j++ та же проблема; это должно быть i++, j++.

Также это:

char somestring[3] = "abc";

резервирует слишком мало байтов из-за завершающего символа NUL в строке - вам нужно четыре байта. Но если вы не собираетесь изменять строку, вам не нужно указывать количество байтов - вы можете просто сказать это:

char *somestring = "abc";

вместо.

2 голосов
/ 11 апреля 2010

Если вы используете &&, оценивается только первый аргумент, если он ложный.i = 0 является ложным, поэтому j не устанавливается в 0. Вы должны использовать оператор komma:

for((i=0) , (j=0); count > 0; i++, j++){ [...]
1 голос
/ 11 апреля 2010

for((i=0) && (j=0)..., похоже, уже неверно.
i=0 уже имеет значение 0, поэтому оценка j=0 не требуется, поэтому она пропускается.

(i++) && (j++) представляется неправильным и для самой первой итерации, по той же причине.

0 голосов
/ 11 апреля 2010

Ваши переменные i & j не инициализированы. Что означает (i=0) && (j=0)? Компилятор сделает ярлык и назначит только i=0 j, оставаясь неинициализированным с описанным вами эффектом.

0 голосов
/ 11 апреля 2010

Вы используете (i==0) && (j==0) для инициализации обеих переменных в цикле.

Однако свойство && заключается в том, что если первый операнд оценивается как ЛОЖЬ (т. Е. 0), второй операнд никогда не выполняется. Таким образом, поскольку я равен 0, j остается неинициализированным. При первом запуске вам просто повезло , так как в нем оказалось значение 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...