C-指针

C-指针

概念

保存地址的变量

普通变量的值是实际的值,指针变量的值时具有实际值的变量的地址

运算符&

作用:获取变量的地址,并且后面永远跟着的是变量

&可以取出一个变量的地址,这个地址的大小,数据类型是否与int相同取决于编译器(64 or 32)

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int a = 1;
 6     int b; 
 7     b = int(&a);
 8     printf("%p
", &a);
 9     printf("%x
", b); 
10     printf("%lu
", sizeof(int));
11     printf("%lu
", sizeof(&a));
12     return 0;
13 }

说明:以32位架构编译上述代码,前两个打印相同,以64位则不同(64:sizeof(int)为4个字节,sizeof(&i)是8个字节,32:都是4个字节)

注意:不能对没有地址的东⻄取地址,如下

&(a+b) X

&(a++) X

&(++a) X

相邻变量的地址 V

&的结果的sizeof  V

数组的地址 V

数组单元的地址 V

相邻数组单元的地址 V

说明

比如int* p = &b;

指针p保存的就是&取地址符取变量b地址的变量

*表示p是一个指针 ,它指向int,我们把变量b的地址交给p

我们可以说p指向b,就是指p变量的值是变量b的地址

int* p,q;

int *p, q;

同一个意思,p是一个指针,指向int,q是一个int类型的变量

我们不是把*加给了int而是把*加给了p, *p是一个int,于是p是一个指针,

并不是说p是int*这种类型

如果你想要把p, q都表示指针,int *p, *q

指针作为参数

1)void f(int *p);

在调用的时候得到了某个变量的地址

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

在函数中可以通过这个指针访问外面的这个i

运算符*

用来访问指针的值所表示的地址上的变量

通过指针变量,我们可以获取一个变量的地址,可以使得函数读写外面变量的能力,用*访问

用法:既可以做右值也可以做左值

int k = *p;

*p = k + 1;

左值

出现在赋值号(=)左边的不是变量,而是值,是表达式计算的结果,是特殊的值

a[0] = 1;

*p = 3;

运算符&和*

&*互相反作⽤

1)*&yptr -> * (&yptr) -> * (yptr的地址)-> 得到那个地址上的变量 -> yptr

2)&*yptr -> &(*yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr

指针的应用

1)交换两个变量的值

2)当个函数需要返回多个值时,某些值就只能通过指针来返回

  (传入的参数实际上就是用来保存结果的变量)

比如:   

函数返回运算的状态,结果通过指针返回(

  状态用函数return,实际值通过指针

  这样做的好处是可以把函数的返回结果放到if语句中

  我的运算可能会出错,这种错误通过另外的途径表达出来

常⽤的套路是让函数返回特殊的不属于有效范围内的值来表⽰出错:-1或0(在⽂件操作会看到⼤量的例⼦)

但是当任何数值都是有效的可能结果时,就得分开返回了

后续的语⾔(C++,Java)采⽤了异常机制来解决这个问题

 

常见错误

定义了指针变量,还没有指向任何变量,就开始使⽤指针

 

思考问题

1)为什么如下这段代码在编译时没有报错

int i;
scanf("%d", i);

因为在win32系统下编译c时,地址和int是一样大的,你把一个int整数传进去和把一个地址传进去对于scanf来说没有区别,

它会以为你传进去的是i的地址。

参考资料:《翁恺C语言编程》

原文地址:https://www.cnblogs.com/marton/p/12354658.html