我试图用下面的代码弄清楚这个问题的答案,但事实证明,指针的值(问题3的地址竟然远离参数和函数的局部变量) )地狱是x = problem3;
指向......
void problem3(int a) {
int overflowme[16];
int x = problem3;
overflowme[15] = 102;
printf(" the address of x is %x\n the addres of the first local is %x\n the addres of the first para is %x\n ", x, &overflowme[15], &a);
}
int main(void) {
problem3(101);
}
OUTPUT
the address of x is 42b613
the addres of the first local is 12fed8
the addres of the first para is 12fee4
Press any key to continue . . .
答案 0 :(得分:4)
problem3是指向函数的指针。在C中,如果使用类似(int)
的强制转换,编译器基本上会关闭所有类型检查并假设您知道自己在做什么(即使在这种情况下,它没有意义) - 在这种情况下转换指向整数的指针。
底线 - 除非你真的需要,否则不要使用演员阵容。
答案 1 :(得分:2)
你能解释为什么我们被允许在上面的代码中分配x =(int)problem3
因为problem3是函数指针(即函数的内存地址),所有指针都可以转换为整数。
我们不是将“hello world”分配给x?
没有。但是你可以这样做,如果你想(通过做x = (int) "hello world";
),因为“hello world”也是一个指针(一个精确的char指针),所以上面适用。
答案 2 :(得分:1)
施放(当你将(int)
放在某物之前时所做的事情)就是那么神奇。它将采取任何形式的东西并将其变成任何其他东西(在这种情况下为int
),无论它是否有任何意义。除非你绝对肯定你必须这样做,否则你应该避免使用施法。
程序的代码就像变量一样存在于内存中。这里发生的事情是,强制转换正在将表示代码所在内存的数字转换为整数。该整数可以更大或更小,具体取决于内存中编译器和链接器决定放置函数代码的位置。
您的printf语句根本没有任何分配。 %x
只是一个占位符,说“将其中一个参数传递给printf并将其打印出来”。它是'x'的事实与程序中变量的名称无关。 'x'所说的是“以16为基数打印此整数(heXadecimal)而不是正常基数10”。如果您将%u
或%d
放入其中仍然有效,您将获得以10为基数的无符号整数或基数为10的有符号整数表示的数字。
答案 3 :(得分:0)
首先,您在problem3;
中缺少一个括号,以便实际执行函数调用。其次,赋值x = (int)problem3
将函数problem3
的地址赋给x,强制转换为int。这在C中是完全合法的事情,虽然我不确定你想要完成什么。
如果将某个函数的地址打印到int,并将其格式化为十六进制数,则可能会将该函数的地址打印为十六进制数。我不确定为什么你会惊讶这个号码有7位数。
答案 4 :(得分:0)
在第一个示例中,您要将problem3
功能的地址分配给x
,然后打印该地址的值。
将它投射到int
通常是完全没用的。您很少需要知道函数的实际内存地址。
您希望获取函数地址的唯一时间是将其传递给代码的其他部分,这将调用函数(执行它)。有关使用函数指针的更多信息,请查看this article。
答案 5 :(得分:0)
您正在打印功能的地址(“problem3”和“main”)。这些地址完全依赖于编译器和实现,因此您所面对的是6到7位数之间的区别。