C语言教程指针笔记整理(一)

打印 上一主题 下一主题

主题 801|帖子 801|积分 2403

https://www.bilibili.com/video/BV1cx4y1d7Ut?spm_id_from=333.788.videopod.episodes&vd_source=e8984989cddeb3ef7b7e9fd89098dbe8&p=107
本篇为贺宏宏老师C语言教程指针部门笔记整理
//.c文件
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <ctype.h>
复制代码
//8-1 什么是指针
//指针:就是地址!
//指针:就是地址!
//指针:就是地址!
  1. int main()
  2. {
  3.     int a = 10; //4个字节   
  4.     int b = 20;
  5.     &a; //获取a的地址
  6.     &b; //获取b的地址
  7.     //printf("a的地址=%p,b的地址=%p\n",&a,&b);//%p:输出地址(指针),以16进制进行输出
  8.     printf("a的地址=%d,b的地址=%d\n",&a,&b);
  9.     return 0;
  10. }
复制代码
// 8-2 指针变量
  1. int main()
  2. {
  3.     int a = 10;
  4.     int b = 20;
  5.     int *p = &a; //一个int地址(指针)赋值给一个int指针变量
  6.     //获取a的地址,int &p = &a;(int &p C++引用) int *p = &a;
  7.     p = &b; //把b的地址赋值给p //此处不能用*p了,*p的含义是引用,一词多义
  8.     char c;
  9.     double d;
  10.     char *p1 = &c;
  11.     double *p2 = &d;//指针的类型要根据变量的类型进行匹配
  12.     return 0;
  13. }
复制代码
// 8-3 使用指针变量
  1. int main()
  2. {
  3.     int a = 10;
  4.     printf("%d,%d\n",a,&a);//a的值,a的地址
  5.     int *p = &a;
  6.     printf("%d,%d,%d\n",*p,p,&p);//p指向的变量a的值,a的地址,p的地址
  7.     return 0;
  8. }
复制代码
// 8-4 &的多个作用
// &的作用:1.按位与 比方4&3 2.取地址 比方 &a 3.C++的引用
//&变量名:获取该变量的地址(指针),&:取地址符(号);这里的&是个单目运算符
//4&3:按位与,这里的&是个双目运算符,有两个变量
  1. int main()
  2. {
  3.     int a = 10;
  4.     int b = 20;
  5.     int c = 4 & 3;//按位与 100 & 011 = 000
  6.     printf("%d\n",c);
  7.     printf("%p,%p,%p\n",&a,&b,&c);
  8.     printf("%p,%p,%p\n",&a&b);//按位与
  9.     int& d = a;//C++的引用,相当于a有一个别名叫d了;与其他两种用法的不同在于这个&前面有数据类型
  10.     return 0;
  11. }
复制代码
//8-5 指针应用(指针最紧张的部门) Swap互换数据(两个错误示例)
//互换两个变量的值(写成函数)
  1. void Swap_err1(int a, int b)//没有交换成功,错误
  2. {
  3.     int tmp = a;
  4.     a =  b;
  5.     b = tmp;
  6.     printf("%d %d",&a,&b);
  7. }
  8. void Swap_err2(int *p1, int *p2)//没有解引用,交换失败
  9. {
  10.     int *tmp = p1;
  11.     p1 = p2;
  12.     p2 = tmp;
  13. }
复制代码

//8-6 指针应用 Swap互换数据2
//总结:一个函数A通过调用函数B,来修改A中变量的值:
//: 1.必须传指针; 2.B中必须解引用
  1. void Swap(int *p1,int *p2)
  2. {
  3.     int tmp;
  4.     tmp = *p1;
  5.     *p1 = *p2;
  6.     *p2 = tmp;
  7. }
  8. int main()
  9. {
  10.     int a,b;
  11.     scanf("%d%d",&a,&b);
  12.     printf("%d %d",&a,&b);
  13.     printf("交换前=%d,%d\n",a,b);
  14.     Swap(&a,&b);//交换a,b两个值
  15.     printf("交换后=%d,%d\n",a,b);
  16.     return 0;
  17. }
复制代码

// 8-7 通过指针返回多个值
//C语言怎么返回两个值?
  1. double Fun(int a, int b, int c)
  2. {
  3.     int d = b * b - 4 * a * c;
  4.     double x1, x2;
  5.     x1 = (-b + sqrt(d))/(2 * a);
  6.     x2 = (-b - sqrt(d))/(2 * a);
  7.     return x1; // C语言一般只能返回0个或1个值
  8. }
  9. double Fun(int a, int b, int c, double *x1,double *x2)
  10. {
  11.     int d = b * b - 4 * a * c;
  12.     double x1, x2;
  13.     *x1 = (-b + sqrt(d))/(2 * a);
  14.     *x2 = (-b - sqrt(d))/(2 * a);
  15.     return 2; //2个根
  16. }
  17. int main()
  18. {
  19.     double x1;
  20.     double x2;
  21.     Fun(4,5,1,&x1,&x2);
  22.     printf("%lf,%lf\n",x1,x2);
  23. }
复制代码
//8-9 指针指向数组元素
//问题1:指针如何指向这个数组的元素
//问题2:arr名字
//一维数组arr的名字arr表示整个数组只在如下情况:
//1.在界说数组的同一个函数中求sizeof.比方int arr[10]; sizeof(arr) -> 40,由于int是4个字节
//2.在界说数组的同一个函数中&arr+1表示&arr的地址加一整个数组的大小,比方int arr[10],&arr,&arr+1 = &arr+40
//其他情况,arr都表示数组的起始地址
  1. int main()
  2. {
  3.     int arr[10] = {1,3,5,7,9,11,13,15,17,19};
  4.    
  5.     //int* p = &arr[0];//第一个元素int的地址
  6.     int *p = arr;//和上一行等价
  7.     printf("%d,\n%d\n",*p,arr[0]);
  8.     printf("%d,\n%d,\n%d\n",&arr,sizeof(arr),&arr+1);
  9.     return 0;
  10. }
复制代码
//8-10 指针的加法运算
//指针的算数运算:条件是这个指针指向一个数组,同时程序应该包管不越界
//p+整数,p++,++p合法
  1. int main()
  2. {
  3.     int arr[10] = {1,3,5,7,9,11,13,15,17,19};
  4.    
  5.     //int* p = &arr[0];//第一个元素int的地址
  6.     int *p = arr;//和上一行等价
  7.     printf("%d ",*p);
  8.     //通过指针输出(访问)数组的所有元素
  9.     for(int i = 0; i < 10; i++, p++)
  10.     {
  11.         printf("%d ",*p);
  12.     }
  13.     return 0;
  14. }
复制代码
//8-11指针的减法运算
//指针的算数运算:条件是这个指针指向一个数组,同时程序应该包管不越界
//p+整数,p++,++p合法
  1. int main()
  2. {
  3.     int arr[10] = {1,3,5,7,9,11,13,15,17,19};
  4.    
  5.     //int* p = &arr[0];//第一个元素int的地址
  6.     int *p = &arr[9];//和上一行等价
  7.     int num = sizeof(arr);
  8.     printf("%d\n",num); // sizeof(arr)可是40哦,不是10哦,因为int表示4个字节哦。
  9.     for(int i = 0; i < 10; i++)//所以这里不能写成i < sizeof(arr),这样就循环40次了。超过10就越界,要出错了
  10.     {
  11.         printf("%d ",*p--);
  12.     }
  13. }
复制代码
//8-12通过指针引用数组元素
  1. int main()
  2. {
  3.     int a[10];
  4.     int i;
  5.     int *p = a;
  6.     printf("please enter 10 integer numbers:");
  7.     for(i = 0; i < 10; i++)
  8.         scanf("%d", &a[i]);
  9.     for(i = 0; i < 10; i++)
  10.         printf("%d ",a[i]);
  11.     printf("\n");
  12.     return 0;
  13. }
复制代码
//8-13 指针的关系运算
//<,> >= , <=, !=,条件是必须指向同一个数组,绝对不可以操作差别的数组
// 错误用法:在差别的数组了,返回值为0
  1. int main()
  2. {
  3.     int a = 10;
  4.     int b = 20;
  5.     int *p = &a;
  6.     printf("%d\n",*(p+1));//错误的应用
  7.     int *q = &b;
  8. }
复制代码
//从头至尾输出数组
  1. int main()
  2. {
  3.     int arr[10] = {1,2,3,4,5,6,7,8,9,10};
  4.    
  5.         for(int *p = arr;p!= &arr[10];p++)//标准规定可以使用尾后(尾巴的后面:此处是指数组最后一位的下一处地址)地址(指针)
  6.             printf("%d ",*p); //输出1 2 3...
  7.     //或者
  8.     /*
  9.         for(int *p = arr; p != &arr[10]; p++)
  10.             printf("%d ",*p);   
  11.     */
  12.     //或者
  13.     /*
  14.         for(int *p = arr; p <= &arr[9]; p++)
  15.             printf("%d ",*p);   
  16.     */
  17.       return 0;
  18. }
复制代码
//8-15 指针在数组中的错误应用
//常见的错误:越界错误
  1. int main()
  2. {
  3.     int a[10];
  4.     int i;
  5.     int *p;
  6.     p= a;
  7.     printf("please enter 10 integer numbers:");
  8.    
  9.     for(i = 0; i < 10; i++)
  10.         scanf("%d", p++); //这里p的指针已经到数组的最后了(p已经到达a的尾后指针),改进办法:p = a;(把p重新赋值),下一行
  11.    
  12.     p = a;
  13.    
  14.     for(i = 0; i < 10; i++,p++)//这里p指针再往后就不是数组内的数了,就是空的地方了,输出的数为随机的数值
  15.         printf("%d ",*p);
  16.     printf("\n");
  17.     return 0;
  18. }
复制代码
8-16
//8-16 数组作为参数传递:数组名仅仅表示数组首元素的地址
//传数组名+数组长度
//示例1.输出数组的全部元素
//p:数组的起始地址,n:元素的个数
  1. void Show (int *p, int n)
  2. {
  3.     for(int i = 0; i < n; i++)
  4.     {
  5.         printf("%d ",p[i]);
  6.     }
  7. }
  8. int main()
  9. {
  10.     int arr[10] = {1,2,3,4,5,6,7,8,9,10};
  11.     Show(arr,sizeof(arr)/sizeof(arr[0]));//数组元素个数=数组长度/数组每一个元素的长度(这里用第一个元素的长度指代了)
  12.     return 0;
  13. }
复制代码
//示例2.将数组a中n个整数按相反顺序存放
  1. void inv(int *x, int n) //x数组的起始地址,n元素个数
  2. {
  3.     int tmp;
  4.     //把x当作数组名来操作:(更推荐使用这种方法)
  5.    
  6.     // for(int i = 0, j = n-1; i < j; i++, j--)//i往后走,j往前走
  7.     // {
  8.     //     tmp = x[i];
  9.     //     x[i] = x[j];
  10.     //     x[j] = tmp;
  11.     // }
  12.    
  13.     //把x当作指针来操作:
  14.     for(int i = 0, j = n-1; i < j; i++, j--)
  15.     {
  16.         tmp = *(x+i);
  17.         *(x+i) = *(x+j);
  18.         *(x+j) = tmp;
  19.     }   
  20. }
  21. void Show (int *p, int n)
  22. {
  23.     for(int i = 0; i < n; i++)
  24.     {
  25.         printf("%d ",p[i]);
  26.     }
  27. }
  28. int main()
  29. {
  30.     int arr[] = {1,3,5,7,9,11,13,15,17,19};
  31.     inv(arr,sizeof(arr)/sizeof(arr[0]));
  32.     Show(arr,sizeof(arr)/sizeof(arr[0]));
  33.     return 0;
  34. }
复制代码
把x当作数组名来操作:

把x当作指针来操作:

示例3

5个数字至少必要4次遍历:
第一次:
将第一个数字与剩下的最小值进行比力:
如果第一个数字小于剩下数字的最小值,顺序稳定;
如果第一个数字大于剩下数字的最小值,将剩下数字的最小值与第一个数字进行互换。
第二次:
将第二个数字与剩下的最小值进行比力:
如果第二个数字小于剩下数字的最小值,顺序稳定;
如果第二个数字大于剩下数字的最小值,将剩下数字的最小值与第二个数字进行互换。
第三次:
将第三个数字与剩下的最小值进行比力:
如果第三个数字小于剩下数字的最小值,顺序稳定;
如果第三个数字大于剩下数字的最小值,将剩下数字的最小值与第三个数字进行互换。
第四次:
将第四个数字与剩下的最小值进行比力:
如果第四个数字小于剩下数字的最小值,顺序稳定;
如果第四个数字大于剩下数字的最小值,将剩下数字的最小值与第四个数字进行互换。
第五次:
将第五个数字与剩下的最小值进行比力:
如果第五个数字小于剩下数字的最小值,顺序稳定;
如果第五个数字大于剩下数字的最小值,将剩下数字的最小值与第五个数字进行互换。
//示例3.用指针方法对10个整数按由大到小顺序排序(选择排序法)
//选择法排序:每次从待排序的数中找最小值和待排序的第一个值进行互换,直到全部有序
//arr:数组起始地址,n:元素个数
//下标法。优先保举使用下标法,指针法轻易堕落
  1. void SelectSort1(int* arr, int n)
  2. {
  3.     int k;
  4.     int tmp;
  5.     for(int i = 0; i < n-1; i++)
  6.     {
  7.         k = i;//这里要提前给k赋值一下
  8.         for(int j = i+1; j < n; j++)
  9.         {
  10.             if(arr[j] < arr[k]) //指针方式:*(arr+j) < *(arr+k)
  11.             {
  12.                k = j;
  13.             }
  14.         }
  15.         if(arr[k] != arr[i])//这里写k!=i就行了
  16.         {
  17.             tmp = arr[i];//指针方式:*(arr+i)
  18.             arr[i] = arr[k];//指针方式:*(arr+i) = *(arr+k)
  19.             arr[k] = tmp;//指针方式:*(arr+k)
  20.         }
  21.     }
  22. }
复制代码
//指针方式:
  1. void SelectSort(int* arr, int n)
  2. {
  3.     int k;
  4.     int tmp;
  5.     for(int i = 0; i < n-1; i++)
  6.     {
  7.         k = i;//这里要提前给k赋值一下
  8.         for(int j = i+1; j < n; j++)
  9.         {
  10.             if(*(arr+j) < *(arr+k))
  11.             {
  12.                k = j;
  13.             }
  14.         }
  15.         if(k != i)
  16.         {
  17.             tmp = *(arr+i);
  18.             *(arr+i) = *(arr+k);
  19.             *(arr+k)  = tmp;
  20.         }
  21.     }
  22. }
  23. void Show (int *p, int n)
  24. {
  25.     for(int i = 0; i < n; i++)
  26.     {
  27.         printf("%d ",p[i]);
  28.     }
  29. }
  30. int main()
  31. {
  32.     int arr[] = {10,3,65,7,69,181,193,15,157,19};
  33.     Show(arr,sizeof(arr)/sizeof(arr[0]));
  34.     printf("\n");
  35.     SelectSort(arr,sizeof(arr)/sizeof(arr[0]));
  36.     Show(arr,sizeof(arr)/sizeof(arr[0]));
  37.     return 0;
  38. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表