网站的域名和空间,wordpress 首页多栏,ps做网站尺寸多少像素,深圳营销型网站seo目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.二级指针5.指针数组6.字符指针变量7.数组指针变量8.二维数组传参的本质9.函数指针变量10.函数指针数组11.回调函数12.qsort函数13.使用回调函数模拟实现qsort函数 1.数组名的理解
int main() {int arr[] { 1,2,3… 目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.二级指针5.指针数组6.字符指针变量7.数组指针变量8.二维数组传参的本质9.函数指针变量10.函数指针数组11.回调函数12.qsort函数13.使用回调函数模拟实现qsort函数 1.数组名的理解
int main() {int arr[] { 1,2,3 };printf(%p\n, arr[0]);printf(%p\n, arr);return 0;
}从结果可以看出arr[0] arr这是用为数组名就是地址而且是首元素的地址 但是arr作为数组名在两种情况下不表示首元素的地址
sizeof数组名sizeof中单独存放数组名表示求整个数组的大小单位是字节arrarr是后面直接加上一个数组名它表示整个数组的地址。arr在数值上可能与arr[0]相同但是本质上是不一样的即arr[0] arr arr 除此之外数组名都表示首元素的地址。 其实arr与arr的区别不在于直接打印的数值上而在于运算上
int main() {int arr[] { 1,2,3 };printf(%p\n, arr[0]);printf(%p\n, arr[0]1);printf(%p\n, arr);printf(%p\n, arr1);printf(%p\n, arr);printf(%p\n, arr1);return 0;
}可以看出arr和arr[0]加一的结果都是跳过4个字节而arr则跳过12个字节E8-F4 (15 * 16 ^ 1 4 * 16 ^ 0- ( 14*16^1 8 *16 ^0) 12). arr表示整个数组加一表示跳过整个数组数组一共3个int类型的数据所以一次跳过12个字节。
2.使用指针访问数组
数组可以使用下标引用操作符来访问比如
int ret arr[9];既然数组名相当于地址那么还可以这样访问
int* p arr[9];
int ret *p;3.一维数组传参的本质
以前将数组作为参数传递给函数时需要将数组的数据个数一起传递给函数那么不传递数据个数可以吗
void test(int arr[]) {int sz2 sizeof(arr) / sizeof(arr[0]);printf(sz1 %d\n, sz2);
}
int main() {int arr[] {1,2,3,4,5};int sz1 sizeof(arr) / sizeof(arr[0]);printf(sz1 %d\n, sz1);test(arr);return 0;
}从结果来看是不行的 其实将数组作为参数是将数组的首元素的地址作为参数传递给函数 所以在函数内部使用sizeofarr实际上计算的是一个地址的大小。正因为参数部分的本质是指针所以不能不传数据个数。
4.二级指针
指针变量也是变量是变量就有地址所以二级指针是用来存放一级指针变量的地址的 画图说明 对于二级指针的运算
*ppa通过对ppa中的地址解引用找到的是pa*ppa访问的就是p**ppa先对ppa解引用得到pa然后对pa解引用得到a
5.指针数组
存放整型的数组叫做整型数组 存放字符的数组叫做字符数组 那么存放指针的数组就叫做指针数组 6.字符指针变量
在指针的类型中有一种指针类型叫做字符指针char* 还有一种使用方法
int main() {const char* p abcdef;printf(%s\n, p);return 0;
}这种表示方法相当于将字符串看作为一个字符数组指针变量p存放的不是字符串而是首字符’a‘的地址。 如果两个指针指向同一个字符串那么不会开辟两个空间来存放也就是说两个指针指向的是同一个内存
7.数组指针变量
存放整型数据地址的指针叫做整型指针 存放字符型数据的指针叫做字符指针 那么存放数组的地址的指针叫做数组指针
指针数组是数组而数组指针是变量
int (*P)[5];p先于*结合说明p是一个指针再于【】和 int结合说明他是一个数组指针数组元素类型是int。
数组自指针的初始化
int main() {int arr[10] { 0 };int(*p)[10] arr;return 0;
}arr p
8.二维数组传参的本质
当我们将二位数组作为参数传递给函数时其实传递的是第一行的地址不是第一个元素的地址
void test(int(*p)[3], int r, int c) {for (int i 0; i r; i) {for (int j 0; j c; j) {printf(%d , *(*(p i) j));}printf(\n);}
}
int main() {int arr[2][3] { {1,2,3},{2,3,4} };test(arr, 2, 3);return 0;
}因为传递的是第一行元素的地址那么该地址就该用函数指针来接收。
9.函数指针变量
函数也有地址那么该地址就可以使用指针变量来接受那么该指针变量就是函数指针变量。
int (*p)(int, int);可以看出函数名就是函数的地址也可以使用函数名来获得函数的地址。 要将函数的地址存放起来就可以使用函数指针变量 可以使用函数指针变量来调用函数
void test() {printf(haha\n);
}
int main() {int(*p)() test;p();return 0;
}10.函数指针数组
函数指针是用来存放函数的地址的那么有很多函数要将它们的地址存放在一起那么就可以使用函数指针数组。
int (*p[10])(int, int);p先于【】结合说明是一个数组那么数组的内容就是int (*)().
int Add(int x, int y) {return x y;
}
int Sub(int x, int y) {return x - y;
}
int Mul(int x, int y) {return x * y;
}
int Div(int x, int y) {return x / y;
}
void Menu() {printf(**************************\n);printf(*****1.加法 2.减法*****\n);printf(*****3.乘法 4.除法*****\n);printf(*****0.退出 *****\n);printf(**************************\n);
}
int main() {int n 0;int num1 0, num2 0;int(*p[5])(int, int) { 0,Add,Sub,Mul,Div };do {Menu();printf(请输入要选择的功能);scanf(%d, n);if (n 1 n 4) {printf(\n请输入两个数用于计算);scanf(%d%d, num1, num2);printf(\n计算结果%d\n, (*p[n])(num1, num2));}else if (n 0) {printf(已退出\n);break;}else {printf(选择错误重新选择);}} while (n);return 0;
}
这个代码实现了一个简单的计算器。 int( * p[5])(int, int) { 0,Add,Sub,Mul,Div }; 这段代码就是将四个函数的地址放在一个函数指针数组里面 ( * p[n])(num1, num2) 这段代码函数指针数组来调用函数n表示想调用哪个函数num1和num2就是传递给函数的参数
11.回调函数
回调函数就是一个通过函数指针调用的函数 如果将函数的指针作为一个参数传递给另一个函数但这个指针被用来调用其所指的函数时被调用的函数就是回调函数。
void test2() {printf(hahaha\n);
}
void test1(void (*test2)()) {printf(haha\n);test2();
}
int main() {test1(test2);return 0;
}在main函数中将test2的地址传递给test1然后test1用函数指针变量来接收然后调用test2函数那么test2函数就是回调函数。
12.qsort函数
qsort函数的功能是将任意类型的数据排列底层原理是快速排序。
#includestdlib.hvoid com_arr(const void* p1, const void* p2) {return *(int*)p1 - *(int*)p2;
}void print(int arr[], int sz) {for (int i 0; i sz; i) {printf(%d , arr[i]);}printf(\n);
}
int main() {int arr[] { 5,2,1,7,3,4,6,14,8 };int sz sizeof(arr) / sizeof(arr[0]);print(arr, sz);qsort(arr, sz, 4, com_arr);print(arr, sz);return 0;
}qsort函数需要4个参数第一个参数是数组首元素的地址第二个参数是数组中元素的个数第三个参数是数组中数据类型的大小第四个参数是一个函数作用是实现排序这种数据的方法。 在上述代码中排序整型数组中的数据那么第四个参数就可以让两个整数相减返回负数表示第一个元素小于第二个元素反之大于。
13.使用回调函数模拟实现qsort函数
我们可以采用冒泡排序的方式来实现qsort函数
int Method(const void* p1, const void* p2) {//用以判断两个数时候该交换return (*(int*)p1 - *(int*)p2);
}void Swap(void* p1, void* p2 ,int sz) {for (int i 0; i sz; i) {char tmp *((char*)p1 i);*((char*)p1 i) *((char*)p2 i);*((char*)p2 i) tmp;}
}
void Maopao(void* arr, int sz, size_t num, int (*method)(void*, void*)) {for (int i 0; i sz - 1; i) {for (int j 0; j sz - 1 - i; j) {if (method((char*)arr j * num, (char*)arr (j1) * num) 0){Swap((char*)arr j * num, (char*)arr (j1) * num, num);}}}
}
int main() {int arr[] { 4,2,6,1,7,5,9,8 };int sz sizeof(arr) / sizeof(arr[0]);for (int i 0; i sz; i) {printf(%d , arr[i]);}printf(\n);Maopao(arr, sz, sizeof(arr[0]), Method);for (int i 0; i sz; i) {printf(%d , arr[i]);}return 0;
}/考研势在必行/