当前位置:   article > 正文

【C语言】深入浅出谈指针:理解指针、指针定义和指针代码实例swap(代码详细注释,含易错实例以及改进办法):利用指针进行交换数值,以及出现数值不改变的改进方法---透彻理解‘*‘指针_c语言指针交换变量a和b的值

c语言指针交换变量a和b的值

巧记=》4行文字迅速学习指针

指针的产生(理解指针):

1.了解指针的产生:

2.指针相关定义

3.巧记:

4.易错点

代码实例(注释包含常见注意事项)

1.change1方法为错误演示(),change1改进型change3方法单独程序在下面

2.change3()改进单独运行实例


一、指针的产生(理解指针):

PS:先理解相关概念:存储单元的地址(房间号)和存储单元的内容(房间里的人)。

1.了解指针的产生:

访问变量内容有两种方法:(以i =3 ;举例)

(1)直接访问(变量名来引用变量值):直接将3送到变量i所标志的单元中(知道房间号,直接去找人)//i=3; ---实际上,是通过变量名i找到存储单元的地址,从而对存储单元的内容进行操作。

(2)间接访问:先将i的地址存放在i_pointer变量中,然后将3送到变量i_pointer指向的单元(先找第三人问出房间号,然后去对应房间找人)//*i_pointer=3; --其中*i_pointer表示:i_pointer指向的对象i

2.指针相关定义

1)&i--i对应的地址;

2)int *p1, *p2; --(*p1,*p2中*表示:该变量的类型为指针型变量;)、(指针变量名是p1、p2);

3)int *p1=&a1, *p2=&a2;--(*和定义类型一起出现-->表示该变量类型为指针型变量;*单独和变量名出现表示:指针变量指向的对象/  *p1-->a1、*p2-->a2等价)

4)int *p1=&a1, *p2=&a2;       等价于:int *p1, *p2;   p1=&a1; p2=&a2;

5)&取地址符,*指针运算符/间接访问运算符

3.巧记:

//定义类型与*一起出现(int *p1;),*可默认无作用,仅用来提示是定义指针

//*和指针变量名出现(*p=3;<-->a=3;),*起指向作用,*p即为指向p指向的对象;

//仅指针变量名出现(p=&a;),p表示地址,此时可以给p变量赋地址值

//还是...不会.....:1)见int、float类把*划掉,但要知道定义了指针、2)*p与a等价,p与&a等价

4.易错点

1)创建指针需要赋值或p=NULL;  ,防止出现野指针,指向未知区域

2)   对于变量a:scanf("%d",&a);    printf("%d",a);  

        对于指针变量p=&a: scanf("%d",p);    printf("%d",*p);  //*p与a等价,p与&a等价

         printf("%d",p);//输出&a,a的地址

二、指针引用数组

1.初始化数组指针:int a[6];

1)  int *p; p=a;  //a为数组首元素地址

2)int *p; p=&a[0];  //同(1)

3)int *p=a; //同(1)

2.数组指针的运算

1) a++;p+1;p++;  表示指向同一数组的下一个元素,a-1; p-1;p--;同理

2)以p+1;为例:1其实指数组元素占用的字节数,p+1代表地址实际是:p+1*d,d为一个数组元素所占字符数(sizeof(a)可以求得)。

3)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i];     //[]实际上是变址运算符

        (1) 当p=a; p[i]=a[i];//p[i]的编译等同*(p+i);

        (2)*p++;  //*与++同优先级,自右向左结合,所以等同:*(p++);

                -----优先级:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

                -----运算方向根据结合方向来判断(从右向左

                         三目运算符(?: 条件运算符 )     表达式1?表达式2: 表达式3 

                         赋值运算符(=)       -=、/=、%=

                        强制类型转换、sizeof 长度运算符、& 取地址运算符、

                        - 负号运算符、! 逻辑非运算符、~ 按位取反运算符

                        * 取值运算符、++ 自增运算符、-- 自减运算符

                *p++;   等价于:  *(p++);

                        

4 )p1-p2(均指向同一数组)结果是:两个地址之差(p1-p2的值除以数组元素的长度)

------两个地址不能相加,相加也无实际意义

3.通过指针引用数组

下标法:a[i];

指针法:*(a+i)、*(p+i)

*p比a[i]运算的快,因为指针是直接指向地址,数组下标法每次需要计算地址

三、代码实例(注释包含常见注意事项)

1.change1方法为错误演示(),change1改进型change3方法单独程序在下面

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. //int *p1,*p2,*p3;
  4. int main()
  5. {
  6. void change1(int *b1,int *b2);//声明函数
  7. void change2(int *b1,int *b2);//声明函数
  8. void change3(int *b1,int *b2);//声明函数
  9. printf("pointer!\n");
  10. int a1,a2,a3;
  11. a1=1; a2=2; a3=3;
  12. int *p1,*p2,*p3=&a3;
  13. //p3=&a3;
  14. p1=&a1;
  15. p2=&a2;
  16. printf("未互换地址时p1,p2,p3:%d,%d,%d\n",*p1,*p2,*p3);
  17. printf("----------------------------------------\n");
  18. printf("错误实例,仅改指针b1,b2值,p1,p3并未变\n");
  19. printf("未互换P:%d,%d,%d\n",p1,p2,p3);
  20. change1(p1,p3);//等价change(&a1,&a3);
  21. printf("互换后P:%d,%d,%d\n",p1,p2,p3);
  22. printf("互换地址后p1,p2,p3:%d,%d,%d\n",*p1,*p2,*p3);
  23. printf("----------------------------------------\n");
  24. //使用改进实例需要将其余部分注释掉,因为全局变量和局部变量重名冲突了
  25. // printf("改正实例:既然是p1,p2没交换,最后更改以下即可\n");//需要定义指针为全局变量
  26. // printf("p1=b1,p3=b2\n");
  27. // printf("未互换P:%d,%d,%d\n",p1,p2,p3);
  28. // change3(p1,p3);//等价change(&a1,&a3);
  29. // printf("互换后P:%d,%d,%d\n",p1,p2,p3);
  30. // printf("互换地址后p1,p2,p3:%d,%d,%d\n",*p1,*p2,*p3);
  31. //
  32. // printf("----------------------------------------\n");
  33. printf("正确实例:既然是a1,a2对象交换,函数就要进行对象的交换*p1,*p2\n");
  34. printf("p1->a1;temp=a1;p1=p2->a2;p2=temp->a1\n");
  35. printf("未互换P:%d,%d,%d\n",p1,p2,p3);
  36. change2(p1,p3);//等价change(&a1,&a3);
  37. printf("互换后P:%d,%d,%d\n",p1,p2,p3);
  38. printf("互换地址后p1,p2,p3:%d,%d,%d\n",*p1,*p2,*p3);
  39. printf("----------------------------------------\n");
  40. return 0;
  41. }
  42. void change1(int *b1,int *b2){
  43. int *b=NULL;//防止野指针
  44. b=b1;//b存b1存储的地址值
  45. b1=b2;
  46. b2=b;//b1 ,b2存储的地址值互换
  47. printf("互换后B:%d,%d\n",b1,b2);
  48. }
  49. void change3(int *b1,int *b2){
  50. int *b=NULL;//防止野指针
  51. b=b1;//b存b1存储的地址值
  52. b1=b2;
  53. b2=b;//b1 ,b2存储的地址值互换
  54. printf("互换后B:%d,%d\n",b1,b2);
  55. p1=b1;
  56. p3=b2;
  57. printf("互换后P:%d,%d\n",p1,p2);
  58. }
  59. void change2(int *b1,int *b2){
  60. int temp;//
  61. temp=*b1;//
  62. *b1=*b2;
  63. *b2=temp;//b1 ,b2存储的地址值互换
  64. printf("互换后B:%d,%d\n",b1,b2);
  65. }

2.change3()改进单独运行实例

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int *p1,*p2,*p3;
  4. int main()
  5. {
  6. void change2(int *b1,int *b2);//声明函数
  7. printf("pointer!\n");
  8. int a1,a2,a3;
  9. a1=1; a2=2; a3=3;
  10. //int *p1,*p2,*p3=&a3;
  11. p3=&a3;
  12. p1=&a1;
  13. p2=&a2;
  14. printf("----------------------------------------\n");
  15. //使用改进实例需要将其余部分注释掉,因为全局变量和局部变量重名冲突了
  16. printf("改正实例:既然是p1,p2没交换,最后更改以下即可\n");//需要定义指针为全局变量
  17. printf("p1=b1,p3=b2\n");
  18. printf("未互换P:%d,%d,%d\n",p1,p2,p3);
  19. change3(p1,p3);//等价change(&a1,&a3);
  20. printf("互换后P:%d,%d,%d\n",p1,p2,p3);
  21. printf("互换地址后p1,p2,p3:%d,%d,%d\n",*p1,*p2,*p3);
  22. printf("----------------------------------------\n");
  23. return 0;
  24. }
  25. void change3(int *b1,int *b2){
  26. int *b=NULL;//防止野指针
  27. b=b1;//b存b1存储的地址值
  28. b1=b2;
  29. b2=b;//b1 ,b2存储的地址值互换
  30. printf("互换后B:%d,%d\n",b1,b2);
  31. p1=b1;
  32. p3=b2;
  33. printf("互换后P:%d,%d\n",p1,p2);
  34. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/思考机器4/article/detail/63061
推荐阅读
相关标签
  

闽ICP备14008679号