• 【C语言】指针那些事(上)


    C语言系列

    文章目录


    文章目录

    一. 字符指针

    一.(1 ) 数组创建空间的地址和指针指向的地址

    二. 指针数组

    二.(1)指针数组模拟一个二维数组

             三. 数组指针

             三.(1)数组指针到底有什么用

    对一维数组没有什么用

    二.(2)正常的二维数组传参的写法 

    总结


    前言

    该文章详细的讲解都有啥指针,及包括指针的日常使用等等,各位可以愉快的食用该文章的对于指针的理解,可以为大家对指针的理解加深一点。


    一. 字符指针

    关于指针的基本常识:
    1. 指针变量就是个变量,用来存放地址,地址唯一标识一块内存空间。
    理解:内存单元是有编号,编号 == 地址 == 指针 要存起来的话就需要一个指针变量 
    2. 指针的大小是固定的4 / 8个字节(32位平台 / 64位平台)。
    理解:地址/指针的大小是4/8个字节,或者是指针变量的大小是4/8个字节
    3. 指针是有类型,指针的类型决定了指针的 + -整数的步长,指针解引用操作的时候的权限。
    4. 指针的运算。

    1. int main()
    2. {
    3.     char ch = 'w';
    4.     char* pc = &ch;
    5.     //将一个字符w的地址赋值给到char*类型的指针变量里面去
    6.     char* p = "abcdef";//该字符串作为一个表达式的时候它的值其实是首字符的地址
    7.     //当我们把这个字符串赋给p的时候,其实就是将该字符串的首地址赋给p
    8.     //当我们在x86环境下,一个指针变量是4个字节
    9.     //常量字符串无法被改变
    10.     printf("%s\n", p);//通过这个字符指针,可以连续访问整个字符串
    11.     printf("%c\n",*p);//对p进行解引用只能拿到一个字符
    12.     return 0;
    13. }

    一.(1 ) 数组创建空间的地址和指针指向的地址

    我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

    1. int main()
    2. {
    3.     char str1[] = "hello bit.";
    4.     char str2[] = "hello bit.";
    5.     //str1和str2两个数组创建了两个不同空间
    6.     //系统创建一个常量字符串,因为常量字符串无法被修改,
    7. //所以系统不会创建两个相同的常量字符串,
    8. //str3和str4这两个指针变量指向的就是那个相同的常量字符串的首地址
    9.     //str3和str4还是两个不同的指针变量,但是它们的存放的值是相同的
    10.     const char* str3 = "hello bit.";
    11.     const char* str4 = "hello bit.";
    12.     if (str1 == str2)
    13.         printf("str1 and str2 are same\n");
    14.     else
    15.         printf("str1 and str2 are not same\n");
    16.     if (str3 == str4)
    17.         printf("str3 and str4 are same\n");
    18.     else
    19.         printf("str3 and str4 are not same\n");
    20.     return 0;
    21. }


     二. 指针数组

    关于指针数组是个啥?

    指针数组是数组
    字符数组 - 存放字符的数组
    整型数组 - 存放整型的数组
    指针数组 - 存放指针的数组,存放在数组中的元素都是指针类型的

      int*         arr[5];//存放整型指针的数组
    //整型指针类型 aar数组
    char* ch[6];//存放字符指针的数组

    1. int main()
    2. {
    3.     int a = 1;
    4.     int b = 2;
    5.     int c = 3;
    6.     int d = 4;
    7.     //不会有人这样使用,因为怎样使用的话,就是多此一举,还不如直接将数字写进数字里面去
    8.     int* arr[] = { &a,&b,&c,&d };
    9.     return 0;
    10. }

    二.(1)指针数组模拟一个二维数组

    我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

    1. int main()
    2. {
    3.     int arr1[] = { 1,2,3,4,5 };
    4.     int arr2[] = { 2,3,4,5,6 };
    5.     int arr3[] = { 3,4,5,6,7 };
    6.             //int* int* int*  //因为是arr1的地址指向的是数组中的整型,所以是整形指针
    7.     //这个时候就可以认为arr数组是一个指针数组
    8.     int* arr[] = { arr1,arr2,arr3 };
    9.     int i = 0;
    10.     for (i = 0; i < 3; i++)
    11.     {
    12.         int j = 0;
    13.         for (j = 0; j < 5; j++)
    14.         {
    15.             printf("%d", arr[i][j]);
    16.         }
    17.         printf("\n");
    18.     }
    19.     return 0;
    20. }

    1. int main()
    2. {
    3.     //指针数组:就是数组类型是指针类型的数组 
    4.     char* arr[5] = { "hello bit","hehe","penggeC","bitejiuyeke","c++" };
    5.     int i = 0;
    6.     for (i = 0; i < 5; i++)
    7.     {
    8.         printf("%s\n", arr[i]);
    9.     }
    10.     return 0;
    11. }

     三. 数组指针

    啥是数组指针: 

    指针数组 - 是数组,是存放指针的数组
    数组指针 - 是指针
    字符指针 - 指向字符的指针
    整型指针 - 指向整型的指针
    浮点型指针 - 指向浮点数指针
    数组指针 - 指向数组的指针

    将数组的地址赋给数组指针

     数组名的理解
     数组名是数组首元素的地址
     但是存在两个例外
     1,sizeof(数组名)
     2,&数组名,这里的数组名表示整个数组,取出的是数组的地址

    1. int main()
    2. {
    3.     int arr[10];
    4.     printf("%p\n", arr);//数组名是首元素的地址int*
    5.     printf("%p\n", arr+1);//数组名是首元素的地址+1就是加一个整数4
    6.     printf("%p\n", &arr[0]);//arr[0]是首元素地址int*
    7.     printf("%p\n", &arr[0]+1);//arr[0]是首元素地址+1就是加一个整数4
    8.     printf("%p\n", &arr);//arr的数组地址
    9.     printf("%p\n", &arr+1);//1就是增加了一个数组的大小
    10.     //指针类型决定了指针+1.到底是+几个字节
    11.     return 0;
    12. }

    三.(1)数组指针到底有什么用

    对一维数组没有什么用

    1. int main()
    2. {
    3.     int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    4.     int* p = arr;
    5.     int i = 0;
    6.     for (i = 0; i < 10; i++)
    7.     {
    8.         printf("%d", p[i]);
    9.     }
    10.     //int (*p)[10] = &arr
    11.     //int i = 0;
    12.     /*for (i = 0; i < 10;)
    13.     {
    14.         printf("%d", (*p)[i]);
    15.     }*/
    16. //这两种形式上不同,但是他们的结果是相同的
    17.     return 0;
    18. }

    二.(2)正常的二维数组传参的写法 

    1. //数组名就是首元素地址 
    2. void print(int arr[3][5], int r, int c)//数组传参同样传的首元素地址,
    3. //首元素的地址是二维数组第一行的地址,
    4. {
    5.     int i = 0;
    6.     for (i = 0; i < 3; i++)
    7.     {
    8.         int j = 0;
    9.         for (j = 0; j < 5; j++)
    10.         {
    11.             printf("%d ", arr[i][j]);
    12.         }
    13.         printf("\n");
    14.     }
    15. }
    16. print(int (*p)[5], int r, int c)
    17. //使用数组指针的形式,传的二维数组,但是指向的第一行的一维数组的地址,一行有5个,
    18. //必须要写成一个一维数组的指针才可以
    19. {
    20.     int i = 0;
    21.     for (i = 0; i < 3; i++)
    22.     {
    23.         int j = 0;
    24.         for (j = 0; j < 5; j++)
    25.         {
    26.             printf("%d ", p[i][j]);
    27.         }
    28.         printf("\n");
    29.     }
    30. }
    31. int main()
    32. {
    33.     int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
    34.     print(arr, 3, 5);
    35.     return 0;
    36. }
    1. void print(int arr[], int sz)//形式参数是数组形式,因为数组传参传的就是一个地址,而不是创建一个新的数组
    2. {//写成数组形式的形参是因为方便新手理解
    3.     int i = 0;
    4.     for (i = 0; i < sz; i++)
    5.     {
    6.         printf("%d", arr[i]);
    7.     }
    8. }
    9. void print(int* arr, int sz)//形式参数是指针的形式
    10. {
    11.     int i = 0;
    12.     for (i = 0; i < sz; i++)
    13.     {
    14.         printf("%d", arr[i]);//arr[i] ===> *(arr+i)
    15.     }
    16. }
    17. int main()
    18. {
    19.     int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    20.     int sz = sizeof(arr) / sizeof(arr[0]);
    21.     print(arr, sz);//一维数组传参传的是数组名,而数组名也等于数组首元素地址
    22.     return 0;
    23. }
    24. int arr[5];//arr是一个能够存放5个整型数组数据的数组
    25. int* parr1[10];//parr是一个指针数组,数组大小为10个元素,类型为整型指针类型
    26. int(*parr2)[10];//parr2是一个数组指针,该指针是指向数组的,指向的数组有10个元素,每个元素的类型的是整型
    27. int(*parr3[10])[5];//parr3是一个数组,是存放数组指针的数组,这个数组有10个元素,存放的这个数组指针,指向的数组有5个元素,每个元素都是整型

    总结

    本文详细的的介绍了一部分的指针的知识,还有代码的理解帮助,并不是全部的知识,大家感觉有用处就好

  • 相关阅读:
    【蓝桥杯选拔赛真题04】C++计算24数字游戏 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析
    【PHP】进阶知识
    基础生态学名词解释
    常见算法-巴斯卡三角形(Pascal)
    【快乐离散数学】命题逻辑 | 复合命题 | 等价命题 | Propositional Logic | Propositional Equivalences
    K8S 安全机制
    SwaggerSpy:一款针对SwaggerHub的自动化OSINT安全工具
    【PHP设计模式03】抽象工厂模式
    车载充电器ROHS认证测试项目和周期
    淘宝API详情接口调用示例
  • 原文地址:https://blog.csdn.net/weixin_73466540/article/details/134032570