关于函数名字是存放在那里???
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于函数名字是存放在那里???相关的知识,希望对你有一定的参考价值。
如果有个函数:void fun();要是输出函数名即printf("%d",fun);和输出printf("%d",&fun);分别是多少,为什么呢???
存放在符号表。函数名本身只是用来在定义域中指称某个函数(若考虑到C++中的函数重载,可能不止一个),一般编译器会保存名称至符号表,并在目标文件中保留函数名称(重载函数可能会被重命名)以供链接器等其它编译程序使用。在运行期函数名称一般不会在内存中出现,操作系统或者程序本身根据函数代码的地址确定某个具体的函数。对于语言的使用者而言,除了用于声明、定义、调用等构成函数表达式外,函数名称和一般的标识符一样不是可以直接被利用的资源,无法作为字符串使用。
对于非调用函数的场合,函数名可以隐式转换为对应的函数指针,且对于一元&作用的函数的结果也是对应的函数指针(C和C++的规定有所不同,但这里体现相同的结果)。因此printf("%d",fun);和printf("%d",&fun);的作用都是输出指向fun的指针的值,也就是fun的地址。(不过输出指针应使用%p,%d不是规范的用法。)
1L错误,fun不带参数列表地引用函数名称不是函数调用;另外%d输出十进制,%x才是十六进制的(%p一般也是十六进制)。 参考技术A printf("%d",fun);这个应该是空(即NULL),因为fun()的返回值是void,也就是其没有返回值!!而printf("%d",&fun);是显示fun()函数的首地址,是以16进制显示的 参考技术B 两个都是该函数在内存中的地址
fun是函数的地址,如果你使用过指向函数的指针你就明白,
&是取地址运算符,所以&fun也是取该函数的地址 参考技术C 函数名本身只是用来在定义域中指称某个函数(若考虑到C++中的函数重载,可能不止一个),一般编译器会保存名称至符号表,并在目标文件中保留函数名称(重载函数可能会被重命名)以供链接器等其它编译程序使用。在运行期函数名称一般不会在内存中出现,操作系统或者程序本身根据函数代码的地址确定某个具体的函数。对于语言的使用者而言,除了用于声明、定义、调用等构成函数表达式外,函数名称和一般的标识符一样不是可以直接被利用的资源,无法作为字符串使用。
对于非调用函数的场合,函数名可以隐式转换为对应的函数指针,且对于一元&作用的函数的结果也是对应的函数指针(C和C++的规定有所不同,但这里体现相同的结果)。因此printf("%d",fun);和printf("%d",&fun);的作用都是输出指向fun的指针的值,也就是fun的地址。(不过输出指针应使用%p,%d不是规范的用法。)
1L错误,fun不带参数列表地引用函数名称不是函数调用;另外%d输出十进制,%x才是十六进制的(%p一般也是十六进制)。
====
[原创回答团]
参考资料:原创
本回答被提问者采纳名称空间作用域闭包装饰器迭代器生成器
--名称空间与作用域
名称空间:是存放名字的地方准确的说名称空间是存放名字与变量值绑定关系的地方
内置名称空间:在python解释器启动时产生,存放一些python内置的名字
全局名称空间: 在执行文件时产生,存放文件级别定义的名字
局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
加载顺序:内置--》全局--》局部
名字的查找顺序 局部--》全局--》内置
max=1
def foo():
max=2
print(max)
foo()//先找局部的max=2 ,max=2注释掉 找max=1,max=1注释掉,max=内置的函数
作用域:变量或函数作用的范围
全局作用域:全局存活,全局有效:查看全局作用域的函数 globals()
x=1
def f1():
def f2():
def f3():
def f4():
print(x)
f4()
f3()
f2()
f1()//1
局部作用域:临时存活,局部有效:locals()
#优先掌握:作用域关系,在函数定义时就已经固定
# ,于调用位置无关,在调用函数时,必须必须必须
#回到函数原来定义的位置去找作用域关系
x=1
def f1():
x=2
def f2():
print(x)
return f2
func = f1()
def f3():
x=33333
func()#调用时必须回到函数原来定义的位置找作用域 f1中的f2按照名称空间原则 x=2
f3()
--闭包
闭包:函数内的函数中对外部作用域名字的引用,而不是对全局作用域名字的引用
x=1
def f1():
x=11111111111
def f2():
print(x)
return f2
func=f1()
--装饰器
1、开放封闭原则:对扩展是开放的,对修改是封闭的
2、装饰器:装饰它人的工具,装饰器本身可以是任意可调用的对象,被装饰的对象本身也可以是任意可调用的对象
2.1 装饰器的遵守原则:1 不修改被装饰对象的源代码 2 不修改被调用的调用方式
2.2 装饰器的目的是:在遵循1和2的原则下,为其他新功能函数添加
#@装饰器名,必须在被装饰对象的正上方,并且是单独一行
--无参
import time
def timmer(func):#= func=index
def wrapper():
start=time.time()
func()
stop = time.time()
print(%s(stop-start))
return wrapper
#timmer(func) = ‘func=index‘ 和wrapper()
@timmer #index = timmer(index)
def index():
time.sleep(3)
print(‘index‘)
@timmer #home = timmer(home)
def home():
time.sleep(3)
print(‘home‘)
index()-->@timmer-->1)index=timmer(index)-->func=1)index | 1)index = wrapper
# index()=warpper()
home()
--改进
#装饰器改进,多了调用时传入的参数和return
import time
def timmer(func):#= func=index
def wrapper(*args,**kwargs):
start=time.time()
res = func(*args,**kwargs)
stop = time.time()
print(‘%s‘%(stop-start))
return res
return wrapper
#timmer(func) = ‘func=index‘ 和wrapper()
@timmer #index = timmer(index)
def index():
time.sleep(3)
print(‘index‘)
@timmer #home = timmer(home)
def home(name):
time.sleep(3)
print(‘home‘)
return 123
#index()-->@timmer-->1)index=timmer(index)-->func=1)index | 1)index = wrapper
# index()=warpper()
res1 = home(‘egon‘)
print(res1)
--带参
current_user = {‘user‘:None}
#多加了一层闭包
def auto(a_type=‘file‘):
def demo(func):
def wapper(*args,**kwargs):
if a_type == ‘file‘:
#第一次登陆验证,第二次不用验证
if current_user[‘user‘]:
return func(*args,**kwargs)
inp = input(‘username:‘).strip()
inp2 = input(‘password:‘).strip()
with open(‘user‘, ‘r‘) as f_read:
user_dic = eval(f_read.read())
if inp in user_dic and inp2 == user_dic[inp]:
current_user[‘user‘] = True
res = func(*args,**kwargs)
return res
else:
print(‘error‘)
else:
print(‘not valid auth_type‘)
return wapper
return demo
@auto(a_type=‘file‘)
def login():
print(‘welcome‘)
@auto(a_type=‘mysql‘)
def home(name):
print(name)
login()
home(‘egon‘)
--迭代器
#迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
#while True: #是单纯的重复不属于迭代
#平时我们取含有索引的对象时可以写成这样
l = [‘a‘,‘b‘,‘c‘,‘d‘]
count =0
while count <len(l):
print(l[count])
count+=1
#迭代器
#可迭代的对象iterable:对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象(字符串、列表、元组、字典、集合、文件都是可迭代对象)
s = ‘hello‘
l = [‘a‘,‘b‘,‘c‘,‘d‘]
t =(‘a‘,‘b‘,‘c‘,‘d‘)
dic = {‘name‘:‘egon‘,‘sex‘:‘m‘,‘age‘:18}
#
#迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
dic = {‘name‘:‘egon‘,‘sex‘:‘m‘,‘age‘:18}
i= dic.__iter__()
print(i)
#不依赖索引的取值方式
l = [‘a‘,‘b‘,‘c‘,‘d‘]
dic = {‘name‘:‘egon‘,‘sex‘:‘m‘,‘age‘:18}
iter_dic = iter(dic)
while True:
try:
k=next(iter_dic)
print(k,dic[k])
except StopIteration:
break
以上是关于关于函数名字是存放在那里???的主要内容,如果未能解决你的问题,请参考以下文章