2d C массив не печатается или создается неправильно

#arrays #c #gcc #ubuntu-18.04 #windows-subsystem-for-linux

Вопрос:

Я написал фрагмент кода на языке си для создания 2d-массива, а затем распечатал его. Однако он не печатается, и я вижу, что каждый цикл, похоже, выполняется в нужное время.

Я очень новичок в c, так что этот ответ может быть действительно простым, извините.

мой код компилируется нормально (gcc), но затем возвращает не то, что я ожидаю. я использую ubuntu 18.04 в WSL с gcc в качестве компилятора.

вот мой код:

 
#include <stdio.h>

int main(void) {
    int i, k;

    int array[2][3] = {0};

    for (i = 0; i < 2; i  ) {
        printf("l1 ");
        for (k = 0; k < 3; k  ) {
            scanf("%d", amp;array[i][k]);
            printf("l2 ");
        }
    }

    for (int i = 0; i < 3;   i) {
        printf("l3 ");
        printf("%d ",  array[k][i]);

        if(i == 2) {
                i = -1;
                  k;
                printf("n");
        }
        if(k == 3) {
                printf("yay");
                return 0;
        }
    }
}
 

окно терминала выглядит следующим образом:

 l1 1
l2 2
l2 3
l2 l1 4
l2 5
l2 6
l2 l3 32602 yay
 

числа-это элементы, которые я ввожу, кроме последнего, который, похоже, выходит в качестве вывода, однако он совсем не похож на то, что я ожидал бы.

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

Спасибо.

Комментарии:

1. «так что мой синтаксис кажется нормальным». Синтаксические ошибки — это только самые простые ошибки. Ваш компилятор даже сообщает вам о них. Все остальные ошибки найти труднее.

2. Общий совет: Для таких крошечных программ самым первым шагом было бы запустить их в отладчике и выполнить инструкции, наблюдая за соответствующими переменными. Это должно сразу показать вам, где вы находитесь во втором цикле и какое значение k имеет значение.

3. Мне нравится подход, но я думаю, что он чрезмерно усложняет задачу, прежде всего, как отметил @Gerhardh, вы используете его повторно k сразу после окончания второго цикла, вам следует сделать второй шаг назад и подумать о том, какова k может быть ценность. Я бы постарался подойти к проблеме, используя наиболее интуитивное решение, чтобы мне не приходилось сталкиваться с такими нюансами!

4. @Новичок вам не нужно говорить нам, что синтаксических ошибок нет, потому что, если бы были синтаксические ошибки, вы бы показали нам журнал ошибок компилятора, не так ли?

5. @Newbie отличная возможность учиться, безусловно, есть много учебных пособий

Ответ №1:

Я рекомендую вам установить ddd (отладчик отображения, по умолчанию он использует gdb). сделайте

 sudo apt install ddd
 

А теперь сделай

 gcc -g test.c
 

теперь вы получаете.выход. (если вы это сделаете gcc -g test.c -o test , вы получите test как исполняемый файл)

и запустите отладчик.

 ddd a.out
 

теперь вы увидите окно исходного кода и окно командной строки. В окне командной строки введите b main (разрыв в главном). A.out работает и останавливается в main. (вы знаете, что есть материалы, запущенные до main.) нажмите » n » для следующего (запуск до следующей строки), чтобы войти в функцию , нажмите s (шаг), чтобы завершить функцию изнутри , нажмите f , чтобы запустить до строки 100, u 100 и т. Д. Поиск по командам gdb. Чтобы отобразить переменную в отдельном графическом окне, выполните graph disp i . Чтобы установить разрыв в строке 100, b 100 , чтобы установить разрыв в строке 100, если j == 3, b 100 if j == 3 . Чтобы напечатать значение i, p i , Есть команда watch (вы запускаете ее, когда наблюдаемое значение изменяется, оно останавливается) и т. Д.
Я не знаю, что вы пытаетесь сделать, но разве вы не забыли установить k=0 между двумя большими циклами for? В любом случае, вы могли бы выполнить отладку и найти, где это неправильно.
ДОБАВИТЬ : Если вы хотите использовать обычный gdb, после ввода введите layout src и вы получите исходный код. Команды восстановления те же, за исключением графического отображения.

Ответ №2:

     int i, k;

    int array[2][3] = {0};

    for (i = 0; i < 2; i  ) {
        printf("l1 ");
        for (k = 0; k < 3; k  ) {
            scanf("%d", amp;array[i][k]);
            printf("l2 ");
        }
    }
 

Рассмотрим этот цикл, он оставит » k » при k=3 после завершения, а затем, если вы сделаете это:

     for (int i = 0; i < 3;   i) {
        printf("l3 ");
        printf("%d ",  array[k][i]); // exactly here

        if(i == 2) {
                i = -1;
                  k;
                printf("n");
        }
        if(k == 3) {
                printf("yay");
                return 0;
        }
    }
 

Вы попытаетесь получить доступ к arr[3][0], который выходит за рамки, поэтому печатается 32602,
и по мере дальнейшего продвижения с k=3 и(все еще) i=0 вы переходите к условию if(k==3), которое печатает yay , возвращает 0 и завершает процесс.

Комментарии:

1. Но добавление чего-то как k=0 между двумя циклами не решит проблему, так как вы будете продолжать увеличивать это число k до числа 3, пока цикл не остановится, и он все равно попытается напечатать массив[2][x]