array 变量在编译时会替换成存储ARRAY数据的内存首地址。
所以 array:%p == &array:%p .
例如 :
function 名则更猛.
[root@db-172-16-3-150 zzz]# cat f.c
#include <stdio.h>
char a[10] = "abcde";
int main() {
fprintf(stdout, "a:%p, &a:%p\n", a, &a);
return 0;
}
结果
[root@db-172-16-3-150 zzz]# gcc -O3 -Wall -Wextra -Werror -g ./f.c -o f && ./f
a:0x6008bc, &a:0x6008bc
function 名则更猛.
function:%p == &function:%p == *function:%p
说明函数名是个指针, 指针的内容就是这个指针的地址本身.
因此使用函数名, 或者*function 或者&function都可以调用这个函数.
例如 :
[root@db-172-16-3-150 zzz]# cat f.c
#include <stdio.h>
int test() {
fprintf(stdout, "test output\n");
return 1;
}
int main() {
int test1() {
return 2;
}
int a = test1();
int b = (&test)(); // 使用&test调用这个函数
int c = (*test)(); // 使用*test调用这个函数
fprintf(stdout, "a:%i, b:%i, c:%i\n", a, b, c);
fprintf(stdout, "test:%p, &test:%p, *test:%p\n", test, &test, *test);
fprintf(stdout, "test1:%p, &test1:%p, *test1:%p\n", test1, &test1, *test1);
fprintf(stdout, "test1+1:%p, (&test1)+1:%p, (*test1)+1:%p\n", test1+1, (&test1)+1, (*test1)+1);
return a;
}
结果
[root@db-172-16-3-150 zzz]# gcc -O3 -Wall -Wextra -Werror -g ./f.c -o f && ./f
test output
test output
a:2, b:1, c:1
test:0x400540, &test:0x400540, *test:0x400540
test1:0x400530, &test1:0x400530, *test1:0x400530
test1+1:0x400531, (&test1)+1:0x400531, (*test1)+1:0x400531 // 这里+1都加了一个字节, 而存储0x400531这个值需要2个字节, 所以看起来就不对劲了.
// 这些可能都是编译器使的障眼法. 函数指针可能另有所指, 那就是code区域.
函数创建时, 这个函数指针将在内存的constants区域创建.
从打印结构来看,
function:%p == &function:%p == *function:%p .但是这可能是编译器搞的鬼. 函数指针肯定是要执行函数体的code区域的,
来看一幅图 :