流心
发布于 2024-05-09 / 1 阅读
0

指针

Scanf

如果能够将取得的变量的地址传递给一个函数,能否通过这个地址在那个函数内访问这个变量

  • scanf("%d",&i);

指针

  • 就是保存地址的变量

    • int i;

    • int* p = &i;

    • int* p,q;

    • int *p,q;

  • 变量的值是内存的地址

    • 普通变量的值是实际的值

    • 指针变量的值是具有实际值的变量的地址

int *p = i; // 假设 i 的变量地址值是 0x2001,这句代码就是将 i 的地址值 0x2001 赋值给 p ; 不管 i 里面是什么内容 p 的内容只会是 0x2001

作为参数的指针

  • void f(int * p);

  • 再别调用的时候得到某个变量的地址:

    • int i = 0;f(&i);

  • 在函数里面可以通过这个指针访问我们的这个 i ;

传入地址

  • 为什么 int i;scanf("%d",i); 编译没有报错?

  • 在大多数C/C++编译器中应该是会报错的。这是因为 scanf 函数期望其第二个及后续参数是指针类型,用于接收输入的数据。i 是一个整数变量,而不是一个指向整数的指针。

  • 正确代码

    • int i;

    • scanf("%d", &i);

指针最常见的错误

  • 定义了指针变量,还没有指向然后变量,就开始使用指针

    • int *p ; int i = 18; *p = 12; // 错误写法

    • i = 18; *p = 12; // 12会开辟另外的空间比如 0xaab, *p 指向 0xaab,如果刚好 0xaab 不能写,程序就会报错

指针和数组

  • 数组参数

  • 四种函数原型等价

    • int sum(int *ar,int n);

    • int sum(int *,int);

    • int sum(int ar[],int n);

    • int sum(int [],int);

  • 数组变量是特殊的指针

    • 数组变量本身表达地址,所以

      • int a[10]; int *p = a; //无需用 & 取地址

      • 但是数组的单元表达的是变量,需要用 & 取地址

      • a == &a[0];

    • [] 运算符可以对数组做,也可以对指针做:

      • p[0] <==> a[0]

    • *运算符可以对指针做,也可以对数组做:

      • *a = 25;

    • 数组变量是 const 的指针,所以不能被赋值

      • int a[] <==> int * const a = ...

指针是 const

  • 表示一旦得到某个变量的地址,不能再指向其他变量

    • int * const q = &i; // q 是 const

    • *q = 26; // ok

    • q++; // ERROR

转换

  • 总是可以把一个非 const 的值转换成 const 的

    • void f(const int *x);

    • int a = 15;

    • f(&a); //ok

    • const int b = a;

    • f(&b); //ok

    • b = a+1; // Error

    • 当要传递的参数类型比地址大的时候,这是常用的手段,既能用比较少的字节数传递给参数,又能避免函数对外面变量的修改

保护数组值

  • 因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值。

  • 为了保护数组不被函数破坏,可以设置参数为 const

    • int sum(cosnt int a[] , int length);