C语言函数名以及取地址的区别和联系

有时看到如下的代码:

/*****************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void test()
{
    printf("123456\n");
}

int main(int argc, char *argv[])
{
    printf("0x%x\n",test);
    printf("0x%x\n",&test);
}

[[email protected] pht]# ./a.out
0x8048328
0x8048328

按照&运算符本来的意义,它要求其操作数是一个对象,但函数名不是对象(函数是一个对象),本来&test是非法的,但很久以前有些编译器已经允许这样做, 
c/c++标准的制定者出于对象的概念已经有所发展的缘故,也承认了&test的合法性。

因此,对于test和&test你应该这样理解,test是函数的首地址,它的类型是void (),&test表示一个指向函数test这个对象的地址, 
它的类型是void (*)(),因此test和&test所代表的地址值是一样的,但类型不一样。test是一个函数,&test表达式的值是一个指针!

跟此问题类似的还有对一个数组名取地址。 
int a[100]; 
printf("%p\n", a); 
printf("%p\n", &a[0]);

打印值一样。 
但是数组名a,指向的是具有100个int类型的组数; 
&a[0]指向的是元素a[0]。 
即他们的值相同,但指向的类型不同。

标准在其rationale中解释了这个问题,摘录如下: 
6.5.3.2 Address and indirection operators 
Some implementations have not allowed the & operator to be applied to an array or a function. 
(The construct was permitted in early versions of C, then later made optional.) The C89 Language 
Committee endorsed the construct since it is unambiguous, and since data abstraction is 
enhanced by allowing the important & operator to apply uniformly to any addressable entity.

原文地址:https://www.cnblogs.com/still-smile/p/11592292.html

时间: 2024-10-06 16:10:20

C语言函数名以及取地址的区别和联系的相关文章

数组名和数组名取地址的区别

数组名和数组名取地址的区别 以下代码会打印出什么样的日志呢? [cpp] view plaincopy #include <stdio.h> int a[2] = {1,2}; int main(){ printf("a = %p\n", a); // I printf("&a = %p\n", &a); // II printf("a + 1 = %p\n", a + 1);// III printf("&

终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good

这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ---------------------------------------------------------------------------------------------------------------- 在学习Delphi的时候,一个很好的建议是和C/C++去类比着学习,从指针,到内存管理,到数组,到面向对象……各个方面,都是有很多可以相似和或者也有不同的方,类比着学习,一

C语言——数组名、取数组首地址的区别(一)

目录: 1. 开篇 2. 论数组名array.&array的区别 3. array.&array的区别表现在什么地方 4. 讨论 5. 参考 1.开篇 很多博客和贴吧都有讨论这个话题,各有自己的表述方式,今天在他们的基础上我将继续试着以我自己理解的方式总结一下,欢迎大家的审阅和指评. 2.论数组名array.&array的区别——省政府和市政府的区别 例如: int array[5] = {0}; 总所周知,其中的&array是整个数组array的首地址,array是数组首

[转载]C++中 引用&amp;与取地址&amp;的区别

一个是用来传值的 一个是用来获取首地址的 &(引用)==>出现在变量声明语句中位于变量左边时,表示声明的是引用.     例如: int &rf; // 声明一个int型的引用rf.&(取地址运算符)==>在给变量赋初值时出现在等号右边或在执行语句中作为一元运算符出现时                  表示取对象的地址. 在C++中,既有引用又有取地址,好多人对引用和取地址不是很清楚,因此也无法区分.其实他们的区别可以用一句话概括:和类型在一起的是引用,和变量在一起的

C语言 函数指针定义三种方式

//函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 //函数名就是函数的地址,函数的指针,对函数名进行&取地址操作,还是函数名本身,这是C语言编译器的特殊处理 void test(int a){ printf("a=%d\n",a); } void ProtectA(){ //定义函数类型 typedef void(FunType)(

c语言函数指针的理解与使用

转载:http://www.cnblogs.com/haore147/p/3647262.html 1.函数指针的定义 顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: A) char * (*fun1)(char * p1,char * p2); B) char * *fun2(char * p1,char * p2); C) char * fun3(char * p1,char * p2); 看看上面三个表达式分别是什么意思? C)这很容易,fun3是函数名,p1,p2

数组名和数组名取地址、指针数组和数组指针的区别

一,首先我们先分析下数组名和数组名取地址的区别. 我们都知道数组名是数组的首地址,然而对数组名取地址又是什么那?看下面一段程序你就会懂的. #include "stdafx.h"     #include<stdio.h>    using namespace std;    void main()    {          int a[5];          printf("%d\n", a);          printf("%d\n

函数名的运用(第一类对象)以及闭包与迭代器

一.函数名的应用(第一类对象) 1.函数的命名规范和变量是一样的,函数名其实就是变量名. 2.函数名的内存地址 def func(): print("呵呵" print(func) 结果: <function func at 0x1101e4ea0> 3.函数名可以赋值给其他变量 def func(): print("呵呵") print(func) a = func # 把函数当成一个变量赋值给另一个变量 a() # 函数调用 func() 结果: &

函数名 闭包 迭代器

函数名 函数名就是变量;  函数名可以作为参数进行传递 1. 函数名的内存地址 def func(): print("哈哈") print(func) #<function func at 0x01CDD4B0> 2. 函数名可以赋值给其他变量 def func(): print("呵呵") print(func) a = func #把函数当成变量 赋值给另一个变量 a() # 函数调用 func() 3. 函数名可以作为列表中的元素进行存储 def