C указывает на функции как param

#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, поэтому вы просто передаете его как есть. Нет необходимости уважать его.