当前位置: 首页 > news >正文

画流程图的网站模板网站可以优化吗

画流程图的网站,模板网站可以优化吗,做网站在厦门排前5名,室内设计联盟官网论坛文章目录数组指针/指针数组函数指针函数指针数组函数指针数组用途(转移表)回调函数qsort函数基于qsort改造冒泡排序源码数组指针/指针数组 int arr1[5] { 1,2,3,4,5 };int (*p1)[5] arr1; //p1是数组指针变量int* arr2[5] { 0 }; //arr2是指针数组指针数组是存放指… 文章目录数组指针/指针数组函数指针函数指针数组函数指针数组用途(转移表)回调函数qsort函数基于qsort改造冒泡排序源码数组指针/指针数组 int arr1[5] { 1,2,3,4,5 };int (*p1)[5] arr1; //p1是数组指针变量int* arr2[5] { 0 }; //arr2是指针数组指针数组是存放指针的数组本质是数组。 数组指针是指向数组的指针本质是指针。 数组指针类型(去掉变量名剩下的就是类型) int (*)[5] //数组指针类型函数指针 函数名本身就是函数指针。 int Add(int x, int y) {return x y; }int (*pf)(int, int) Add; //pf就是存放函数地址(指针)的变量函数指针变量函数指针类型和数组指针类型相似如下 int (*)(int, int) //函数指针类型通过函数指针调用函数 int x (*pf)(10, 20); printf(%d\n, x);因为函数名本身就是函数地址所以前面的Add 和 调用函数时的(*p) 中的取地址符和*不加也可以达到一样的效果。 函数指针数组 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; }int (*padd)(int, int) Add; int (*psub)(int, int) Sub; int (*pmul)(int, int) Mul; int (*pdiv)(int, int) Div; // 类比 int arr[5] int (*pfarr[4])(int, int) { padd ,psub,pmul,pdiv }; //下面这样这可以 int (*pfarr[4])(int, int) { Add, Sub, Mul, Div };上面的pfarr就是函数指针数组的变量名函数指针数组最好在函数指针变量的基础上改造得到也就是在函数指针变量的变量名后面加[ ]。 函数指针数组的理解可以类比普通的数组比如 int arr[5]一个存放5个整型变量的数组把它的变量名和中括号(arr[5])去掉剩余的就是数组存放变量的类型放在函数指针数组里也一样把pfarr[4]去掉剩余的int(*)(int, int)就是数组里存放的变量类型。 函数指针数组用途(转移表) 我们先来看下面实现的一个简易计算器 void menu() {printf(********************\n);printf(*** 1.add 2.sub ***\n);printf(*** 3.mul 4.div ***\n);printf(*** 0.exit ***\n);printf(********************\n); }int input 0; int a 0; int b 0; int r 0;do{menu();printf(请选择);scanf(%d, input);switch (input){case 1:printf(请输入两个操作数);scanf(%d %d, a, b);r Add(a, b);printf(r %d\n, r);break;case 2:printf(请输入两个操作数);scanf(%d %d, a, b);r Sub(a, b);printf(r %d\n, r);break;case 3:printf(请输入两个操作数);scanf(%d %d, a, b);r Mul(a, b);printf(r %d\n, r);break;case 4:printf(请输入两个操作数);scanf(%d %d, a, b);r Div(a, b);printf(r %d\n, r);break;case 0:printf(退出计算器\n);break;default:printf(选择错误重新选择\n);break;}} while (input);我们可以看到虽然可以实现计算器的功能但是代码非常冗长并且如果要增加更多运算函数的话还会增加更多的case想要简化代码就可以用函数指针数组把函数存放在函数指针数组里想要调用函数直接下标访问这个函数指针数组就行了这里我们想要让数组下标和菜单选择数字对应的话就需要在数组开头增加一个空指针让下标依次向后挪一位。 int (*fparr[])(int, int) {NULL,Add,Sub,Mul,Div};do{menu();printf(请选择);scanf(%d, input);if (input 0 input 4){printf(请输入两个操作数);scanf(%d %d, a, b);//fparr[input]是数组下标访问函数对象printf(r %d\n, fparr[input](a, b)); }else if (input 0){printf(退出计算器\n);break;}else{printf(选择错误重新选择\n);}}while(input);这样的方法又名转移表。 回调函数 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数时被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应。 补充至于回调函数为什么只能传函数指针类型而不能直接传递函数类型因为这是C语言语法特性决定的就算传递的是函数类型编译器也会将它隐式转化为函数指针类型。 下面我们举个例子 void calc(int (*pf)(int, int)) {int a 0;int b 0;int r 0;printf(请输入两个操作数);scanf(%d %d, a, b);r pf(a, b);printf(r %d\n, r); }int input 0;do{menu();printf(请选择);scanf(%d, input);switch (input){case 1:calc(Add);break;case 2:calc(Sub);break;case 3:calc(Mul);break;case 4:calc(Div);break;case 0:printf(退出计算器\n);break;default:printf(选择错误重新选择\n);break;}} while (input);之前我们实现的计算器switch-case部分非常冗余有很多重复的代码case1-4的四行代码只有调用运算函数那一行有区别但是我们直接把代码封装成函数那又需要写四个函数所以这里就可以用回调函数。 首先写一个回调函数calc参数是运算函数对应的函数指针所以每一个case只用去调用calc函数根据不同的函数指针参数再在calc函数体中调用对应的运算函数。 qsort函数 qsort函数是C语言的一个库函数它是基于快速排序算法实现的这个函数可以用来排序任意类型数据。 我们来分析一下它的四个参数 其中compar函数需要我们重点关注这是我们自己设计的比较函数C标准对这个函数是有约定的 compar函数返回值有三类当参数p1指向的元素大于参数p2指向的元素时返回大于0的数字当参数p1指向的元素等于于参数p2指向的元素时返回0参数p1指向的元素小于参数p2指向的元素时返回小于0的数字。 因为qsort默认是排升序的所以我们按照上面的规定实现比较函数传给qsort后最后结果为升序如果要排降序就需要实现比较函数时把大小于号反号。 下面我们就来使用一下qsort比较函数需要我们自己实现 int cmp_int(const void* e1, const void* e2) {//e1 e2 是void*需要强制类型转换后才能使用(解引用)return *(int*)e1 - *(int*)e2; }void test02() {int arr[] { 4, 1, 2, 3, 6, 8, 7 };size_t sz sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);for (int i 0; i sizeof(arr) / sizeof(arr[0]); i){printf(%d , arr[i]);} }比较结构体类型数据也是可以的 typedef struct stu {char name[20];size_t age; }stu;cmp_struct_by_name(const void* e1, const void* e2) {return strcmp(((stu*)e1)-name, ((stu*)e2)-name); }cmp_struct_by_age(const void* e1, const void* e2) {return ((stu*)e1)-age - ((stu*)e2)-age; }void test03() {stu arr[] { {jiyi, 7}, {xiaoba, 8}, {wusaqi, 6}, };size_t sz sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_struct_by_age); }按名字比较时需要调用strcmp函数我们查文档可以看到strcmp函数的返回值正好和我们要实现的比较函数逻辑一致所以比较函数直接返回strcmp函数的返回值就行了。 基于qsort改造冒泡排序 我们以前实现的冒泡排序只能排整型数据我们想让它适配更多类型的数据就需要对它进行改造这里模拟qsort的方式对我们自己的冒泡排序进行改造我们先分析需要改造哪些地方 一、首先是参数我们要比较不同类型数据就需要按照qsort的参数实现方式进行传递。 第一个参数传递数组首元素的地址有了地址才能知道待排序数据在哪里和第一个元素的地址方便以第一个元素的地址为基准指针加数字访问到数组后面的元素(要配合第三个参数使用因为第一个参数的类型的void*无法直接加减数字操作也无法确定强制类型转换的类型)。 第二个参数传递数组的元素个数用于确定循环躺数。 第三个参数传递单个元素的单位大小因为无法直接传递参数类型所以传递单个元素的单位大小来间接确定元素类型。因为首元素地址是void*无法直接以首元素地址为基准指针加数字访问到数组后面的元素这里有一个思路就是将首元素地址强转成char*,用它加单位数乘以第三个参数大小就可以访问到单位位置的元素比如(int*)base j * (width) 就可以访问到指向int数组的第j个元素的指针然后再把指针作为参数传给对应的比较函数在比较函数内部再对指针解引用访问数据大小并比较。 第四个参数是我们自己实现的比较函数。 二、然后是比较函数部分传递我们自己实现的比较函数。 三、最后是swap因为不知道数据的类型所以不能直接交换在前面参数部分已经将首元素指针类型强转成了char*不如将计就计在交换部分还是以char类型来交换不管你的数据类型大小有多少字节以char类型形式一个字节一个字节的交换一共交换width次。 int cmp_int(const void* e1, const void* e2) {//e1 e2 是void*需要强制类型转换后才能使用 return *(int*)e1 - *(int*)e2; }swap(char* p1, char* p2, int width) {for (width; width 0; width--){char tmp *p1;*p1 *p2;*p2 tmp;p1;p2;} }Bubble_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2)) {int flag 1; //默认有序for (int i 0; i sz - 1; i) //躺数{for (int j 0; j sz - 1 - i; j){//(char*)arr j * widthif (cmp((char*)base j * width, (char*)base (j 1) * width) 0){swap((char*)base j * width, (char*)base (j 1) * width, width);flag 0;}}if (flag 1)break;} }print(int* arr , int sz) {for (int i 0; i sz; i){printf(%d , arr[i]);}printf(\n); }void test04() {int arr[] { 4, 1, 2, 3, 6, 8, 7 };size_t sz sizeof(arr) / sizeof(arr[0]);Bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);print(arr, sz); }源码 p1: #include stdio.hint 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 test01() {int arr1[5] { 1,2,3,4,5 };int (*p1)[5] arr1; //p1是数组指针变量//int (*)[5] //数组指针类型int* arr2[5] { 0 }; //arr2是指针数组int (*pf)(int, int) Add; //pf就是存放函数地址(指针)的变量函数指针变量//int (*)(int, int) //函数指针类型int x (*pf)(10, 20);printf(%d\n, x); }void test02() {int (*padd)(int, int) Add;int (*psub)(int, int) Sub;int (*pmul)(int, int) Mul;int (*pdiv)(int, int) Div;// 类比 int arr[5]int (*pfarr[4])(int, int) { Add, Sub, Mul, Div }; }void menu() {printf(********************\n);printf(*** 1.add 2.sub ***\n);printf(*** 3.mul 4.div ***\n);printf(*** 0.exit ***\n);printf(********************\n); }void test03() {int input 0;int a 0;int b 0;int r 0;do{menu();printf(请选择);scanf(%d, input);switch(input){case 1:printf(请输入两个操作数);scanf(%d %d, a, b);r Add(a, b);printf(r %d\n, r);break;case 2:printf(请输入两个操作数);scanf(%d %d, a, b);r Sub(a, b);printf(r %d\n, r);break;case 3:printf(请输入两个操作数);scanf(%d %d, a, b);r Mul(a, b);printf(r %d\n, r);break;case 4:printf(请输入两个操作数);scanf(%d %d, a, b);r Div(a, b);printf(r %d\n, r);break;case 0:printf(退出计算器\n);break;default:printf(选择错误重新选择\n);break;}} while (input); }void test04() {int input 0;int a 0;int b 0;int r 0;int (*fparr[])(int, int) {NULL,Add,Sub,Mul,Div};do{menu();printf(请选择);scanf(%d, input);if (input 0 input 4){printf(请输入两个操作数);scanf(%d %d, a, b);printf(r %d\n, fparr[input](a, b));}else if (input 0){printf(退出计算器\n);break;}else{printf(选择错误重新选择\n);}}while(input);//do//{// menu();// printf(请选择);// scanf(%d, input);// switch (input)// {// case 1:// printf(请输入两个操作数);// scanf(%d %d, a, b);// r Add(a, b);// printf(r %d\n, r);// break;// case 2:// printf(请输入两个操作数);// scanf(%d %d, a, b);// r Sub(a, b);// printf(r %d\n, r);// break;// case 3:// printf(请输入两个操作数);// scanf(%d %d, a, b);// r Mul(a, b);// printf(r %d\n, r);// break;// case 4:// printf(请输入两个操作数);// scanf(%d %d, a, b);// r Div(a, b);// printf(r %d\n, r);// break;// case 0:// printf(退出计算器\n);// break;// default:// printf(选择错误重新选择\n);// break;// }//} while (input); }void calc(int (*pf)(int, int)) {int a 0;int b 0;int r 0;printf(请输入两个操作数);scanf(%d %d, a, b);r pf(a, b);printf(r %d\n, r); }void test05() {int input 0;do{menu();printf(请选择);scanf(%d, input);switch (input){case 1:calc(Add);break;case 2:calc(Sub);break;case 3:calc(Mul);break;case 4:calc(Div);break;case 0:printf(退出计算器\n);break;default:printf(选择错误重新选择\n);break;}} while (input); }int main() {//test01();//test02();//test03();//test04();test05();return 0; }p2: #include stdlib.h #include stdio.h #include string.h//Bubble_sort(int arr[], int sz) //{ // int flag 1; //默认有序 // for (int i 0; i sz - 1; i) //躺数 // { // for (int j 0; j sz - 1 - i; j) // { // if (arr[j] arr[j 1]) // { // int tmp arr[j]; // arr[j] arr[j 1]; // arr[j 1] tmp; // flag 0; // } // // } // if (flag 1) // break; // } //} //test01() //{ // int arr[] { 4, 1, 2, 3, 6, 8, 7 }; // Bubble_sort(arr, 7); // for (int i 0; i sizeof(arr) / sizeof(arr[0]); i) // { // printf(%d , arr[i]); // } //}int cmp_int(const void* e1, const void* e2) {//e1 e2 是void*需要强制类型转换后才能使用 return *(int*)e1 - *(int*)e2; }//print(int* arr) //{ // for (int i 0; i sizeof(arr) / sizeof(arr[0]); i) // { // printf(%d , arr[i]); // } //}//void test02() //{ // int arr[] { 4, 1, 2, 3, 6, 8, 7 }; // size_t sz sizeof(arr) / sizeof(arr[0]); // qsort(arr, sz, sizeof(arr[0]), cmp_int); // // for (int i 0; i sizeof(arr) / sizeof(arr[0]); i) // { // printf(%d , arr[i]); // } //}typedef struct stu {char name[20];size_t age; }stu;cmp_struct_by_name(const void* e1, const void* e2) {return strcmp(((stu*)e1)-name, ((stu*)e2)-name); }cmp_struct_by_age(const void* e1, const void* e2) {return ((stu*)e1)-age - ((stu*)e2)-age; }//void test03() //{ // stu arr[] { {jiyi, 7}, {xiaoba, 8}, {wusaqi, 6}, }; // size_t sz sizeof(arr) / sizeof(arr[0]); // qsort(arr, sz, sizeof(arr[0]), cmp_struct_by_age); //}swap(char* p1, char* p2, int width) {for (width; width 0; width--){char tmp *p1;*p1 *p2;*p2 tmp;p1;p2;} }Bubble_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2)) {int flag 1; //默认有序for (int i 0; i sz - 1; i) //躺数{for (int j 0; j sz - 1 - i; j){//(char*)arr j * widthif (cmp((char*)base j * width, (char*)base (j 1) * width) 0){swap((char*)base j * width, (char*)base (j 1) * width, width);flag 0;}}if (flag 1)break;} }//void test_func(void* p1) //{ // p1[1]; //}print(int* arr , int sz) {for (int i 0; i sz; i){printf(%d , arr[i]);}printf(\n); }void test04() {int arr[] { 4, 1, 2, 3, 6, 8, 7 };size_t sz sizeof(arr) / sizeof(arr[0]);Bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);print(arr, sz); }int main() {//test01();//test02();//test03();test04();return 0; }以上就是小编分享的全部内容了如果觉得不错还请留下免费的关注和收藏 如果有建议欢迎通过评论区或私信留言感谢您的大力支持。 一键三连好运连连哦~~
http://www.zqtcl.cn/news/920189/

相关文章:

  • 网络营销是营销的网络化吗广州推广seo
  • 茌平做网站推广网站刷链接怎么做的
  • 东莞网站优化推广Wordpress的根目录在哪
  • 备案的网站建设书是什么意思跨境电商代运营公司十强
  • 网站建设的功能要求wordpress typo3
  • 深圳网站平台前程无忧招聘网
  • 个人业余做网站怎么弄wordpress子主题修改
  • 深圳营销型网站建设优化做虚拟币网站需要什么手续
  • 青海市建设局网站西安网站seo推广
  • 广元做网站的公司合肥市建设网
  • 如何做网站不被查如何做网站内部优化
  • 网站建设用什么框架好做网站需要用到哪些开发软件
  • 网站建设工程师待遇wordpress 工具插件
  • 网站怎样做反向链接中国新闻社邮箱
  • 专业的外贸网站建设wordpress后台编辑
  • 德清建设银行网站2016wordpress淘宝客程序
  • 网站建设包括两个方面专业网站设计企业
  • dnf可以去哪个网站做代练导购网站 模板
  • 苏州网站开发培训深圳福田区口岸社区
  • 信息网站开发网络公司jsp实战网站开发视频
  • 做 理财网站深圳网站快速优化公司
  • 公司网站建设方案江门建设建筑网站
  • 网站是生成静态好还是动态好怎么找到域名做的那个网站
  • 婚纱网站页面设计上海商地网站建设公司
  • 模板手机网站建设多少钱百度搜索词排名
  • 怎么学做网站住房和城乡建设部网站一级建造师
  • 政务公开网惠州seo推广公司
  • 建设英文商城网站网站开发工具选择
  • 沈阳市浑南区城乡建设局网站淄博哪里有网站建设平台
  • 做不锈钢管网站口碑好的定制网站建设提供商