#c #function #pointers
#c #функция #указатели
Вопрос:
#include<iostream>
using namespace std;
void passPointer(int *pointer)
{
cout << *pointer;
}
int main()
{
int *iNum = new int(25);
passPointer(iNum);
return 0;
}
Может кто-нибудь объяснить мне, почему, когда я использую passPointer()
функцию в main, она должна быть passPointer(iNum)
, но не passPointer(*iNum)
должна? Это потому, что я разыменовываю его в параметре, если я использую *
? Пожалуйста, объясните как можно подробнее, поскольку я немного запутался.
Спасибо, ребята.
Ответ №1:
Это потому, что вы объявили passPointer
, что принимаете аргумент типа int*
. iNum
имеет тип int*
, и поэтому может быть передан напрямую passPointer
. *iNum
имеет тип int
, и нет неявного преобразования int
в int*
, поэтому вы не можете передать его passPointer
.
В более общем плане, в C (и практически во всех других типизированных языках) каждое выражение и каждая переменная имеют тип. Тип выражения выражается в терминах типа его операндов: если тип операнда унарного *
является T*
(и тип должен быть указателем), то тип результатов является T
. И чтобы вызвать функцию, вы должны предоставить правильное количество аргументов с правильными типами.
Ответ №2:
Я очень сочувствую такого рода вопросам, потому что это одна из единственных вещей, с которыми у меня возникли проблемы при изучении C .
Основная проблема заключается в том, что в синтаксисе C символы *
и amp;
используются для многих разных вещей с похожими, но слегка отличающимися значениями.
В вашем случае вы рассматриваете возможность использования *
в четырех разных местах.
Во-первых: int *iNum = new int(25);
, *
находится в объявлении. Это означает, что это аннотация типа, в которой говорится, что iNum
это указатель.
Во-вторых: passPointer(*iNum);
, *
находится в выражении. Это означает, что это оператор разыменования, что означает: «получить значение, на которое указывает iNum
«. В этом случае значение, на которое указывает , iNum
является an int
. Как вы увидите позже, passPointer
объявлено, что принимает аргумент типа pointer to int
, поэтому вы не можете передать равнину int
в качестве аргумента passPointer
. Вместо этого вы должны просто передать iNum
(как iNum
указатель на int).
В-третьих: void passPointer(int *pointer)
, *
снова находится в объявлении. Это означает, что он имеет то же значение, что и в первую очередь — он говорит, что pointer
это указатель (на int
).
В четвертом месте: cout << *pointer;
, *
снова находится в выражении. Это означает, что, как и во втором случае, он говорит «разыменовать pointer
и получить значение, в котором pointer
хранится адрес».
Ответ №3:
Это создает переменную с именем iNum
и типом int *
:
int *iNum = new int(25);
Это принимает параметр типа int *
:
void passPointer(int *pointer)
При этом передается параметр name iNum
и type int *
:
passPointer(iNum);
Не нужно думать об указателях, это все типы данных. Думайте об указателях только тогда, когда вы выполняете арифметику указателей и ссылаетесь, ссылаетесь. 😉
int****
это просто тип.
Ответ №4:
Это потому, что я разыменовываю его в параметре, если я использую
*
?
Да. iNum
имеет указатель типа на int
, *iNum
имеет тип int
. Если бы у вас была функция, которая принимает an int
, вы могли бы передать ее *iNum
.
Ответ №5:
passPointer()
Функция принимает указатель на int. iNum
это уже указатель на int, поэтому вы просто передаете его как есть. Нет необходимости уважать его.