*p操作内存

  • 在指针声明时,*号表示所声明的变量为指针
  • 在指针使用时,*号表示操作指针所指向的内存空间中的值
    • *p相当于通过地址(p变量的值)找到一块内存;然后操作内存
    • *p放在等号的左边赋值(给内存赋值)
    • *p放在等号的右边取值(从内存获取值)

指针变量和它指向的内存块是两个不同的概念

  • 含义1 给p赋值p=0x1111; 只会改变指针变量值,不会改变所指的内容;p = p +1; p++
  • 含义2 给_p赋值_p=’a’; 不会改变指针变量的值,只会改变所指的内存块的值
  • 含义3 =左边_p 表示给内存赋值, =右边_p 表示取值含义不同切结!
  • 含义4 =左边char *p
  • 含义5 保证所指的内存块能修改(常量是不能修改的)

示例

  1. void main()
  2. {
  3. int a = 10;
  4. char *p1 = 100;//指针变量 分配4个字节的内存 (给内存赋值)
  5. char ****p2 = 100;
  6. int *p3 = NULL;
  7. p3 = &a;
  8. *p3 = 20; //间接修改a的值 a=20
  9. // *就像一把钥匙 通过一个地址(&a),去改变变量的标示的空间
  10. int c = *p3;//取值 c=20
  11. printf("%d\n", c);
  12. printf("a:%d,p1:%d,p2:%d\n", sizeof(a), sizeof(p1), sizeof(p2));//4 4 4
  13. {
  14. char *p4 = NULL;
  15. p4 = (char *)mollac(100);
  16. p4 = (char *)mollac(200);
  17. /*
  18. p4在栈中 指向堆中 100的内存空间地址(0xbb11)
  19. 后又指向堆中 200的内存空间地址(0xcc11)
  20. 总结:不断的给指针变赋值,相当于不停的改变指针方向
  21. */
  22. }
  23. system("pause");
  24. return;
  25. }

铁律1-指针是一种数据类型 - 图1

  • *就像一把钥匙 通过一个地址(&a),去改变变量的标示的空间
  • 不断的给指针变赋值,相当于不停的改变指针方向(和所指向内存空间没有任何关系)

指针是一种数据类型,是指它指向的内存空间的数据类型

  • 含义1:指针步长(p++),根据所致内存空间的数据类型来确定
    p++ => (unsigned char )p+sizeof(a);
  • 结论:指针的步长,根据所指内存空间类型来定。
  1. /*
  2. int getAbc1(char *p1);
  3. int getAbc2(char **p2);
  4. int getAbc3(char ***p3);
  5. int getAbc4(char (*p4)[30]);
  6. int getAbc5(char p5[10][30]);
  7. 指针做函数参数,形参有多级指针的时候
  8. 站在编译器的角度,只需要分配4个字节的内存(32bit平台)
  9. 当我们使用内存的时候,我们才关心指针所指向的内存是一维的还是二维的
  10. 重点:
  11. 指针是一种数据类型,是指它指向的内存空间的数据类型
  12. */

指针也是一种变量,占有内存空间,用来保存内存地址

测试指针变量占有内存空间大小

  1. #include <stdio.h>
  2. // 引用
  3. int main12 () {
  4. char a = 1 ;
  5. short b = 2;
  6. int c = 3;
  7. long d = 4;
  8. float e = 1.2;
  9. double f = 2.3;
  10. printf("&a = %p\n", &a);
  11. printf("&b = %p\n", &b);
  12. printf("&c = %p\n", &c);
  13. printf("&d = %p\n", &d);
  14. printf("&e = %p\n", &e);
  15. printf("&f = %p\n", &f);
  16. // &a = 0028FEBF
  17. // &b = 0028FEBC
  18. // &c = 0028FEB8
  19. // &d = 0028FEB4
  20. // &e = 0028FEB0
  21. // &f = 0028FEA8
  22. printf("a = %d\n", *(&a));
  23. printf("b = %d\n", *(&b));
  24. printf("c = %d\n", *(&c));
  25. printf("d = %d\n", *(&d));
  26. printf("e = %f\n", *(&e));
  27. printf("f = %f\n", *(&f));
  28. // a = 1
  29. // b = 2
  30. // c = 3
  31. // d = 4
  32. // e = 1.200000
  33. // f = 2.300000
  34. printf("a = %d\n", *((char *)0x0028FEBF)); // (char *)0x0028FEBF == &a
  35. printf("b = %d\n", *((short *)0x0028FEBC));
  36. printf("c = %d\n", *((int *)0x0028FEB8));
  37. printf("d = %d\n", *((long *)0x0028FEB4));
  38. printf("e = %f\n", *((float *)0x0028FEB0)); // 从这里可以看出 &e 进行取地址,取出来的地址是有类型的
  39. printf("f = %f\n", *((double *)0x0028FEA8));
  40. // a = 1
  41. // b = 2
  42. // c = 3
  43. // d = 4
  44. // e = 1.200000
  45. // f = 2.300000
  46. return 0;
  47. }