Поле массива структуры полностью клонируется, когда передается по значению в функцию? - PullRequest
0 голосов
/ 13 сентября 2018

В С:

  • Когда struct отправляется (через параметр) по значению в функцию, создается новая struct , поэтому изменение структуры внутри функции выиграет изменить первоначальную структуру.

  • Когда массив отправляется (через параметр) по значению в функцию, создается новый указатель , поэтому изменение массива внутри функции t изменить исходный массив, но изменение значений массива внутри функции (поскольку у нас есть указатель на исходный массив) изменит значения в исходном массиве.

  • Когда struct с полем array отправляется (через параметр) по значению в функцию, ????? создается так, что изменение массива (указателя) внутри функции не изменит исходного массива, а изменение значений массива не изменит значений в исходном массиве.

Означает ли третий пункт, что массив поля struct при отправке в функцию будет полностью клонирован? Почему вместо него используется только указатель? Что спецификация говорит об этом?

фрагмент кода, с которым я играл:

typedef struct {
    int value;
    int array[3]; /* initialized to 0 by default */
} Struct_t;

void foo(Struct_t structure)
{
    printf("-- %p\n", structure.array); /* Pointer to local array */

    structure.value = 1;
    *structure.array = 1;       /* Won't change the original array */
    *(structure.array + 1) = 1; /* Won't change the original array */
    structure.array[2] = 1;     /* Won't change the original array */
}

int main()
{
    Struct_t s = { .value = 0 };

    foo(s);

    printf("-- %p\n", s.array); /* Pointer to original array */

    printf("%d\n", s.value);
    printf("%d\n", s.array[0]);
    printf("%d\n", s.array[1]);
    printf("%d\n", s.array[2]);
}

Выход:

-- 0x7ffe8f17d194
-- 0x7ffe8f17d1b4
0
0
0
0

Ответы [ 4 ]

0 голосов
/ 13 сентября 2018

ОП "Когда массив отправляется ..." нуждается в пояснении.

Когда массив отправляется (через параметр) по значению в функцию, создается новый указатель, поэтомуизменение массива внутри функции не изменит исходный массив, но изменение значений массива внутри функции (поскольку у нас есть указатель на исходный массив) изменит значения в исходном массиве.(OP)

Когда массив, такой как s[] ниже, передается в strcpy(char *s1, const char *s2), происходит преобразование first .Объект s преобразуется в адрес первого элемента массива.strcpy() не получает s[] в качестве параметра s1, вместо этого он получает копию значения &s[0].

char s[6] = "Hello";
strcpy(s, "World");

В пределах strcpy(), s1 не является массив .s1 - указатель на char.strcpy() не имеет понятия «изменение массива внутри функции», так как функция не знает, s1 указывает на память массива, выделенную память или что-либо еще.strcpy() понимает s1 указывает на char.


Означает ли третья точка, что поле массива структуры при отправке в функцию будет полностью клонировано?

Да.Когда объект передается функции в C, он потенциально конвертируется и затем передается по значению.Это очень похоже на любое задание.Содержимое объекта после преобразования копируется в место назначения.После преобразования не имеет значения, является ли объект struct, union, int, double, void*, int(*)() и т. Д. Или a struct, содержащий массив .

int a;
double b;
a = 5;  // 5 is copied to a
b = a;  // a is converted to double and copied to b


char s[6] = "Hello";
char *e;
void *v;
e = s; // s is converted to the address on the first array element and then copied to e
v = e; // e is converted to a `void*` and then copied to v

Struct_t f = {0};
Struct_t g;
g = f; // f is copied to g
0 голосов
/ 13 сентября 2018

Структура - это предопределенная структура памяти, которая имеет определенную структуру памяти.При добавлении массива в структуру фактическая память массива находится в структуре, а не указатель.Вот почему он должен быть скопирован с остальной частью структуры.

Массивы не являются указателями, у массивов есть определенная неизменяемая область памяти, в то время как указатель может указывать куда угодно.

0 голосов
/ 13 сентября 2018

Означает ли третья точка, что поле массива структуры при отправке в функцию будет полностью клонировано?

Да.

Почему вместо него используется только указатель?

Потому что нет указателя.Массив является , а не указателем.( Подробнее об этом здесь. )

0 голосов
/ 13 сентября 2018

В C все передается по значению.

  1. Когда мы передаем по значению, мы передаем копию переменной в функцию.

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

    Копирует значение указателя, адреса в функцию.

Если передано structПо значению функции bytes из struct копируются в качестве параметра функции.Все, что сделано для этого struct в функции, изменяет копию, а не оригинал struct

...