指针的本质就是地址

  1. #include <stdio.h>
  2. // 指针
  3. int main()
  4. {
  5. int i = 5;
  6. // &是(引用)取地址 指针变量的初始化一定是某个变量取地址
  7. int *i_pointer = &i;
  8. // || *是解析地址 如果只是 i_pointer 就是其存的地址
  9. printf("%d\n", *i_pointer);
  10. return 0;
  11. }

指针的使用场景通常只有两个,即传递与偏移。

指针传递

  1. #include <stdio.h>
  2. void change(int *j) // j 形参 j=&i
  3. {
  4. *j = 5;
  5. }
  6. // 指针传递
  7. int main()
  8. {
  9. int i = 10; // i 局部变量
  10. printf("before change , i = %d\n", i);
  11. change(&i); //函数调用时,把&i称为实参
  12. printf("after change , i = %d\n", i);
  13. return 0;
  14. }

指针偏移

前面介绍了指针的传递。指针即地址,就像我们找到了-栋楼,这栋楼的楼号是B,那么往
前就是A,往后就是C,所以应用指针的另一个场景就是对其进行加减,但对指针进行乘除是没
有意义的,就像家庭地址乘以5没有意义那样。在工作中,我们把对指针的加减称为指针的偏移,
加就是向后偏移,减就是向前偏移。

  1. #include <stdio.h>
  2. // 指针偏移
  3. int main()
  4. {
  5. int a[5] = {1,
  6. 2,
  7. 3,
  8. 4,
  9. 5};
  10. int *p; //对一个指针变量进行取值,得到的类型是其基类型
  11. p = a;
  12. for (int i = 0; i < 5; i++)
  13. {
  14. /* 先偏移在取地址 */
  15. printf("*p = %d \n", *(p + i));
  16. }
  17. return 0;
  18. }

指针自增自减

  1. #include <stdio.h>
  2. // p[0] = *p
  3. // 指针自增
  4. int main()
  5. {
  6. int a[3] = {2, 5, 8};
  7. int *p;
  8. int j;
  9. p = a; // 让指针变量p,指向数组的开头
  10. // j = *p++;
  11. j = *p;
  12. p++;
  13. printf("a[0] =%d,j =%d,*p =%d\n", a[0], j, *p); // 2,2,5
  14. // j = p[0]++;
  15. j = *p;
  16. printf("之前的*p =%d\n", *p);
  17. printf("之前的a[1] =%d\n", a[1]);
  18. // *p++ 指的是这个空间向前加一位 (*p)++ == p[0]++这个地址里面的数加一
  19. *p++;
  20. printf("之后的*p =%d\n", *p);
  21. printf("之后的a[1] =%d\n", a[1]);
  22. printf("a[1] =%d,j =%d,*p =%d\n", a[1], j, *p); // 6,5,6
  23. return 0;
  24. }

指针与一维数组

一维 数组在函数调用进行传递时,它的长度子函数无法知道
数组名作为实参传递给子函数时,是弱化为指针的

  1. #include <stdio.h>
  2. void change(char *d)
  3. {
  4. *d = 'H';
  5. d[1] = 'E';
  6. // 等于上面的操作
  7. // *(d + 1) = 'E';
  8. *(d + 2) = 'L';
  9. }
  10. // 指针与一维数组
  11. int main()
  12. {
  13. char c[10] = "hello";
  14. change(c);
  15. puts(c);
  16. return 0;
  17. }

指针与动态内存申请

C语言的数组后会觉得数组长度固定很不方便,其实C语言的数组长度固定是因为其定义的整型、浮点型、字符型变量、数组变量都在栈空间中,而栈空间的大小在编译时是确定的。如果使用的空间大小不确定,那么就要使用堆空间

程序是放在磁盘上的有序的指令集合