有时看到如下的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*****************************/
#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);
}
 
[root@localhost 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.

函数名&函数名取地址的更多相关文章

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

    这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ------------------------------------------------- ...

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

    有时看到如下的代码: /*****************************/ #include <stdio.h> #include <string.h> #inclu ...

  3. C语言的数组名和对数组名取地址

    http://blog.csdn.net/zdcsky123/article/details/6517811 相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针, ...

  4. python 函数和函数名的应用

    一.函数 1.函数定义 def 关键字 -- 定义 func 函数名 -- 和变量定义规则一样 ()必须要写格式 : 声明语句结束 def my_len(): ​ 函数体 def func(a:int ...

  5. Python函数03/函数名的第一类对象及使用/f 格式化/迭代器/递归

    Python函数03/函数名的第一类对象及使用/f 格式化/迭代器/递归 目录 Python函数03/函数名的第一类对象及使用/f 格式化/迭代器/递归 内容纲要 1.函数名的第一类对象及使用 2.f ...

  6. 深入理解javascript---命名函数表达式

    简单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你就会发现其实是不切实际的.当然,如果你不关注调试,那就没什么可 ...

  7. Python函数二(函数名,闭包,迭代器)之杵臼之交

    函数名的使用: 函数名可以作为值,赋值给变量. 函数名可以作为参数传参给函数. 函数名可以作为返回值. 函数名可以作为元素存储在容器里. 闭包:在嵌套函数内,使用外层局部变量(非全局变量)就是一个闭包 ...

  8. day11函数的参数,函数对象 - 函数名,函数的嵌套调用

    复习 # 什么是函数:具体特定功能的代码块 - 特定功能代码块作为一个整体,并给该整体命名,就是函数 # 函数的优点: # 1.减少代码的冗余 # 2.结构清晰,可读性强 # 3.具有复用性,开发效率 ...

  9. 快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)

    apply方法是Scala中十分常见的方法,你可以把这种用法当做是()操作符的重载形式. 像以上这样伴生对象的apply方法是Scala中构建对象的常用手法,不再需要使用new. if 条件表达式的值 ...

随机推荐

  1. 2017年3月14日-----------乱码新手自学.net 之Authorize特性与Forms身份验证(登陆验证、授权小实例)

    有段时间没写博客了,最近工作比较忙,能敲代码的时间也不多. 我一直有一个想法,想给单位免费做点小软件,一切思路都想好了,但是卡在一个非常基础的问题上:登陆与授权. 为此,我看了很多关于微软提供的Ide ...

  2. linux 安装jdk (二进制文件安装)

    1.下载jdk 此处以1.7 为例 :jdk-7u79-linux-x64.tar.gz 2.通过ssh将安装介质传到服务器 我一般放在 /opt 目录下 3.用tar 命令解压缩   tar -zx ...

  3. IO流----转换流、缓冲流

    打开一个文本文件,另存为: Ansi就是系统默认编码(就是gbk) 建一个编码是utf-8的txt文件, 例: import java.io.FileWriter; import java.io.IO ...

  4. 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here

    你的飞碟在这儿 难度:☆ Code: #include<iostream> #include<cstring> #include<cstdio> using nam ...

  5. 告别CMD.windows终端神器conemu设置

    前言 一种刘姥姥进大观园的感觉,现在是见啥啥新鲜.因为之前不怎么接触到命令操作,平时偶尔用用cmd也没觉得什么不妥.直到现在经常调试脚本,使用git越发感觉不方便.看见同事使用的terminal绚丽夺 ...

  6. sqlserver创建触发器

    Create TRIGGER [dbo].[tr_Delete_AllocationedDN] --删除指定账户已分配未拣货的任务 ON [dbo].[FRU_PickLocationNew] --触 ...

  7. UVALive 3983 Robotruck (单调队列,dp)

    如果状态定义为序号和重量的话,决策就是下一个垃圾捡或者不减,但是状态数太多了. 如果只定义序号作为状态的话,决策就变成从前面的某个j一直捡到i才送回垃圾. 这就变成了一个区间选最小值的问题,用单调队列 ...

  8. 关于 NetBackup 应答文件(/tmp/NBInstallAnswer.conf)

    关于 NetBackup 应答文件 在 UNIX 和 Linux 安装和升级期间使用 NetBackup 应答文件 (/tmp/NBInstallAnswer.conf),以便: 覆盖某些默认值. 避 ...

  9. 在linux命令行下如何访问网址

    1. wget Ubuntu系统自带,会将访问的首页下载到本地 admin@iZj6c9c6vaqj1i0a9j7h78Z:~$ wget www.baidu.com --2019-04-20 17: ...

  10. JavaScript内存泄露,闭包内存泄露如何解决

    本文原链接:https://cloud.tencent.com/developer/article/1340979 JavaScript 内存泄露的4种方式及如何避免 简介 什么是内存泄露? Java ...