Когда функция вызывается в C, переменные должны иметь новый адрес? - PullRequest
1 голос
/ 21 сентября 2010

Я немного озадачен поведением программы на C другого программиста, с которым я сейчас работаю.Что я не могу понять, так это:

1) переменная определяется таким образом

typedef float (array3d_i)[3];
array3d_i d_i[NMAX];

2) как только некоторые значения назначены для всех d_i, вызывается функция, котораякак это:

void calc(elem3d_i d_element);

, который вызывается из main используя:

calc(d_i[i]);

в цикле.

Когда d_i инициализируются в main, каждый элемент получаетадрес в памяти, я думаю, в стеке или где-то еще.Когда мы вызываем функцию «calc», я ожидаю, что внутри функции будет создана копия переменной по другому адресу.Но я отладил программу и вижу, что внутри функции «calc» переменная «d_elemt» получает тот же адрес, что и d_i в main.

Это нормально или нет?

Я еще больше сбит с толку, потому что позже происходит вызов другой функции, очень похожая ситуация, за исключением того, что теперь переменные имеют тип float, а также их массив инициализируется, и внутри функции переменным присваивается другой адрес, чем вmain.

Как это может быть?Почему разница?Код или отладчик делают что-то странное?

Спасибо

Ответы [ 4 ]

3 голосов
/ 21 сентября 2010

Массивы передаются по ссылке в C, а простые значения передаются по значению.Или, скорее, массивы также передаются по значению, но «значение» массива в этом контексте является ссылкой на его первый элемент.Это «распад», на который ссылается Чарльз в своем комментарии.

Под «ссылкой» я подразумеваю указатель, конечно, поскольку у C нет ссылок, как у C ++.

C не имеетконцепция массива более высокого уровня, поэтому вы не можете вычислить длину массива в вызываемой функции.

2 голосов
/ 21 сентября 2010

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

0 голосов
/ 21 сентября 2010

Как уже отмечали другие, все передается по значению.Однако это может вводить в заблуждение для массивов.Хотя массивы похожи на указатели, они не являются указателями.Указатели - это переменные, которые содержат адреса.Массивы - это блоки памяти по определенному адресу.Для массивов не существует отдельной переменной, которая содержит адрес, как указатель.Когда вы передаете массив в качестве аргумента функции или получаете его адрес, присваивая указателю имя (без индексации []), тогда его адрес содержится в переменной.Таким образом, то, что «передается по значению», это указатель, а не массив, даже если вы вызывали функцию с массивом в качестве аргумента.Таким образом, следующие значения эквивалентны:

void func1(char *const arg);
void func2(char arg[]);
0 голосов
/ 21 сентября 2010

Обратите внимание, что "передающие массивы" такие же, как и передающие указатели, и что в C все параметры передаются по значению.

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

Представьте

int a = 42, b = 42, c = 42;

Если вы посмотрите на a, b или c в отладчике, вы всегда увидите 42 ( значение ), но это разные переменные.

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