空指针和NULL

#include <stdio.h>
int add(int a, int b ){  //函数的返回值和参数意一样有副本机制,存储在寄存器中,而不在内存中,函数的返回值不能取地址  &add()
    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; //指向为空的指针,指向0000000,不能打印读取
    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("%f,%f,%f||",pFloat[i],pFloat[i],*pFloat);  //记得要按照%f解析数据,而不是%d
        //0.000000,0.000000,0.000000||1.000000,1.000000,0.000000||2.000000,2.000000,0.000000||3.000000,3.000000,0.000000||4.000000
        //,4.000000,0.000000||
    }

}

 

转载于:https://www.cnblogs.com/luoxuw/p/11313411.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值