之前在学校学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. 最精简写法→去掉任意多个空行
  2. java网络编程的通信原理_11 - 网络编程之设备间通信原理
  3. Dart Way 1
  4. (七)OpenStack---M版---双节点搭建---Dashboard安装和配置
  5. 遍历Map的几种方式以及性能小结
  6. K8S报错:controller-manager Unhealthy Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252
  7. 关于SDIO接口的wifi和通用SD卡的一些记录
  8. MyBatis实现SaveOrUpdate
  9. C语言高级编程:i++ 或 ++i作为函数参数
  10. _一文让你透彻理解Linux的SOCKET编程(含实例解析)
  11. laravel-admin grid中使用switch操作一对一关联属性(源码探究到功能实现)
  12. Python类方法和静态方法
  13. 分治法——查找最大最小元素(C++)
  14. 2003年考研数学一答案解析pdf
  15. Python学习:IndentationError: expected an indented block
  16. 转载:h5标签中的embed标签
  17. 失效而后犬儒【2019.05.15报告记录】
  18. python 知乎 合并 pdf_怎么把多个pdf合并在一起?
  19. 一个SAP开发人员的2017总结:编程与游泳
  20. JAVA ImageIO图片处理后变色

热门文章

  1. matlab里面q函数,q函数原理及matlab计算
  2. osg学习(五十四)PNG lib warning : Interlace handling should be turned on when using png_read_image
  3. 杭电OJ——ACM 1009.FatMouse‘ Trade
  4. linux下的并发编程详解
  5. NetSuite资产负债表编制技巧
  6. 路由器总是显示未连接到服务器,链接路由器但一直显示未连接服务器
  7. 0359-模型训练和部署-Iris数据集
  8. Excel  VBA批量修改文件名
  9. 公众号推文中添加文件的方法
  10. 学不会编程?试试我的方法