Получите одномерные массивы из двумерного массива в C - PullRequest
1 голос
/ 18 марта 2020

Я пытаюсь написать функцию, которая выдает (в смысле генератора Python ... грубо говоря) элементы двумерного массива по одному в C. Каждый из этих элементов должен быть указателем на 0-е значение 1D-массива. Я озадачен, почему приведенный ниже код не работает должным образом.

#include <stdio.h>
void get_cords(int * coords){
    static int count = 0;
    int list[][2] = {{0,0}, {1,1}};
    // this should assign the starting address of {0,0} to coords the first time the function is called, then the address of {1,1} next time
    coords = list[count];
    count +=1;
}
void main() {
    int coords[] = {0,0};
    get_cords(coords);
    printf("%d, %d\n", coords[0], coords[1]);
    get_cords(coords);
    printf("%d, %d\n", coords[0], coords[1]);
} 

Вывод:

0, 0
0, 0

Интересно, что если мы присваиваем значения индивидуально в get_coords, это работает как и ожидалось:

void get_cords(int * coords){
    static int count = 0;
    int list[][2] = {{0,0}, {1,1}};
    // this should assign the starting address of {0,0} to coords the first time the function is called, then the address of {1,1} next time
    coords[0] = list[count][0];
    coords[1] = list[count][1];
    count +=1;
}

Ожидаемый и фактический результат:

0, 0
1, 1

Может кто-нибудь объяснить, что здесь происходит?

1 Ответ

3 голосов
/ 18 марта 2020

Здесь вы не передаете ссылки.

По сути, это то, что происходит:

В вашей основной функции, когда вы делаете:

Этот массив не выделяется в во время выполнения. Скорее это распределяется во время компиляции. [1]

int coords[] = {0,0};

Когда вы передаете этот массив в функцию, вы фактически передаете адрес его первого элемента.

Грубо говоря, вы можете сказать:

coords —-> &coords[0] 

Поэтому, когда вы передали coords в функцию, вы фактически передали ее адрес.

Если массив хранился по адресу 1000, вы просто передали 1000. [2]

В функции int *coords хранится 1000 в ней. Теперь coords в функции является некоторой другой переменной, которая содержит адрес массива.

Когда вы делаете:

coords = list[count];

Вы меняете адрес, на который указывает coords. Теперь он указывает на адрес массива list. Это просто изменило место, где была создана копия при вводе функциональных точек.

Когда вы это сделали:

coords[0] = list[count][0];
coords[1] = list[count][1];

означает:

coords[0] —-> *(coords + 0)
coords[1] —-> *(coords + 1)

Вы изменили значения по адресу.

Просто для примера, который близок к тому, что вы пытались сделать:

#include <stdio.h>

void get_cords(int ** coords){
    static int count = 0;

    // list is allocated in stack and 
    // would be popped off once func call returns if it's not static
    // static would cause it to be allocated at compile time
    // and it will stay in memory till the end of the program
    static int list[][2] = {{0,0}, {1,1}};

    // at the address that you received in arg, store the address of new arr
    *coords = list[count];

    count += 1;
}
void main() {
    int coords_arr[] = {0,0};

    int *coords = coords_arr;

    // now you are actually passing address of coords pointer
    get_cords(&coords);
    printf("%d, %d\n", coords[0], coords[1]);
    get_cords(&coords);
    printf("%d, %d\n", coords[0], coords[1]);
}

[1] Что означает «память, выделенная во время компиляции» на самом деле значит?

[2] Передача массива в качестве аргумента функции в C

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