2

Summary

1)指针的本质是变量,特殊在于存储的内容是一段内存地址

2)在指针声明时*号表示所声明的变量为指针;在指针使用时*号表示取指针所指向的内存空间中的值

3)指针作为函数参数:

  • 指针是变量,因此可以声明指针参数
  • 当一个函数体内部需要改变实参的值
  • 则需要使用指针参数;函数调用时实参值将复制到形参
  • 指针适用于复杂数据类型作为参数的函数中

4)口诀:左数右指 -- 当const出现在*号左侧时,指向的数据为常量;当const出现在*号右侧时,指针为常量

const int* p;        // 指针p可变,指向的数据*p不可变
int const* p;        // 指针p可变,指向的数据*p不可变
int* const p;        // 指针p不可变,指向的数据*p可变
const int* const p;  // 指针p不可变,指向的数据*p也不可变

指针的本质分析

问题:程序中的变量只是一段存储空间的别名,那么是不是必须通过这个别名才能使用这段存储空间?

1、指针的声明和使用

下面的程序输出什么?为什么

int i = 5;
int* p = &i;

printf("%d, %p\n", i, p);    // 5, 0XBFDB216C

*p = 10;

printf("%d, %p\n", i, p);    // 10, 0XBFDB216C
  • 在指针声明时*号表示所声明的变量为指针
  • 在指针使用时*号表示取指针所指向的内存空间中的值
    image.png

2、传值调用和传址调用

  • 指针是变量,因此可以声明指针参数
  • 当一个函数体内部需要改变实参的值,则需要使用指针参数
  • 函数调用时实参值将复制到形参
  • 指针适用于复杂数据类型作为参数的函数中

    // 指针作为参数分析
    void swap1(int a, int b)
    {
      int t = a;
      a = b;
      b = a;
    }
    
    void swap2(int* pa, int* pb)
    {
      int t = *pa;
      *pa = *pb;
      *pb = t;
    }
    
    int main()
    {
      int a = 1, b = 2;
    
      swap1(a, b);                 // 将实参a和b的值,赋值给swap1参数a、b,函数内部实际修改的是函数的形参a和b,不会影响实参
      printf("%d, %d\n", a, b);    // 1, 2
      
      swap2(&a, &b);               // 将实参a和b的地址,赋值给参数指针pa和pb,函数内部使用*号打开了这两个地址,并修改了里面的值,所以外面的实参也会变
      printf("%d, %d\n", a, b);    // 2, 1
      return 0;
    }

3、const和指针

口诀:左数右指 -- 当const出现在*号左侧时,指向的数据为常量;当const出现在*号右侧时,指针为常量

const int* p;        // 指针p可变,指向的数据*p不可变
int const* p;        // 指针p可变,指向的数据*p不可变
int* const p;        // 指针p不可变,指向的数据*p可变
const int* const p;  // 指针p不可变,指向的数据*p也不可变

本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。


bryson
169 声望12 粉丝