
1. 内存和地址*1内存电脑内存RAM就像一排连续的小房间。每个小房间大小固定1字节(8bit)。程序运行的时候变量、数组、字符串全都放在这些房间里程序关掉内存里的数据就清空。2地址每个字节小房间都有一个独一无二的门牌号这个门牌号就是内存地址。比如0x00010000是十六进制编号。• 一个地址对应1个字节。• 比如 int 占4字节它会占用连续4个房间变量的地址 这一块的第一个房间的门牌号。2. 指针变量和地址1地址内存里每1个字节都有唯一门牌号这个编号就是内存地址。• 变量在内存里会占用一块空间• 变量名取这个变量首地址这块空间第一个字节的门牌号。2指针变量普通变量存数值 指针变量专门用来存放地址门牌号。址3. 指针变量类型的意义指针的类型决定两件事①解引用的时候取多少字节的数据②指针±1的时候地址跳多少字节。例如• int *p指向intint占4字节 → p1地址 4• char *p指向charchar占1字节 → p1地址 1• double *p指向double8字节 → p1地址 8指针变量本身不管是什么类型存的都是内存地址单纯一个门牌号。在32位系统所有指针都是4字节64位系统所有指针都是8字节。✅ 指针本身大小和它是什么类型无关类型只规定“怎么解释这个地址”4. const修饰指针① const int *p; 【常量指针指向的内容不能改指针本身可以改】等价写法int const *p;• 被保护的*p指针指向的值• 允许p 可以改可以指向别的地址• 禁止*p xxx; 不能通过指针修改指向的数据② int *const p; 【指针常量指针本身不能改指向的内容可以改】• 被保护的p指针变量本身存的地址• 允许*p 可以修改内容• 禁止p 别的地址; 指针不能换指向对象总结const如果放在 * 的左边修饰的是指针指向的内容保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。• const如果放在 * 的右边修饰的是指针变量本身保证了指针变量的内容不能修改但是指针指向的内容可以通过指针改变。5. 指针运算1指针± 整数因为数组在内存中是连续存放的只要知道第⼀个元素的地址顺藤摸瓜就能找到后面的所有元素。#includestdio.h//指针- 整数intmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};int*parr[0];inti0;intszsizeof(arr)/sizeof(arr[0]);for(i0;isz;i){printf(%d ,*(pi));//pi 这⾥就是指针整数}return0;2指针-指针#includestdio.hintmy_strlen(char*s){char*ps;while(*p!\0)p;returnp-s;}intmain(){printf(%d\n,my_strlen(abc));return0;}3指针的关系运算#includestdio.hintmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};int*parr[0];intszsizeof(arr)/sizeof(arr[0]);while(parrsz)//指针的⼤⼩⽐较{printf(%d ,*p);p;}return0;}6.传值调用和传址调用例如写⼀个函数交换两个整型变量的值我们可能写出这样的代码#includestdio.hvoidSwap1(intx,inty){inttmpx;xy;ytmp;}intmain(){inta0;intb0;scanf(%d %d,a,b);printf(交换前a%d b%d\n,a,b);Swap1(a,b);printf(交换后a%d b%d\n,a,b);return0;}但没产生交换的效果这是因为实参传递给形参的时候形参会单独创建⼀份临时空间来接收实参对形参的修改不影响实参所以交换失败。这里我们需要传址调用传址调用可以让函数和主调函数之间建立真正的联系在函数内部可以修改主调函数中的变量所以未来函数中只是需要主调函数中的变量值来实现计算就可以采用传值调用。如果函数内部要修改主调函数中的变量的值就需要传址调用。#includestdio.hvoidSwap2(int*px,int*py){inttmp0;tmp*px;*px*py;*pytmp;}intmain(){inta0;intb0;scanf(%d %d,a,b);printf(交换前a%d b%d\n,a,b);Swap2(a,b);printf(交换后a%d b%d\n,a,b);return0;}