之前在学校学C语言指针部分的时候,看到了这样一道题:

编写程序 ,程序实现的功能是:假设有 20 个英文姓名,将姓名按升序排序。

最开始那会儿还没有什么思路,在网上搜索了一下相同题的解题思路,只看到了有个百度知道里的回答。回答里的思路很好,不过感觉上和指针关系不是很大。因此博主决定自行尝试编写本程序。

首先整理一下思路,将姓名由小到大排序,还要用上指针,我们可以:

  1. 设置一个二维数组,让二维数组的每行空间存储一个名字。
  2. 设置一个数组指针,提前将名字定义在数组指针内部。
  3. 设置一个结构体存放名字。

之后设置一个函数,使用冒泡法,将名字按字母大小重新排序。

前面列出的3个分支方法其实都只是在收集名字上有些许差别。本文重点分析第一种思路,后两种简单介绍。

目录

二维数组法

1. 纠正理解strcpy

2. 冒泡法强化记忆

数组指针法

结构体法

1. qsort函数

(1)功能

(2)函数声明

without qsort


二维数组法

第一种思路的主函数如下:

int main()
{int i = 0;char name[20][10];printf("请输入20个英文名字:\n");for (i = 0; i < 20; i++){scanf("%s", name[i]);}my_bubble(name);printf("\n******************\n//排序后的结果为//\n");for (i = 0; i < 20; i++){printf("%s\t", name[i]);}printf("\n******************\n");return 0;
}

这里二维数组name在输入输出时使用的name[i],意思是第i行上name数组里的数据。比如说用户输入了“Tom \n Peter \n”,那么在name数组里前两行存储的就是

  • “         T        o        m        \0        \0        \0        \0        \0        \0        \0 "
  • "         P        e        t          e          r         \0        \0        \0        \0        \0 "

冒泡法函数如下:

void my_bubble(char name[][10])
{int i = 0;int j = 0;char tmp[20] = { 0 };//char* p = tmp;//_!通过每次循环最后指针指向NULL,实现内存清空for (i = 0; i < 20; i++)//循环的总次数{for (j = 0; j < (19 - i); j++)//每次循环要比较的元素数量{if (strcmp(name[j], name[j+1])== 1)//交换{strcpy(tmp, name[j]);strcpy(name[j], name[j + 1]);strcpy(name[j + 1], tmp);//p = NULL;//_!}}}
}

1. 纠正理解strcpy

这段里我保留下的//_!两排注释主要是记录当时自己的错误理解(那两段注释是不对的),纠正自己之前对strcpy的一些误解。

之前已经知道strcpy具有溢出隐患,曾经以为strcpy是通过将后一段字符串直接挤在前一段字符串开头实现的。但实际上,strcpy是通过将后一段字符串覆盖前一段字符串数据实现的。

举个例子说明下我的错误理解和实际情况:

char a[20] = "umbrella";char b[5] = "rain";strcpy(a, b);puts(a);

我理解在strcpy后,a数组里的情况是:r a i n \n u m b r e l l a \n

而事实上,strcpy会覆盖原数组的数据:r a i n \n l l a \n (umbre被覆盖掉了)

再说strcpy的隐患是什么。就原先代码举例,当我们想把a的字符串覆盖在b里时,由于b里只有5个char的内存,分配的内存不足以存放”umbrella"字符串,所以存在溢出问题。

//这段代码最后会崩溃
char a[20] = "umbrella";char b[5] = "rain";strcpy(b, a);puts(b);return 0;

2. 冒泡法强化记忆

冒泡法很常见,理解了就能用。

for( i = 0; i <sz ; i++)

// 确定了比较次数,这里要遍历数组里的所有元素,比较次数就是所有元素的总数

for( j = 0; j< (sz - 1 - i) ; j++)

//确定每次要拿来比较的两个数,不断一次3左右两个比较

{

if (a[ j ] > a[ j + 1] )

//这里使用升序,要从小到大

设置一个中间变量,交换两个元素。

}


数组指针法

首先提一句,不能用指针数组啊,一般指针数组都会把常值给定义出来,比如char* arr[ 2 ] = { "harry" , "poter" } ; 这里面的两个元素都不能被改变,到后面要用冒泡法交换两个内容的位置就很麻烦了。

数组指针法其实比较多此一举,写出来主要是为了让自己以后更好地理解并应用数组指针。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
void my_cmp(char(*np)[10])
{int i = 0;int j = 0;char tmp[20] = { 0 };for (i = 0; i < 20; i++)//冒泡法实现姓名排序{for (j = 0; j < (19 - i); j++){if (strcmp(*(np + j), *(np + j + 1)) == 1){strcpy(tmp, *(np + j));strcpy(*(np + j), *(np + j + 1));strcpy(*(np + j + 1), tmp);}}}
}
int main()
{int i = 0;char name[20][10];char(*np)[10] = &name;printf("请输入20个英文名字:\n");for (i = 0; i < 20; i++){scanf("%s",name[i]);}my_cmp(np);printf("//排序后的结果为//\n");for (i = 0; i < 20; i++){printf("%s ",name[i]);}return 0;
}

结果如下图:

­


结构体法

结构体法里我使用了最近学的函数——qsort函数。对这个函数,我在这里简单介绍一下。

1. qsort函数

(1)功能

对所指数组元素进行升序或逆序排序。C语言里要调用头文件stdlib.c

(2)函数声明

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

就像本实验程序里写的:

qsort ( people,  sz,  sizeof ( people [ 0 ] ),  name_cmp ) ;

第一个空要填需要排序的数组中的首元素地址。第二个空要填数组长度。第三个空要填每个元素所占内存的大小,第四个空填写一个比较两元素大小的函数。

接着再进入这个函数里,简要解释一下“((struct member*)e1)->name”是什么意思:

(struct member*)指的是参数类型是结构体指针,e1里存放着结构体某个name的地址,然后(struct member*)e1整体指向了成员name,将其解引用得到e1地址里存放的name数据。

注意,由于e1,e2是两个地址,所以获取结构体成员数据时要用" -> ",不能用“ . ”。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>struct member {char name[10];
}people[20];//定义结构体int cmp_str(const void* e1, const void* e2)//sqrt内部实现前后排序的函数
{return strcmp(((struct member*)e1)->name, ((struct member*)e2)->name);
}int main()
{int i = 0, j = 0;int sz = sizeof(people) / sizeof(people[0]);printf("请输入20个英文名字:\n");for (i = 0; i < 20; i++){scanf("%s", people[i].name);}qsort(people, sz, sizeof(people[0]), cmp_str);//使用qsort函数进行排序printf("///排序后的结果为///\n");for (i = 0; i < 20; i++){printf("%s ", people[i].name);j++;if(j==4){printf("\n");j = 0;}}return 0;
}

without qsort

当然不用qsort函数也可以做出来,我把只用了结构体的代码也截取了部分下来。

void bubble_sort(int sz, struct member p[])
{int i = 0;int j = 0;char tmp1[10] = { 0 };for (i = 0; i < sz; i++){for (j = 0; j < (sz - 1 - i); j++){if (strcmp(p[j].name, p[j + 1].name) == 1){strcpy(tmp1, p[j].name);strcpy(p[j].name, p[j+1].name);strcpy(p[j + 1].name, tmp1);}}}
}
int main()
{int i = 0, j = 0;int sz = sizeof(people) / sizeof(people[0]);printf("请输入20个英文名字:\n");for (i = 0; i < 20; i++){scanf("%s", people[i].name);}bubble_sort(sz, people);printf("///排序后的结果为///\n");for (i = 0; i < 20; i++){printf("%s  ", people[i].name);j++;if(j==4){printf("\n");j = 0;}}return 0;
}

最后结果为

C语言实验过程化记录-1相关推荐

  1. c是过程化语言吗数据库,关于SQL错误的是()A、所有数据库的公共语言B、非过程化的C、统一的语言D、所有用SQL缩写的程序都...

    关于SQL错误的是()A.所有数据库的公共语言B.非过程化的C.统一的语言D.所有用SQL缩写的程序都 更多相关问题 [多选] 在彩色电视机遥控系统中,属于模拟量控制的有()等几种. [多选] 在色度 ...

  2. pl/sql过程化语言

    plsql过程化语言 --控制输出-- declare begindbms_output.put_line('hello/plsql'); end; --变量的声明和使用-- declarev_num ...

  3. 语言都是相通的,学好一门语言,再学第二门语言就很简单,记录一下我复习c语言的过程。...

    语言都是相通的,学好一门语言,再学第二门语言就很简单,记录一下我复习c语言的过程. 为了将本人的python培训提高一个层次,本人最近买了很多算法的书. 这个书上的代码基本都是c语言实现的,c语言很久 ...

  4. c是过程化语言吗数据库,A.数据库语言B.过程化语言C.宿主语言D.数据库管理系统...

    A.数据库语言B.过程化语言C.宿主语言D.数据库管理系统 更多相关问题 [填空题] 为了安全起见,起动发动机前要检查()有无行人.---叉车操作和保养手册第2-77.在起动叉车前()以警告周围的人. ...

  5. 川轻化c语言实验答案,c语言实验报告(学生学籍管理系统)

    <c语言实验报告(学生学籍管理系统)>由会员分享,可在线阅读,更多相关<c语言实验报告(学生学籍管理系统)(20页珍藏版)>请在人人文库网上搜索. 1.氮闭谜蹋典灸逐簇距坏硕蹄 ...

  6. 【C++程序设计教程(第三版)钱能】 学习笔记 上半部/C++过程化语言基础

    ◆ 第一部分 C++过程化语言基础 >> 在生成可执行程序之前,C++忽略注释,并把每个注释都视为一个空格. ◆ 第2章 基本数据类型与输入/输出 >> 匈牙利标记法(Hung ...

  7. c语言初步实验报告,c语言实验报告(大一c语言实验报告答案)

    哪位帮我一下啊,我这有个作业,要写C语言程序设计实验报告,包括五个部. 最低0.27元/天开通百度文库会员,可在文库查看完整内容> 原发布者:aming7728081 计算机科学与技术系C语言实 ...

  8. 太原理工大学c语言课程设计报告,太原理工大学C语言实验报告

    太原理工大学C语言实验报告 本科实验报告课程名称: 程序设计技术 B 实验项目: 实验地点: 明向校区软件学院机房 专业班级: 学号: 学生姓名: 指导教师: 呼克佑 2014 年 12 月 日实验名 ...

  9. c语言对分查找实验报告,C语言实验指导.doc

    C语言实验指导.doc C语言实验指导(要求认真填写实验报告中的各项内容,不得空白或填写未发现问题)实验一 顺序结构程序设计实验二 选择结构程序设计实验三 循环结构程序设计实验四 一维数组及其应用实验 ...

最新文章

  1. flowable工作流_【程序源代码】Springboot开源工作流开发框架
  2. Android_Sqlbrite入门使用
  3. 安装后系统配置及优化
  4. 以下哪些是oracle预定义角色,Oracle中预定义角色有哪些?
  5. Tomcat源码学习(7)-How Tomcat works(转)
  6. Eclipse卸载Groovy Development tool时,为什么要去查询hana.ondemand.com的资源?
  7. java.policy无法修改_如何配置Policy文件进行Java安全策略的设置
  8. java simplejson_JSON.simple首页、文档和下载 - JSON/BSON开发包 - OSCHINA - 中文开源技术交流社区...
  9. Node.js 14 发布,改进了诊断功能
  10. 学长们的求职血泪史(C/C++/JAVA)
  11. 浅谈NFC、RFID、红外、蓝牙的区别
  12. 微信怎么不支持华为鸿蒙,微信迟迟不加入鸿蒙,华为为何不着急呢?
  13. 计算机系统文件夹打不开,为什么打不开文件夹
  14. 巨杉数据库支持的mysql兼容特性包括_核心特性_SequoiaDB简介_文档中心_SequoiaDB巨杉数据库...
  15. java ee jpi是什么,JPI 150、300、600RF、RJ什么意思
  16. 前端初学,记下标签以后参考
  17. matlab中signal pulses,MATLAB信号处理仿真-基带脉冲成形的数字滤波器
  18. 中国大学生三天连夜做的AI特效小游戏,一天暴涨800万用户!
  19. 服务器被入侵,执行了2个非常危险的命令
  20. 提示未登录,点确认,跳到登陆页

热门文章

  1. 计算机开机时间不对,电脑每次开机时间都不对?究竟是哪里出了问题?该怎么修复?...
  2. 2023西南大学907考研,西南大学计算机考研情况
  3. CQUCQUPT联合狂欢赛小结
  4. Vue - 简约大气 404 页面
  5. 关于绩效考核,可能与你理解的不一样
  6. Mix-land拓荒的星际勇者 | 实验
  7. 计算机专业硬件,什么是计算机硬件?
  8. 全连接神经网络VS卷积神经网络基本概念理解
  9. 二叉树的层次遍历(图解、思想、与实现)
  10. N5772A 34901A