問題描述
我在理解某些結合函數指針和函數聲明的 C++ 語法時遇到了問題,即:
I have a problem with understanding some C++ syntax combined with function pointers and function declarations, that is:
通常,當我們想聲明一種函數時,我們會做這樣的事情:
Usually when we want to declare a type of function we make something like:
typedef void(*functionPtr)(int);
這對我來說很好.從現在起 functionPtr 是一個類型,它代表指向函數的指針,該函數返回 void 并以 int 值作為參數.
and this is fine for me. From now on functionPtr is a type, that represents pointer to the function, that returns void and takes int by a value as an argument.
我們可以這樣使用:
typedef void(*functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
然后我們將 5
打印在屏幕上.
And we get 5
printed on a screen.
我們得到了函數fun
的指針,我們為函數分配了一些現有的指針——function
,然后我們通過一個指針來執行這個函數.很酷.
we have got pointer to function fun
, we assign some existing pointer to function - function
and we execute this function by a pointer. Cool.
現在,正如我在一些書中讀到的那樣,函數和指向函數的指針以某種方式被對待函數的類型相同,所以下面的編譯和每條指令給出相同的結果(5 打印在屏幕上):
Now as I read in some books, function and pointer to function are treated somehow the same, so in fact after declaration of function()
function everytime we say function we mean real function and pointer to function at the same type, so following compiles and every instruction gives the same result (5 printed on a screen):
int main() {
functionPtr fun = function;
fun(5);
(*fun)(5);
(*function)(5);
function(5);
return 0;
}
所以現在只要我能想象,指向函數的指針和指向函數的指針幾乎相同,那對我來說就沒什么問題了.
So now as long as I can imagine, that pointers to functions and functions are pretty much the same, then it's somehow fine for me.
那么我雖然,如果指向函數和實際函數的指針是相同的,那我為什么不能做以下操作:
Then I though, if pointer to function and real function is the same, then why cannot I do following:
typedef void(functionPtr)(int); //removed *
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
這給了我以下錯誤:
prog.cpp:12:14: 警告:'void fun(int)' 的聲明有 'extern' 并已初始化functionPtr fun = 函數;
prog.cpp:12:14: warning: declaration of 'void fun(int)' has 'extern' and is initialized functionPtr fun = function;
因此我明白,由于某種原因編譯器現在明白,樂趣是已經存在的功能.然后我嘗試了以下操作:
therefore I understood, that for some reason compiler now understands, that fun is already existing function. Then I tried following:
int main() {
functionPtr fun;
fun(5);
return 0;
}
我遇到了鏈接錯誤.我以某種方式理解,因為編譯器現在將 fun 視為已經存在的函數,然后由于沒有定義該 fun 的事實,我將收到鏈接錯誤.因此我更改了變量的名稱:
And I got linking error. I somehow understand, that as compiler now treats fun as already existing function, then due to the fact, that fun is nowhere defined, I will get linking error. Therefore I changed the name of the variable:
typedef void(functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr function;
function(5);
return 0;
}
所以現在函數在 main shadows 全局名稱函數中,所以 function(5)
用于聲明 functionPtr function;
它工作正常并在屏幕上打印 5.
So now function in main shadows global name function, so function(5)
is used from declaration functionPtr function;
It works fine and prints 5 on the screen.
所以現在我很震驚.為什么會這樣?同樣具有誤導性的是,當函數指針像這樣聲明時:
So now I am shocked. Why did this happen? Also misleading thing is, that when function pointer is declared like this:
typedef void(*functionPtr)(int);
我可以通過以下方式創建 functionPtr 類型的函數:
i can create function of type functionPtr in following manner:
functionPtr function(int a){
std::cout << a << std::endl;
}
然而,在聲明如下內容時:
whereas, when declaring something like:
typedef void(functionPtr)(int);
使這個:
functionPtr function(int a){
std::cout << a << std::endl;
}
被編譯器解釋為函數返回函數.如果是這樣,為什么之前的聲明 (typedef void(functionPtr)(int);
) 知道這是一個返回 void 的函數而不是返回 functionPtr 的函數?
being interpreted by a compiler as function returning function. If this is so, why previous declaration (typedef void(functionPtr)(int);
) knew, that this is a function returning void and not function returning functionPtr?
有人可以為我解釋一下到底發生了什么嗎?
Could someone please explain what is really happening underhood for me?
我正在使用啟用了 C++14 選項的 g++ C++ 編譯器.
I am using g++ C++ compiler with C++14 option enabled.
推薦答案
嗯,有點混亂.
函數類型和函數類型指針確實是兩種不同的類型(不比int
和int
的指針更相似).但是,有一個規則,即函數類型在幾乎所有上下文中衰減指向函數類型的指針.這里decaying 松散地表示轉換(類型轉換和衰減之間有區別,但您現在可能對此不感興趣).
Function type and pointer to function type are indeed two different types (no more similar than int
and pointer to int
). However, there is a rule, that a function type decays to pointer to function type in almost all contexts. Here decaying loosely means converted (there is a difference between type conversion and decaying, but you are probably not interested in it right now).
重要的是,幾乎每次使用函數類型時,最終都會得到指向函數類型的指針.但是請注意幾乎 - 幾乎每次都不是總是!
What is important, is that almost every time you use a function type, you end up with pointer to function type. Note the almost, however - almost every time is not always!
而且您遇到了某些情況,但沒有這樣做.
And you are hitting some cases when it doesn't.
typedef void(functionPtr)(int);
functionPtr fun = function;
這段代碼試圖將一個函數(不是指針!函數!)復制到另一個函數.但當然,這是不可能的——你不能在 C++ 中復制函數.編譯器不允許這樣做,我不敢相信你編譯了它(你是說你有鏈接器錯誤?)
This code attempts to copy one function (not the pointer! the function!) to another. But of course, this is not possible - you can't copy functions in C++. The compiler doesn't allow this, and I can't believe you got it compiled (you are saying you got linker errors?)
現在,這段代碼:
typedef void(functionPtr)(int);
functionPtr function;
function(5);
function
不會隱藏任何東西.編譯器知道它不是一個可以調用的函數指針,只會調用你原來的function
.
function
does not shadow anything. Compiler knows it is not a function pointer which can be called, and just calls your original function
.
這篇關于函數指針的解釋的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!