今天突然有兴趣研究一下C的指针,下面是我的一些学习手稿,拿出来分享下.
首先:
#include <stdio.h>
int main(){
int arr[100];
printf("arr=[%x]\n&arr=[%x]\n",addr,&addr);
return 0;
}
执行结果:
arr=[e45c69f0]
&addr=[e45c69f0]
得到的是相同的结果.
再看个例子...
#include <stdio.h>
int **pi;
int main(){
int **pi1;
printf("%x\n",pi);
printf("%x\n",pi1);
return 0;
}
最终得到的结果是
0
0
这里表示 虽然这里的指向指针的变量没有初始化,但是都会默认的赋予一个 初值0
不管是全局变量或者是局部变量,都会初始化,而有些书上说 全局变量或者静态变量会初始化,而自动变量只是随机的值.
我想可能是编译器的原因导致的吧.
int *func();
由于()的优先级高于 间接访问操作符.所以func是一个函数,它的返回值类型是一个指向整形的指针.
比较 int (*func)();
第一个括号是聚组的作用,它迫使间接访问在函数调用之前进行.使func 成为一个指针,它所指向的函数返回一个整型值.
在比较 int *(*func)();
和上面的类似,只是返回的类型变成了一个指向整形变量的指针.
所有 func是一个指向返回值是指向整形指针的函数.(比较拗口)
比较
#include <stdio.h>
void func();
int main(){
printf("%x\n",func);
printf("%x\n",&func);
}
void func(){}
结果:
4004fd
4004fd
相同的内容.
解释:&操作符是可选的,因为函数名被使用时总是由编译器把它转化为函数指针.
这里我想到了一点,为什么有些类库中的函数使用回调函数时,
例如 :
void (*signal(int signum,void (* handler)(int)))(int);
不要觉得看的头晕,仔细分析一下.
函数使用回调函数, void(* handler)(int);
主函数是 (*signal)(int signum , 函数指针);
返回值类型是一个函数指针,函数指针就是指向handler, 后面再接(int),所以就是调用 回调函数 handler,
最终的返回值是 void,而handler的类型也是 void,正好符合.
但是真正调用的时候,我们的做法是定义handler.
void handler(){}
直接传入
signal(SIGHUP,handler);
明白原因了吗? handler就是指向该函数的指针.
int *arr[];
分析 []操作符优先级高于 * 所以arr是个数组.所以该数组存储的是指向整形的指针.
#include <stdio.h>
int main(){
int *arr[10];
printf("%x\n",*arr[0]);
printf("%x\n",arr);
printf("%x\n",&arr);
}
返回的是相同的内容.
这就说明了 数组名指向是指向数组第一个元素的地址
和前面的函数指针类似,操作符&是可选的.