目录
一,qsort函数
二,模仿qsort函数,利用冒泡排序排序任意类型的数据
三,sizeof和strlen对比
四,指针例题
1,指针+-整数
2,指针+-指针
3,指针复杂计算案例
一,qsort函数
qsort函数作为库函数可以直接用来排序任意类型的数组,只需要向里面传递合理的参数即可。
语法:
void qsort(void* base,size_t num,size_t size,int (*compar)(const void*,const void*));
分析:
1,base是一个指针,指向待排序的数组中的第一个元素
2,num是数组指向待排序的数组的元素个数
3,size是一个数组元素的大小
4,(*compar)(const void*,const void*)是一个函数指针,这个函数指针用来进行补充数组元素排序的规则
tmp_t函数的返回值有三种:当p1>p2时,返回正数,当p1<p2时,返回负数,当p1=p2时,返回0
p1和p2分别为数组的第一个元素和第二个元素的地址
写成p1减p2是升序,写成p2减p1是降序
strcmp()函数:用来比较字符串的大小,p1大于p2返回正数,p1小于p2返回负数,p1等于p2返回0
头文件为:include <string.h>
二,模仿qsort函数,利用冒泡排序排序任意类型的数据
分析:bubble_sort函数模仿qsort函数设置四个相同的形参。
冒泡排序的比较为了保持能通用任意数据利用基地址base转化为char*类型的指针,进行地址加减时,让步进单位变成一个字节。可以满足不同大小的数据类型的输入。
交换同理:为了满足任意类型数据的交换,设置一个函数,这个函数同样以一个字节为单位,利用循环(一次交换一个字节)和数据的大小width实现不同类型元素的交换。
对于不同类型的元素,冒泡排序是通用的,交换也是通用的。
不通用的是不同类型元素的比较方法。
三,sizeof和strlen对比
sizeof:
1,sizeof是操作符
2,sizeof计算操作数在内存中所占大小
3,sizeof不关注操作数中的具体内容
补充:sizeof括号中的表达式不进行计算
sizeof中的内容是地址就一定为4/8
例子:
原因:
一个文件test.c需要经过编译,链接,生成test.exe可执行程序,再进行运行。sizeof在编译时就需要进行计算。而表达式则需要在运行时才真正计算,此时表达式已经使用了。
strlen:
1,strlen是库函数,需要包含头文件#include <string.h>
2,strlen只能计算字符串的大小,即字符串中"\0"前的元素个数。
3,关注具体内容,如果没有“\0",就会越界访问继续寻找"\0",最后生成一个随机数。
运用例子:
1,
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
运行结果为:7
arr单独放在sizeof中表示的是整个数组的大小,算上“\0"总共7个字符。
2,
*arr和arr[1]分别为a和b,strlen遇到实际值时报错
只有是地址时,会顺着地址找”\0“,遇到时终止。
&arr +1表示跳过整个数组后的地址,没有”\0“,不知道多久遇到”\0“,故生成随机值。
&arr就表示arr整个数组的地址,取最小的就是第一个元素的地址。
3,
4,
四,指针例题
1,指针+-整数
分析:
根据结构体成员的内存对齐规则:结构体的大小为24个字节,同时十六进制的0x1其实就是十进制的1
加1的大小跟前面是什么类型的数据密切相关,展示:
1,p+1 : 0x100000+18(24转化为16进制的值)=0x100018
2,p+1: 0x100000(数值)+1 = 0x100001
3,p+1: 0x100000+4(int*的大小)=0x100004
2,指针+-指针
分析:
主要分析&p[4][2]的位置。
p是一个数组指针,指向含有四个元素的数组。
已知p=a;则p的首元素的地址即为a的首元素的地址。
p[4][2]=*(*(p+4)+2)
*(p+4)=a[3][1],因为p为指向一个有四个整形元素的数组的地址(数组指针),一次跳过四个元素,跳过16个就在a[3][1],此时在跳过2个整数,就到了a[3][3],a[3][3]和a[4][2]之间差了4个字节。
地址差计算:
&p[4][2] - &a[4][2]= (p + 4)[2] - (a + 4)[2]= (p + 4 * 4 + 2) - (a + 4 * 5 + 2)
= (p + 18) - (a + 22)= -4
故第二个值为-4,由于第一个值是地址,所以要将-4从补码转化为原码,再转化为16进制的地址。
-4的补码就是0xFFFFFFFC
3,指针复杂计算案例
分析:
一级指针表示首元素的地址例如:E N P F
二级指针表示地址的地址(即首元素地址的地址)
利用地址加上%s即可打印地址处存放的字符串
一级指针的加减跳过一个元素
二级指针的加减跳过一个地址的地址
三级指针的加减跳过一个二级指针的地址