为什么解除引用主函数不显示内存内容?

我试图获取函数名[abc()和main()]指向的地址的内存内容,但函数内的printf()都给出了相同的输出,尽管我取消引用了函数名所指的地址。每个函数内部的第二个printf()。 这是为什么? 为什么内存地址由*(abc)和*(main)而不是内容打印?

#include void abc(){ printf("\n%p \n ", abc); printf("\n%#x\n ",*(abc)); } void main(){ abc(); printf("\n%p \n ", main); printf("\n%#x\n ",*(main)); } 

您还没有打印数据(实际上是代码),而是指向代码的指针值。

 #include void abc(){ int i; printf("\n%p \n ", abc); printf("\n%#x\n ",*(abc)); for( i = 0; i < 100; i++ ){ printf( "%X ", ((unsigned char *)abc)[i] ); } } void main(){ int i; printf("\n%p \n ", abc); abc(); printf("\n%p \n ", main); printf("\n%#x\n ",*(main)); for( i = 0; i < 100; i++ ){ printf( "%X ", ((unsigned char *)main)[i] ); } } 

这表明代码在两个函数指针指向的位置是不同的。 除非你精通逆向assembly,否则它是相当无用的,但是你应该能够validation它转储的代码是否与调试器的输出一致,该调试器反汇编了相应的代码片段。

你不能取消引用一个函数本身,因为在解除引用它的上下文中它将成为一个函数指针。 并且,当你取消引用它时,你会得到同样的旧function……

你可以尝试一下:

 printf("one"); (*printf)("two"); (**printf)("three"); 

要实际查看函数内容,您需要像memcpy()这样的东西。 但是,这样做可能没那么有用,因为无法获得函数的大小(至少通过任何标准方法)。 如果要查看函数的内容是什么样的,请在调试器中调试程序并反汇编该函数。

那是因为函数和函数指针的语法非常奇怪。

  • abc给出了一个指向函数的指针。
  • &abc还给出了一个指向函数的指针。
  • *abc给出了一个函数指示符。

函数指示符会衰减为函数指针,因此当您在表达式中使用函数指示符时,您将获得函数的地址。

所以abc&abc*abc都会给你相同的地址。

永远不要认为C是一种理性,理智,一致的语言!

在C中,函数指针的行为与常规指针不同 – 无论是使用取消引用还是使用address-of运算符,它仍然是对函数的引用。 为了实现您的目标,您需要将其转换为不同的指针类型; 例如:

 void main() { printf("\n%p \n ", main); printf("\n%#x\n ", *((char*)main) ); } 

指向函数的指针不会被视为指向对象的指针,并且您不能将函数指针视为任意字节数组,就像使用对象指针一样。

如果您愿意违反一些规则,可以尝试为对象指针指定一个函数指针,如

 unsigned char *data = (unsigned char *) abc; 

然后检查data[i]的内容。

请注意,您的编译器应该抱怨这一点。 根据平台的不同,这可能根本不起作用。 C标准没有定义从函数指针类型到对象指针类型的转换,反之亦然。 允许个人实施,但不是必需的。