C语言KR圣经笔记 5.6指针数组;指针的指针

5.6 指针数组;指针的指针

因为指针本身也是变量,所以它们也能像其他变量一样保存在数组里面。我们写个程序来说明,该程序将一些文本行按照字母顺序排列,算是 UNIX 程序 sort 的精简版本。

在第三章中,我们介绍了对一个整数数组进行排序的 Shell 排序函数,而在第四章中,我们用快速排序对其进行改进。同样的算法在这里也还能用,差异之处在于,现在我们要处理的是文本行,每行有不同的长度,而且文本行不像整数,没法用单个操作来比较或者移动。我们需要一种数据表示法,能够高效且方便地处理长度可变的文本行。

指针数组在这里就派上用场了。如果待排序的行是头尾相连地(end-to-end)保存在一个长字符数组里面,则每行都可以通过执行其首个字符的指针来访问。这些指针本身可以保存在一个数组里。将某两行的指针传递给 strcmp 就可以比较两行。当两个错序的行需要交换时,交换的是指针数组里面的指针,而不是文本行本身。

这就同时避免了移动文本行本身带来的两个孪生问题:复杂的内存管理,以及高额的开销。

排序过程很自然地分为三步:

读入所有的文本行

对其排序

按顺序打印

一如既往,最好是将程序拆分成与上面各步骤匹配的几个函数,再用主函数来控制这些函数。我们先聚焦于数据结构和输入输出,晚点再看排序步骤。

输入例程必须收集和保存每行的字符,并创建一个指向每行的指针数组。它还需要计算输入的行数,因为这个信息还需要用于排序和打印。由于输入函数只能处理有限数量的输入行,如果有太多输入时,它可以返回某些非法的行数,例如 -1。

输出例程只需要按指针数组中的顺序来打印行即可。

#include <stdio.h>
#include <string.h>#define MAXLINES 5000        /* 最多储存的行数 */char *lineptr[MAXLINES];     /* 文本行的指针 */int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);void qsort(char *lineptr[], int left, int right);/* 对输入行排序 */
int main()
{int nlines;    /* 读入的输入行数 */if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {qsort(lineptr, 0, nlines - 1);writelines(lineptr, nlines);return 0;} else {printf("error: input too big to sort\n");return 1;}
}

#define MAXLEN 1000    /* 输入行的最大长度 */
int getline(char *, int);
char *alloc(n);/* readlines: 读入文本行 */
int readlines(char *lineptr[], int maxlines)
{int len, nlines;char *p, line[MAXLEN];nlines = 0;while ((len = getline(line, MAXLEN)) > 0)if (nlines >= maxlines || (p = alloc(n)) == NULL)return -1;else {line[len -1] = '\0';    /* 删除换行 */strcpy(p, line);lineptr[nlines++] = p;}return nlines;
}/* writelines:输出行*/
void writelines(char *lineptr[], int nlines)
{int i;for (i = 0; i < nlines; i++)printf("%s\n", lineptr[i]);
}

函数 getline 来自 1.9 节。

新东西主要是 lineptr 的声明:

char *lineptr[MAXLINES]

它表示 lineptr 是一个有 MAXLINES 个元素的数组,每个元素是一个指向 char 的指针。也就是说,lineptr[i] 是一个字符指针,而 *lineptr[i] 是它指向的字符,即所保存的第 i 个文本行的首字符。

由于 lineptr 本身也是数组名称,因此我们也能和前面的例子一样把它当作指针,这样 writelines 也能写成:

/* writelines:输出行*/
void writelines(char *lineptr[], int nlines)
{int i;while (nlines-- > 0)printf("%s\n", *lineptr++);
}

最初 *lineptr 指向第一行,当 nlines 递减时,lineptr 每次递增推进到下一行的指针。

搞定了输入输出,现在我们来做排序。需要对第四章的快速排序做些小改动:声明得修改;比较操作必须通过调用 strcmp 来做。算法保持不变,这样给我们了一些信心,相信它还能工作:

/* qsort: 把v[left],...v[right]按升序排列 */
void qsort(char *v[], int left, int right)
{int i, last;void swap(char *v[], int i, int j);if (left >= right)    /* 若数组小于两个元素则什么都不用做  */return;swap(v, left, (left + right)/2);last = left;for (i = left+1;i <= right; i++)if (strcmp(v[i], v[left]) < 0)swap(v, ++last, i);swap(v, left, last);qsort(v, left, last-1);qsort(v, last+1, right);
}

类似地,交换例程也只要做一点改动:

/* swap: 交换v[i]和v[j] */
void swap(char *v[], int i, int j)
{char *temp;temp = v[i];v[i] = v[j];v[j] = temp;
}

由于 v (即 lineptr 的别名)的每个元素都是字符指针,而 temp 也是,因此它们可以互相拷贝。

练习5-7、重写 readlines 函数,将行保存到 main 提供的数组中,而不是调用 alloc 来维护内存空间。程序会快多少?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/598800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10-链表-删除排序链表中的重复元素 II

这是链表的第10篇算法&#xff0c;这是上一篇文章的加强版&#xff0c;力扣链接。 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,…

Facebook选品方法大揭秘,这几个最畅销类目别错过!

现在越来越多的卖家开始做社媒电商&#xff0c;其中很多人都想在 Facebook 这个平台上分一杯羹&#xff0c;而 Facebook选品对于这些商家来说非常重要。俗话说&#xff0c;七分靠选品&#xff0c;三分靠运营&#xff0c;想成功入局 Facebook&#xff0c;选品选的好&#xff0c…

肠道重要属——芽孢杆菌属,益生与病原双标签

谷禾健康 芽孢杆菌属&#xff08;Bacillus&#xff09;是革兰氏阳性、杆状、芽孢杆菌科细菌的一个属&#xff0c;属于厚壁菌门。 芽孢杆菌属物种可以是专性需氧微生物(依赖氧气)或兼性厌氧微生物(具有需氧或厌氧的能力)。当使用或存在氧气时&#xff0c;它们的过氧化氢酶检测呈…

Stable Diffusion汉化插件

今天为大家介绍Stable Diffusion的两种UI汉化包&#xff0c;一种是汉化包&#xff0c;就中文界面&#xff0c;方便大家对于繁杂的参数的模型的操作&#xff0c;一种是中英文对照界面&#xff0c;在中文提示下&#xff0c;同时显示英文&#xff0c;不但方便设置也同时学习了英文…

MySQL进阶篇(一)存储引擎

一、MySQL 体系结构 &#xff08;1&#xff09; 连接层 最上层是一些客户端和链接服务&#xff0c;包含本地 sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff…

如何通过内网穿透实现无公网IP远程访问内网的Linux宝塔面板

文章目录 一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

这款IDEA插件真的爽,白嫖真香

Apipost-Helper是由Apipost推出的IDEA插件&#xff0c;写完接口可以进行快速调试&#xff0c;且支持搜索接口、根据method跳转接口&#xff0c;还支持生成标准的API文档&#xff0c;注意&#xff1a;这些操作都可以在代码编辑器内独立完成&#xff0c;非常好用&#xff01;这里…

XD6500S一款串口SiP模块 射频LoRa芯片 内置sx1262

1.1产品介绍 XD6500S是一款集射频前端和LoRa射频于一体的LoRa SIP模块系列收发器SX1262 senies&#xff0c;支持LoRa⑧和FSK调制。LoRa技术是一种扩频协议优化低数据速率&#xff0c;超长距离和超低功耗用于LPWAN应用的通信。 XD6500S设计具有4.2 mA的有效接收电流消耗&#…

DevOps(10)

目录 56.Docker的架构&#xff1f; 57.Docker镜像相关操作有哪些&#xff1f; 58.Docker容器相关操作有哪些&#xff1f; ​编辑59.如何查看Docker容器的日志&#xff1f; 60.如何启动Docker容器&#xff1f;参数含义&#xff1f; 61.如何进入Docker后台模式&#xff1f;有…

Open3D将聚类结果显示或者保存

将聚类结果按大小排序&#xff0c;并取出最大的4个结果 import time import open3d as o3d; import numpy as np; import matplotlib.pyplot as plt#坐标 mesh_coord_frame o3d.geometry.TriangleMesh.create_coordinate_frame(size355, origin[0, 0, 0]) #mesh_coord_frame…

2023APMCM亚太数学建模C题 - 中国新能源汽车的发展趋势(2)

五&#xff0e;问题二模型建立和求解 5.1 问题二模型建立和求解 针对题目二&#xff0c;题目要求收集中国新能源电动汽车行业发展数据&#xff0c;建立数学模型描述&#xff0c;并预测未来十年的发展。由于在第一文中&#xff0c;我们已经收集了一定的新能源行业发展数据&…

【漏洞复现】ActiveMQ反序列化漏洞(CVE-2015-5254)

Nx01 产品简介 Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件。ActiveMQ是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高可用、出色性能、可扩展、稳定和安全保障。 Nx02 漏洞描述 Re…

数据分析求职-岗位介绍

这是咱们干货开始的第一篇文章&#xff0c;后续我尽量会保持日更的节奏和大家做分享~ 在未来所有分享的内容展开之前&#xff0c;咱们有必要先彻底、深入地了解下数据分析这个岗位。如果你还在犹豫是否要走数据分析的路&#xff0c;或者你已经拿了数据分析的offer想了解下将来…

插入排序详解!!!(简单排序),基本功排序C语言版

目录 1.什么是插入排序 2.插入排序的源代码 3.源代码详解 1.什么是插入排序 这是一个插入排序的流程图&#xff0c;插入排序 很像我们玩斗地主&#xff0c;玩牌&#xff0c;斗地主在开始前&#xff0c;我们是不是要给我们手上的牌排序啊&#xff0c;假设我们理牌有一个规矩就…

CLM陆面过程模式实践技术应用

NCAR陆面模式CLM (Community Land Model)是地球系统模式CESM (Community Earth System Model)中的陆面过程模式分量&#xff0c;是在结合了BATS、LSM和IAP94等众多陆面模式的优点后&#xff0c;加入水文过程而开发出的综合性陆面模式&#xff0c;是目前国际上发展最为完善且得到…

MySQL-DDL

DDL是数据定义语言&#xff0c;用来定义数据对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09; 数据库操作&#xff1a; 1.查询&#xff1a; 查询所有数据库&#xff1a;SHOW DATABASES; 查询当前数据库&#xff1a;SELECT DATABASE(); 2.创建&#xff1a; C…

UI测试平台RunnerGo一键安装教程

现在安装RunnerGo仅需要一条命令&#xff01;目前支持系统&#xff1a;Centos、Debian、Ubuntu三种。下面给大家介绍一下RunnerGo安装使用流程&#xff1a; Step1&#xff1a;复制以下命令 wget https://img.cdn.apipost.cn/running_go/img/wiki/runnergo.tar && ta…

基于SSM的新闻网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

打破闲鱼商品搜索瓶颈!云端电商API接口让你畅享商品详情关键词搜索的便利!

在闲鱼卖家的日常经营中&#xff0c;商品搜索是一个至关重要的环节。但是&#xff0c;由于闲鱼平台商品信息繁杂&#xff0c;卖家往往很难通过手动搜索的方式找到符合自己需求的商品。为了解决这一问题&#xff0c;云端电商API接口应运而生。联讯数据将详细介绍云端电商API接口…

有没有游泳可以戴的耳机?游泳耳机入耳式好,还是骨传导好

游泳是一项既能锻炼身体又能让人放松心情的运动。我们知道&#xff0c;音乐能够为我们的水上时光增添更多的乐趣。那么&#xff0c;在众多游泳耳机中&#xff0c;如何选择一款既适合自己的需求又具备良好性能的产品呢&#xff1f; 首先&#xff0c;我们要了解的是&#xff0c;…