Как значение массива b [] может быть заполнено значением другого массива a [] из другой функции? - PullRequest
0 голосов
/ 14 октября 2019

Я нашел этот код в интернете. И я запутался с 1 часа. Что мне показалось странным, так это то, что массив b [] находится внутри функции met2 () с локальной областью видимости. И есть еще один массив a [], который находится внутри функции met1 () с локальной областью видимости. Но как может значение a [] переносится в массив b []. И самое главное, обе функции не возвращают никаких значений. Это так запутанно. Пожалуйста, помогите мне здесь. Я искал в Интернете, но никто не задавал такие вопросы.

#include <stdio.h>
int main()
{
    met2();
    return 0;
}
void met1(int a[1])
{
    a[0]=199;
}
void met2()
{
    int b[1];
    met1(b);
    printf("%d",b[0]);
}

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Ключевым моментом здесь является понимание того, что всякий раз, когда мы объявляем массив как параметр функции, он настраивается на указатель на свой первый элемент. C17 6.7.6.3 выделенная шахта:

Объявление параметра как «массива типа» должно быть скорректировано на «квалифицированный указатель на тип »,где квалификаторы типа (если таковые имеются) - это те, которые указаны в [и] деривации типа массива.

Это означает, что void met1(int a[1]) и void met1(int* a) эквивалентны на 100%. Первый автоматически переводится в компилятор.

Это довольно странно, потому что int a[1] выглядит как объявление массива, и можно легко понять, что массив передается по значению. Но передача массивов по значению невозможна в C.

В вашем случае, локальный массив b передается в met1 как указатель на его первый элемент. С a[0] = ... этот указанный элемент изменяется.

0 голосов
/ 14 октября 2019

За исключением случаев, когда он является операндом операторов sizeof или унарных & или является строковым литералом, используемым для инициализации массива символов в объявлении, N-элемент выражение типа "N"массив T "преобразуется (" распадается ") в выражение типа" указатель на T ", а значением выражения является адрес первого элемента массива.

Когда выcall

met1(b);

выражение b преобразуется из типа "массив из 1 элемента int" в тип "указатель на int" и значениевыражение - это адрес b[0].

В прототипе функции

void met1(int a[1])

объявление параметра int a[1] "скорректировано" до int *a - оно фактически объявляется как указатель(что удобно, поскольку именно это и получает функция).

Поэтому, когда met2 вызывает met1, он передает адрес первого элемента b. Оператор [] может бытьиспользуется для указателей, а также массивов (это на самом деле определяется в тошибки арифметики указателя - a[i] интерпретируется как *(a + i)).

Таким образом, запись a[0] = 199; в met1 эквивалентна записи b[0] = 199; в met2.

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