#include <stdio.h> int add(int a, int b ){ return a+b; } void main1(){ //定义函数指针的三部曲 int add(int a, int b ); //第一步:函数声明 int (*p)(int a, int b ); //第二步:把函数名字改成(*p) ()优先级大于* //简化 int (*p)(int, int); 定义了一个函数指针变量p,用于指向函数的首地址 返回值为int类型,int (*)(int int) 再加一个p就是指针名字 //对比int *p(int a, int b ); 就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。 p =add; //第三步:函数名代表函数的首地址 初始化指针 int res = p(1,3); //第四步:用指针间接调用函数 printf("%d\n",res); //函数是代码,代码会变化,p++ 无意义 void *pAdd = add; //定义指针变量pAdd时没有指定函数的返回类型和参数列表,不可以用pAdd(1,3)来调用; //定义函数指针时,函数的参数列表和返回类型缺一不可 } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void main2(){ //int *p = 0x56777; 直接把地址赋值给指针变量,p指针存储了0x56777的地址,并不知道其按照何种类型来解析,所以不合法 int *pInt = (int *)0x56777; //把0x56777地址强制转换成int * 类型, pInt就知道从0x56777地址开始按照int类型解析数据了 int num =10; double d =10.4; int *p1 = # double *p2 = &d; void *pVoid = p1; pVoid = p2; // void 指针主要用于传地址 // printf("%d\n",*pVoid); //void指针只是存储了p2的地址,并没有存储p2的类型,所以无法用*取出他的值 printf("%f\n",*((double *)pVoid)); //void指针只是存储了p2的地址,强制转换成double*类型,(double *)pVoid,就知道按double类型来解析 //空指针用于参数或者返回值,在不明确指针类型的情况下,传递地址 //要把空指针用于某种数据类型,则需要进行强制类型转换 //空指针还是一个指针,可以指向任何一个数据类型的地址,不需要强制类型转换,只有在使用时才要 // NULL是不指向任何地址,主要用于条件判断 int *pInt1 = NULL; //指向为空的指针 if(pInt1 == NULL){ printf("pInt1没有指向任何地址"); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <memory.h> //使用memset函数 void main3(){ char str[30] = "China is great"; int num[5] ={1,2,3,4,5}; memset(str,'A',5); //void * __cdecl memset(void *_Dst,int _Val,size_t _Size); str的地址传给Dst空指针,从这里开始往后5个字节byte,都赋值于字符‘A’ printf("%s\n",str); //AAAAA is great memset(num,0,20); // num首的地址传给Dst空指针,从这里开始往后20个字节,都赋值于字符0,整个数组就清零了 for (int i = 0; i < 5; ++i) { printf("%d,",num[i]); //0,0,0,0,0, } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <stdlib.h> void main(){ //定义一个指针类型包含了三个信息 //1、首地址,2、步长(int float double),3、内容如何解析(%d,%f) //malloc(1024*1024*100) 分配100M 括号里面是字节数 void *pVoid; pVoid = malloc(20); //分配20个字节的内存, pVoid保存这段内存空间的首地址 //首地址一样,步长一样,下面按照两种方式解析20个字节的内存数据 //按照%d解析 int *pInt = (int *)pVoid; for (int i = 0; i < 5; ++i) { pInt[i] =i; printf("%d,%f||",pInt[i],pInt[i]); //0,0.000000||1,0.000000||2,0.000000||3,0.000000||4,0.000000|| } printf("\n\n"); //按照%f解析, void *pVoidF = malloc(20); float *pFloat = (float *)pVoidF; printf("%d\n\n", sizeof(float *)); for (int i = 0; i < 5; ++i) { pFloat[i]=i; printf("%d,%f,%d||",pFloat[i],pFloat[i],*pFloat); //0,0.000000,0||0,0.000000,1072693248||0,0.000000,1073741824||0,0.000000,1074266112||0,0.000000,1074790400|| 没有搞懂 } }
空指针和NULL
猜你喜欢
转载自www.cnblogs.com/luoxuw/p/11313411.html
周排行