一:内存和地址
1.常见单位:
bit---比特位
byte---比特 1byte=8bit
KB 1KB=1024byte
MB 1MB=1024KB
GB 1GB=1024MB
TB 1TB=1024GB
PB 1PB=1024TB
2.计算机内存(图示)
内存单元的编号==地址==指针
3.编址的理解(图示)
地址信息被下达给内存,在内存上就可以找到该地址对应的数据,将数据通过数据总线传入CPU内寄存器。
二:指针变量和地址
1.取地址操作符&
设置变量并赋值,就是向内存申请空间存放数值
2.解引用操作符*
其作用是通过指针变量中储存的变量的地址找到变量,改变变量的值
3.指针变量的大小
指针变量的大小取决于一个地址的存放需要多大的空间;
指针变量的大小和类型无关,只要是指针类型的变量,大小都是相同的;
32位平台下,地址是32个比特位,指针变量大小是4个字节
64位平台下,地址是64个比特位,指针变量大小是8个字节
三:指针变量类型的意义
(一)意义
指针类型决定了对指针解引用的时候一次能操作几个字节;
*p将四个字节全部改为0:
char* p将第一个字节改为0:
(二)字符指针变量(char*)
1.字符指针变量的使用方式
2.举例(图示)
解析(图示):
(三)数组指针变量
1.数组指针变量是——存放数组的地址,指向数组的指针变量
使用举例:
2.初始化
(四)函数指针变量
1.创建以及使用
函数指针变量是用来存放函数的地址的
2.关键字typedef
(1)作用:用于类型重命名,将复杂类型简单化
(2)格式:对于数组指针和函数指针,新的类型名必须在*右边
eg.数组指针:typedef int(* parr_t)[5];
eg.函数指针:typedef void(* pfun_t)(int);
(五)void*指针
1.可以用来接收任意类型地址;但无法直接进行指针的+-整数运算和解引用的运算
(1)接受地址(图示)
(2)无法直接进行指针运算(图示)
2.作用:一般用在函数参数部分 ,用来接收不同类型数据的地址;这样的设计可以实现泛型编程的效果,使得一个函数来处理多种类型的数据
(六)指针+-整数
指针+-整数后的变化(向前/向后走的距离)取决于指针变量的类型
四:const修饰指针
1.const修饰变量
2.const修饰指针变量
(1)const放在*左边,限制的是*p,意思是:不能通过指针变量p修改p指向的空间的内容;但是p是不受限制的
(2)const放在*右边,限制的是p,意思是:p不能被修改,不能指向其他变量;但是*p不受限制,可以通过p修改指向对象的内容
五:指针运算
1.指针+-整数(和二.3指针变量的大小联系起来)
2.指针-指针
前提条件:两个指针指向同一块空间;
指针-指针的绝对值的数值表示指针和指针之间的元素个数;
六:野指针
1.概念:野指针就是指针指向的位置是不可知的/随机的/不正确的/没有明确限制的
2.成因:
(1)指针未初始化
(2)指针越界访问(大多出现在数组中)
(3)指针指向的空间释放(大多出现在函数中)
3.如何规避:
(1)指针初始化
明确知道就直接赋值地址,eg:int a=10;int* p=&a;
不知道,可以给指针赋值NULL,eg:int* p=NULL;
(2)小心指针越界
(3)指针变量不再使用时,及时置NULL;指针使用前检查其有效性
(4)避免返回局部变量的地址
七:assert断言
1.需要包含头文件assert.h
2.使用方法:
2.使用assert的好处:
(1)能自动标识文件和出错的行号
(2)有一种无需更改代码就能使用或者不使用assert()的机制
——#defineNDEBUG
#include<assert.h>
可以通过注释定义的宏来重新使用assert断言
八:指针的使用和传址调用
1.指针的使用
举例:模拟strlen的函数的实现
2.传值调用和传址调用
举例:交换两个变量的值
九:数组名的理解
1.数组名是数组首元素的地址
2.sizeof(数组名)
这里的数组名表示整个数组,计算的是数组的大小,单位是字节
3.&数组名
这里的数组名表示整个数组,取出的是整个数组的地址(与数组首元素的地址不同)
十:使用指针访问数组
举例:使用指针打印数组
十一:数组传参的本质
(一)一维数组传参本质
一维数组传参实际上传的是数组首元素的地址
(二)二维数组传参本质
二维数组传参实际上传的是第一行这个一维数组的地址(二维数组可以看是一维数组的数组)
十二:冒泡排序
1.思想:相邻的两个元素比较,不满足顺序就交换
2.代码实现:
不足:只能排序整形数据
十三:二级指针
1.二级指针是用来存放一级指针变量的地址的
2.使用举例:
十四:指针数组
(一)指针数组
1.指针数组是存放指针的数组,其内每个元素都是用来存放地址的
int* arr[4]
2.指针数组模拟二维数组
(二)函数指针数组
1.用途:作为转移表
2.其中,被调用的Add函数,Sub函数,Mul函数,Div函数都是回调函数(把函数的地址作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数)
十五:qsort使用举例
1.格式
2.使用举例
(1)完成整形数据的排序
(2)完成结构体数据的排序
十六:qsort函数的模拟实现
使用回调函数,采用冒泡排序的方式
十七:sizeof和strlen的对比
(1)sizeof
(2)strlen