gpt4 book ai didi

c - 为什么使用 & 符号来检索整数的内存地址,而不是函数的地址?

转载 作者:太空宇宙 更新时间:2023-11-04 00:20:52 25 4
gpt4 key购买 nike

我目前正在关注 Big Nerd Ranch 的 Objective-C 指南,其中一个示例如下:

int main(int argc, const char * argv[])
{
int i = 17;
printf("i stores its value at %p\n", &i); return 0;
}

// output => i stores its value at 0xbffff738

int main(int argc, const char * argv[])
{
int i = 17;
printf("i stores its value at %p\n", &i);
printf("this function starts at %p\n", main); return 0;
}

// output => i stores its value at 0xbffff738
// this function starts at 0x100000ed0

我尝试在 main 前面使用“&”符号,我得到了相同的结果——0x100000ed0。但是,当我从“i”前面删除“&”符号时,我只看到 0x11 而不是 0xbffff738。

问题 - 为什么不同?为什么一个人可以使用或不使用&符号,而另一个似乎需要它才能产生预期的输出?

最佳答案

在大多数情况下,函数类型的表达式(包括函数名称)隐式转换为指向函数的指针。异常(exception)情况是它是一元 sizeof& 运算符的参数。 sizeof function_name 是非法的,但在 &function_name 中,子表达式 function_name 转换为指针; & 运算符然后生成函数的地址。

鉴于 foo 是一个函数的名称,这些表达式:

foo
&foo
*foo
**foo
***foo
...

全部产生函数的地址。

数组表达式也有类似的规则,通常是转换为数组首元素的地址。还有一个额外的异常(exception)(数组对象的初始化程序中使用的字符串文字),并且 &array_name 是有效的(它产生数组对象的地址,它引用相同的地址但具有不同的类型比第一个元素的地址)。

顺便说一下,%p 格式需要一个类型为 void* 的参数。在许多系统上,所有指针都具有相同的表示形式,因此您可能可以不传递任何指针值而逃脱——但不能保证它会起作用。为了获得最大的安全性和可移植性,您应该通过将指针值强制转换为 void* 来打印指针值:

printf("i stores its value at %p\n", (void*)&i);

并且没有用于打印函数指针值的标准格式。这:

printf("this function starts at %p\n", (void*)main);

可能会起作用,但严格来说是 int (*)(int, char **) 的转换行为(main 的地址类型) 到 void* 是未定义的。参见 this question获取更多信息。

为了 100% 的可移植性,您可以通过将函数指针视为 unsigned char 数组来提取函数指针的表示形式,但这可能不是必需的。

关于c - 为什么使用 & 符号来检索整数的内存地址,而不是函数的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27628215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com