C/C++基础(二)

1.指针和地址的区别

指针:指针有类型。
地址:没有类型,需要强制类型转换才能赋值给指针变量。

int *p = (int *)0x33fc32;

2.空指针

注意 :指针使用之前必须要有初始化值(初始化)。

void main(){
    int *p = NULL;
    //NULL地址
    printf("地址:%#x",p);
    //取值:0x00000000 因为这个是操作系统所使用,
    //一般应用程序不能够访问
    printf("值:%d",*p);

   //判断NULL
   if(p == NULL){
       printf("为NULL。。。。。");
   }

   //把10当做一个内存地址赋值给了指针变量(16进制)
   p = 200;
   //打印指针变量对应的值
   printf("%d\n",*p);

   //总结:由于数字比较小,系统本身已经占用了这块内区
   //域,系统本身内存数据不允许访问所以一般情况下,我
   //们不会直接给指针变量赋值为整数。

   getchar();
}

3.多级指针

指针变量也是变量,也占用内存空间,同样有地址,因此可以用一个指针指向它,这就称之为二级指针。正常情况下最多就是三级指针。
多级指针的作用:删除链表、动态分配内存给二维数组等等。。。

void main(){
    int a = 100;
    int b = 200;
    //a变量的地址
    int *p1 = &a;
    //打印指针的地址
    printf("p1的地址:%#x\n",p1);

   //二级指针
   int **p2 = &p1;

   //p2保存的数据是p1的地址,*p2上的数据是p1地址值,
   //p1保存的数据是a的地址,**p2实际上就是a的值。
   **p2 = 999printf("二级指针地址:%#x\n",&p2);
   printf("a的值:%d",a);

   getchar();
}

4.指针的运算(赋值运算、算数运算)

void main(){
    //赋值运算
    int a = 44;
    int *p = &a;

   //算术运算(+ - * /)
   //数组:(1)ids常量指针,存储的是数组的首地址
   //(2)数组在内存中排列是连续不断的(线性排列)
   int ids[] = {23,53,24,63,62,73}
   //打印数组
   printf("数组:%#x\n",ids);
   //数组第一个元素地址
   printf("数组第一个元素的地址:%#x\n",&dis[0]);

   //p++每次向前移sizeof(数据类型)个字节
   int *P = ids;
   p++;
   printf("p的地址:%#x   p的值:%d\n", p,*p);

  //遍历数组
  //传统方法
  int i = 0;
  for(;i<6;i++){
      printf("值:%d\n",ids[i]);
  }

 //通过指针遍历 注意:让指针递增或者递减,一般情况下只
 //有在数据遍历的时候才有意义,基于数组在内存中是线性排
 //列的,有可能会导致访问到其他的内存区域(如:系统程序,
 //第三方程序)
  for(;p<ids+6;i++){
      printf("地址:%#x  值:%d\n",p,*p);
  }

  getchar();
}

5.指针运算(通过使用指针循环给数组赋值)

 void main(){
    int ids[6] ;
    int *p = ids;

    //传统赋值
    int i = 0;
    int j = 0;
    /**
     *  for(;i<6;i++){
     *      ids[i] = i;
     *   }
     */
    //指针方式赋值
    for(;p<ids+6;p++){
        *p = i;
        i++;
    }

    //输出
     for(;j<6;j++){
         printf("值:%d\n",ids[j]);
     }

     getchar();
}

6.数组内部指针的加减

void main(){
    int ids[6] = {24,34,25,16,34,84};
    int *p = ids;
    p = p+4;
    printf("值:%d  地址:%#x\n",*p,p);
    p = p - 1;
    printf("值:%d  地址:%#x\n",*p,p);
    getchar();
}

7.指针大小比较

1.指针大小比较:都是在遍历数组的时候运用,其他情况下没什么用。
2.指针相等比较:指针地址相等,并不代表值相等,因为指针有类型。

void main(){
    int *p1 = (int *) 0x006732;
    double p2 = (double*)0x006732;
}

8.指针和数组的几种写法

void main(){

    int ids[6] = {24,34,25,16,34,84};
    int i = 0;
    for(;i<6;i++){
        printf("%d %#x\n",ids[i],&ids[i]);
        //分析取地址:ids是首地址
        //ids+0等价于&ids[0]   
        //ids+1等价于&ids[1]
        //以此类推.....
        //总结:ids+i等价于&ids[i]
        //分析取值
        //*(ids+0)等价于ids[0]
        //*(ids+1)等价于ids[1]     
        //以此类推.....
        //总结:*(ids+i)等价于ids[i]  
        printf("%d  %#x\n",*(ids+i),ids+i);
    }

    printf("\n\n");
    int *p = ids;
    int i = 0;
    for(;i<6;i++){
        printf("%d  %#x\n ",ids[i],&ids[i]);
        printf("%d  %#x\n ",*(p+i),p+i);
    }

}

9.指针和二维数组

void main(){

    //两行三列二维数组
    int ids[2][3] = {32,43,24,53,64,63};
    //遍历二维数组:外层循环控制行,内层循环控制列。
    int i = 0;
    for(;i<2;i++){
        int j = 0;
        for(;j<3;j++){
            printf(“值:%d 地址:%#x”,
            ids[i][j],&ids[i][j]);
        }
    printf("\n");
   }

   printf("\n");
   printf("\n");    

  //地址相同,不代表值相同。
  //ids代表的是一个行指针,指向一个有三个元素数组,大小
  //12
  //&ids代表的是一个二维数组指针,当前二维数组6个元素,
  //长度24。
  //*ids代表的是一个指向该二维数组的数据类型的指针(相当
  //于首地址:ids[0][0]
  printf("ids:%#x  &ids:%#x       *ids:%#x\n",ids,&ids,*ids);
  printf("长度:%d  长度:%d  长度:%d\n",sizeof(*ids),sizeof(*&ids),sizeof(**ids));
  printf("值:%d\n",**ids);

  //打印第二行第三列
  printf(“%d\n”,ids[1][2]);
  //推导过程分析
  //ids+0代表第一行 第一行的第一个值
  //ids+1代表第二行 第二行的第一个值
  //以此类推 ids+i
  //取每一行第一个元素的指针:*(ids+i)

  //取第一行第一个指针:*ids+0
  //取第一行第二个指针:*ids+1
  //取第一行第三个指针:*ids+2
  //以此类推 *ids+j

  //取第一行第二个指针:*(ids+0)+1;
  //取第二行第二个指针:*(ids+1)+1;
  //以此类推:*(ids+i)+j (这个公式获取的是地址,
  //是一个指针变量)
  //值:*(*(ids+i)+j)

  printf("%d",*(*(ids+1)+2));

  getchar();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值