• C语言基础-指针


    1.指针是什么?

    指针是内存中一个最小单元的编号,也就是地址

    平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

    总结:指针就是地址,口语中说的指针通常指的是指针变量

    1. // 指针是什么?
    2. // 1.指针是内存中一个最小单元的编号,也就是地址
    3. // 2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
    4. // 总结:指针就是地址,口语中说的指针通常指的是指针变量
    5. int main()
    6. {
    7. int a = 100; //在内存中开辟一块空间
    8. int * pa = &a; //pa是专门来存放地址(指针)的,pa在这里就被称为指针变量
    9. //这里我们对变量a,取出它的地址,可以使用&操作符
    10. //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个指针变量
    11. // int arr[10];
    12. // printf("%p\n",&a);
    13. printf("%p\n",pa);
    14. return 0;
    15. }

    2.指针和指针类型

    int* 的指针解引用访问4个字节

    char* 的指针解引用访问1个字节

    结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)

    int* 4个字节  char* 1个字节  short* 2个字节  float* 4个字节   double* 8个字节

    1. //指针类型的意义
    2. int main()
    3. {
    4. int a = 0x11223344; //0x开头是16进制数字
    5. //int * pa = &a;
    6. char * pa = &a;
    7. // int* 的指针解引用访问4个字节
    8. // char* 的指针解引用访问1个字节
    9. // 结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)
    10. *pa = 0;
    11. return 0;
    12. }
    13. //type * p *说明p是指针变量
    14. //1. p指向的对象的类型
    15. //2. p解引用的时候访问的对象大小是sizeof(type)
    16. int main()
    17. {
    18. int a = 0x11223344; //0x开头是16进制数字
    19. int* pa = &a;
    20. char* pc = &a;
    21. printf("%p\n",pa); //0x16d207388
    22. printf("%p\n",pc);//0x16d207388
    23. //int * 增加4个字节,char * 增加1个字节
    24. printf("%p\n",pa+1); //0x16d20738c
    25. printf("%p\n",pc+1);//0x16d207389
    26. //指针类型决定指针+1/-1操作时的步长
    27. //整形指针+1跳过4个字节
    28. //字符指针+1跳过1个字节
    29. return 0;
    30. }

    3.野指针

    1. //野指针
    2. // int main()
    3. // {
    4. // int a = 10;
    5. // int* pa = &a;
    6. // *pa = 20;
    7. // printf("%d\n",a);
    8. // return 0;
    9. // }
    10. //p是野指针 野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
    11. // int main()
    12. // {
    13. // int* p; //局部变量不初始化的时候,内容是随机值
    14. // *p = 20;
    15. // printf("%d\n",*p);
    16. // return 0;
    17. // }
    18. //指针越界访问
    19. // int main()
    20. // {
    21. // int arr[10] = {0};
    22. // int* p = arr;
    23. // int i = 0;
    24. // for(i = 0; i<= 11;i++)
    25. // {
    26. // //当指针指向的范围超出数组arr的范围时,p就是野指针
    27. // *(p++) = i;
    28. // }
    29. // return 0;
    30. // }
    31. //指针释放
    32. int* test()
    33. {
    34. int a = 110;
    35. return &a;
    36. }
    37. int main()
    38. {
    39. int* p = test();
    40. printf("%d\n",*p);
    41. return 0;
    42. }

    如何规避野指针:

    1指针初始化

    2小心指针越界

    3指针指向的空间释放,及时置NULL

    4避免返回局部变量的地址

    5指针使用之前检查有效性

    1. // 如何规避野指针:
    2. // 1指针初始化
    3. int main()
    4. {
    5. int a = 0;
    6. int* p = &a;
    7. int* ptr = NULL; //告诉你ptr是一个空指针,没有指向任何有效的空间,这个指针不能直接使用
    8. int* ptr2; //野指针
    9. if (ptr != NULL)
    10. {
    11. //使用
    12. }
    13. return 0;
    14. }
    15. // 2小心指针越界
    16. // 3指针指向的空间释放,及时置NULL
    17. // 4避免返回局部变量的地址
    18. // 5指针使用之前检查有效性

    4.指针运算

    指针+ - 整数

    1. //指针运算
    2. // int main()
    3. // {
    4. // int arr[10] = {0};
    5. // //不使用下标访问数组
    6. // int* p = &arr[0];
    7. // int i = 0;
    8. // int sz = sizeof(arr)/sizeof(arr[0]);
    9. // for (int i = 0; i < sz; i++)
    10. // {
    11. // *p = i;
    12. // p++; // p = p+1
    13. // }
    14. // p = arr;
    15. // for (i = 0; i < sz; i++)
    16. // {
    17. // printf("%d ",*(p+i)); // p+i
    18. // }
    19. // // for (i = 0; i < 10; i++)
    20. // // {
    21. // // printf("%d",arr[i]);
    22. // // }
    23. // return 0;
    24. // }
    25. //int arr[10];
    26. //int* p = arr;
    27. //*(p+i) == arr[i]
    28. //*(arr+i) == arr[i]
    29. //数组名是首元素的地址 -- 指针
    30. //arr[i] == *(arr+i) == *(i+arr) == i[arr]
    31. int main()
    32. {
    33. int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    34. int i = 0;
    35. int *p = arr;
    36. for(i = 0;i < 10; i++)
    37. {
    38. printf("%d ",i[arr]); //[]操作符
    39. printf("%d ",*(p+i)); //[]操作符
    40. }
    41. //arr[i] --> i[arr]
    42. return 0;
    43. }
    44. // int my_strlen(char* s)
    45. // {
    46. // int count = 0;
    47. // while (*s != '\0')
    48. // {
    49. // count++;
    50. // s++;
    51. // }
    52. // return count;
    53. // }
    54. //递归实现
    55. // int my_strlen(char* s)
    56. // {
    57. // if (*s == '\0')
    58. // {
    59. // return 0;
    60. // } else
    61. // {
    62. // return 1 + my_strlen(s + 1);
    63. // }
    64. // return 0;
    65. // }
    66. int my_strlen(char* s)
    67. {
    68. char* start = s;
    69. while (*s != '\0') //(*s)
    70. {
    71. s++;
    72. }
    73. // while (*s++); //err
    74. //while (*s++); return s -start-1; //true
    75. return s -start;
    76. }
    77. int main()
    78. {
    79. char arr[] = "abcdef"; // a b c d e f \0
    80. int len = my_strlen(arr);
    81. printf("%d\n",len);
    82. return 0;
    83. }

    5.指针和数组

    1. //指针和数组之间是什么关系呢?
    2. //指针变量就是指针变量,不是数组,指针变量的大小是4/8个字节,专门是用来存放地址的
    3. //数组就是数组,不是指针,数组一块连续的空间,可以存放一个或者多个类型相同的数据
    4. //指针和数组之间的关系:数组中,数组名其实是数组首元素的地址,数组名 == 地址 == 指针
    5. //当我们知道数组首元素的地址的时候,因为数组又是连续存放的,使用通过指针就可以遍历访问数组,数组是可以通过指针访问的
    6. // int main()
    7. // {
    8. // int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    9. // int i = 0;
    10. // int sz = sizeof(arr) / sizeof(arr[0]);
    11. // int* p = arr;
    12. // for(i = 0; i < sz; i++)
    13. // {
    14. // printf("%p == %p\n",p+i,&arr[i]);
    15. // }
    16. // return 0;
    17. // }
    18. // int main()
    19. // {
    20. // int a = 10;
    21. // int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的
    22. // int** pp = &p; //pp就是二级指针,二级指针变量就是用来存放一级指针变量的地址
    23. // *(*pp) = 100;
    24. // *p = 10;
    25. // int** * ppp = &pp;
    26. // //int* 是在说明pp指向的是int*类型的变量
    27. // printf("%d\n",a);
    28. // printf("%p\n",&a);
    29. // printf("%p\n",&p);
    30. // printf("%p\n",pp);
    31. // return 0;
    32. // }

    6.二级指针

    1. // int main()
    2. // {
    3. // int a = 10;
    4. // int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的
    5. // int** pp = &p; //pp就是二级指针,二级指针变量就是用来存放一级指针变量的地址
    6. // *(*pp) = 100;
    7. // *p = 10;
    8. // int** * ppp = &pp;
    9. // //int* 是在说明pp指向的是int*类型的变量
    10. // printf("%d\n",a);
    11. // printf("%p\n",&a);
    12. // printf("%p\n",&p);
    13. // printf("%p\n",pp);
    14. // return 0;
    15. // }
    16. int main()
    17. {
    18. char arr1[] = "abcdef";
    19. char arr2[] = "hello world";
    20. char arr3[] = "xiaofan";
    21. char* parr[] = {arr1,arr2,arr3};
    22. int i = 0;
    23. int sz = sizeof(parr)/sizeof(parr[0]);
    24. char** p = parr;
    25. for (i = 0;i
    26. {
    27. //printf("%s\n",parr[i]);
    28. printf("%s\n",*(p+i));
    29. }
    30. //**p = '1111';
    31. //printf("%s\n",parr[0]);
    32. return 0;
    33. }

    7.指针数组

    1. //指针数组
    2. //指针数组是指针还是数组 是数组,是存放指针的数组 数组我们已经知道整形数组,字符数组
    3. //整型数组 -存放整型的数组 字符数组 - 存放字符的数组 指针数组-存放指针(地址)的数组
    4. int main()
    5. {
    6. // char arr[] = "abcdef";
    7. // printf("%s\n",arr);
    8. int arr1[] = {1,2,3,4,5};
    9. int arr2[] = {2,3,4,5,6};
    10. int arr3[] = {3,4,5,6,7};
    11. //指针数组
    12. int* parr[] = {arr1, arr2, arr3};
    13. int i = 0;
    14. for(i = 0;i<3;i++)
    15. {
    16. int j = 0;
    17. for(j = 0;j <5;j++)
    18. {
    19. //printf("%d ",parr[i+j]);//err
    20. printf("%d ",*(parr[i]) + j);
    21. // printf("%d ",parr[i][j]);
    22. }
    23. printf("\n");
    24. }
    25. return 0;
    26. }

  • 相关阅读:
    tomcat9w无法启动
    Java现在还适合入门吗?
    MySQL常用指令
    运放:运放输入电压
    Vision Transformer学习
    抖音小程序开发教学系列(6)- 抖音小程序高级功能
    软考高级系统架构设计师系列论文二十三:论数据中心集中存储架构
    C++简单实现红黑树
    网络安全(黑客)自学
    Word控件Spire.Doc 【页面设置】教程(3):在 C#、VB.NET 中设置 Word 页边距
  • 原文地址:https://blog.csdn.net/qq_61658398/article/details/132962654