整数存储时是个循环
指针数组模拟实现二维数组
遍历
区别在于真正的二维数组元素间的地址是连续的,这里模拟实现的二维数组内部各一维数组间的地址是不连续的
二级指针指向的堆空间当成二维数组使用
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
//malloc的空间当成二维数组使用
int main()
{
先申请外层空间
//int** p = malloc(3 * sizeof(int*));
再申请内层空间
//int i = 0;
//for (i = 0; i < 3; i++)
//{
// p[i] = malloc(5 * sizeof(int));
//}
写数据到内层空间
//for (i = 0; i < 3; i++)
//{
// for (size_t j = 0; j < 5; j++)
// {
// p[i][j] = i + j;
// }
//}
从内层空间读数据
//for (size_t i = 0; i < 3; i++)
//{
// for (int j = 0; j < 5; j++)
// {
// printf("%d ", p[i][j]);
// }
// printf("\n");
//}
释放空间
先释放内层空间
//for (i = 0; i < 3; i++)
//{
// free(p[i]);
// p[i] = NULL;
//}
再释放外层空间
//free(p);
//p = NULL;
//先申请外层空间
char** p = (char**)malloc(3 * sizeof(char*));
//再申请内层空间
for (size_t i = 0; i < 3; i++)
{
p[i] = (char*)malloc(4 * sizeof(char));
}
//使用内层空间---写
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
p[i][j] = 'A' + i + j;
}
}
//使用内层空间---读
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
printf("%c ",p[i][j]);
}
printf("\n");
}
//释放空间时,应该先释放内层空间
for (size_t i = 0; i < 3; i++)
{
free(p[i]);
p[i] = NULL;
}
//再释放外层空间
free(p);
p = NULL;
return 0;
}
逻辑图
函数指针的作用 (回调函数)
函数指针用于函数作为参数传参,可以实现抽离不同函数内部相同的代码,单独封装成一个函数,防止代码冗余。例如:实现一个简易计算器
抽离冗余代码,进行封装
回调函数
qsort库函数的使用
qsort函数是一个能实现任意类型的任意排序的排序函数
输入和输出
把内存中的数据写到外部设备叫输出,把外部设备中的数据读到内存叫输入
观察发现printf/scanf和 fprintf/fscanf的区别就是参数少了个文件流FILE*sream,printf/scanf其实是把文件流FILE*sream默认成了stdout/stdin,省略了没写,例如fprintf(stdout,"%s",arr);等价于printf("%s",arr);,fscanf(stdin,"%s",arr);等价于scanf("%s",arr);
所以printf/scanf和 fprintf/fscanf的区别就是printf和scanf只适用于键盘屏幕的读写(标准输入输出流),而fprintf和fscanf适用于所有外部设备的读写,