空指针和NULL

#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|| 没有搞懂
    }

}

猜你喜欢

转载自www.cnblogs.com/luoxuw/p/11313411.html