2015-12-13 3 views
6
geändert funktionieren

Ich habe einige Funktionen definiert und drucke ich ihre Adresse wie folgt aus:C++ Zeiger nicht

#include<iostream> 
#include <string> 

using std::cout; 

std::string func() 
{ 
    return "hello world\n"; 

} 

int func2(int n) 
{ 
    if (n==0) 
    { 
     cout << func2 << std::endl; 
     return 1; 
    } 

    cout << func2 << std::endl; 

    return n + func2(n - 1); 
} 

//================================================ 
int main() 
{ 
    int (*fun)(int) = func2; 

    cout << fun; 

    cout << std::endl << func2(3); 
} 

Wenn ich die Funktion des Namens drucken (Adresse) sie alle Druck 1 auf meinem Compiler (Mingw gcc 4.8) .

Ist es OK oder sollte es anders sein?

Antwort

0

Sie‘ Die Adresse wird nicht gedruckt, da sie jetzt in einen booleschen Wert konvertiert wird.

Aber Sie können z.B. dies:

std::cout << reinterpret_cast<unsigned long long int *>(func2) << std::endl; 

Jetzt erhalten Sie die tatsächliche Adresse.

+0

Angenommen, die Größe eines Funktionszeigers ist nicht größer als die Größe von 'unsigned long long int'. Sie sollten der Besetzung auch "const" hinzufügen, um Unfälle zu vermeiden. –

+1

Ja, nun ... in C++ 11 lang lang ist mindestens 64 Bit. – juzzlin

+0

Also? Was ist, wenn Zeiger in Zukunft 128 Bits haben? Einmal waren sie nur 16-Bit. –

3

Es existiert keine Überladung von operator<< für std::ostream, die einen Funktionszeiger übernimmt. Daher wird die operator<<(std::ostream&, bool) Überlastung bevorzugt. Die Adresse einer Funktion wird immer auf true ausgewertet, wenn sie in bool konvertiert wird. Somit wird 1 gedruckt.

Alternatevely, wenn ein Funktionszeiger nicht größer als die Größe eines Datenzeiger ist, könnten Sie Ihre Funktion Zeiger auf eine void* über reinterpret_cast gegossen und erinnern an die operator<<(std::ostream&, void*) Überlastung und damit die tatsächliche Adresse der Funktion erhalten gedruckt.

int (*fun)(int) = func2; 
std::cout << reinterpret_cast<void*>(fun) << std::endl; 

Live Demo

jedoch als richtig Neil und M. M in den Kommentaren erwähnt, gibt es von einer Funktion Zeiger auf einen Datenzeiger keine Standardkonvertierung ist, und dies nicht definiertes Verhalten hervorrufen könnte.

Alternativ und in meiner bescheidenen Meinung nach richtig, könnten Sie Ihre Funktionszeiger als char Array Puffer formatiert und seine Adresse in einen String in der folgenden Art und Weise konvertieren:

unsigned char *p = reinterpret_cast<unsigned char*>(&func2); 
std::stringstream ss; 
ss << std::hex << std::setfill('0'); 
for(int i(sizeof(func2) - 1); i >= 0; --i) ss << std::setw(2) 
               << static_cast<unsigned int>(p[i]); 
std::cout << ss.str() << std::endl; 

Live Demo

+1

Angenommen, die Größe eines Funktionszeigers ist nicht größer als die Größe eines Datenzeigers. Sie sollten der Besetzung auch "const" hinzufügen, um Unfälle zu vermeiden. –

+0

@ NeilKirk Das ist richtig. – 101010

+0

hinweis: diese umwandlung zu 'void *' muss nicht existieren –