指针的本质:间接访问

【*】解引用取地址对应的值 【&】取地址运算符:取变量的地址

函数调用的本质

每个函数对于数据的存储都有一个栈空间;
程序的运行本质上就是把内存空间反复修改;
函数调用本质是值传递,也就是换汤不换药,商品发生了传递,而配方并不会因此而改变;

code

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. void change(int j);
  6. void change(int j) {
  7. j = 5;
  8. }
  9. int main() {
  10. int i = 10; /*括号内定义的变量:局部变量*/
  11. printf("before changing i = %d\n", i);
  12. change(i);
  13. printf("after changing i = %d\n", i);
  14. return 0;
  15. }
  1. 0x0078FBA8 0a 00 00 00 ....
  2. 0x0078FBAC cc cc cc cc ????
  3. 0x0078FBB0 d0 fb 78 00 ??x.
  4. 0x0078FBB4 b3 20 96 00 ? ?.
  5. 0x0078FAD4 0a 00 00 00 ....
  6. 0x0078FAD8 23 10 96 00 #.?.
  7. 0x0078FADC 23 10 96 00 #.?.
  8. 0x0078FAE0 00 f0 4c 00 .?L.

image.png

image.png

为什么要用指针传值?

仅传递值,相当于传递python当中的引用,无法对值进行实质性修改,必须传递内存地址,直接修改内存地址对应的数值,这样的修改才能有效;此操作类似于python当中的深拷贝,将内存地址拷贝过去,对拷贝变量的修改会同步到原数据;

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. void change(int *j);
  6. /*解引用运算符,负责解析内存地址对应的值*/
  7. void change(int *j) {
  8. *j = 5;
  9. }
  10. int main() {
  11. int i = 10; /*括号内定义的变量:局部变量*/
  12. printf("before changing i = %d\n", i);
  13. change(&i); /* 取地址运算符 */
  14. printf("after changing i = %d\n", i);
  15. return 0;
  16. }

image.png

指针的偏移

数据类型的划分

image.png

默认地址引起的赋值冲突

微软对变量赋予默认值 0xcccccccc,相当于关键字占用,不能再将其赋予给变量;
出现上述报错是因为该处内存不可读;内存也有三个权限:可读,可写,可执行;

image.png