C语言K&R圣经笔记 5.6指针数组;指针的指针

这篇具有很好参考价值的文章主要介绍了C语言K&R圣经笔记 5.6指针数组;指针的指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

5.6 指针数组;指针的指针

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

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

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

C语言K&R圣经笔记 5.6指针数组;指针的指针,C语言,c语言,笔记,开发语言

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

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

读入所有的文本行

对其排序

按顺序打印

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

输入例程必须收集和保存每行的字符,并创建一个指向每行的指针数组。它还需要计算输入的行数,因为这个信息还需要用于排序和打印。由于输入函数只能处理有限数量的输入行,如果有太多输入时,它可以返回某些非法的行数,例如 -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 来维护内存空间。程序会快多少?文章来源地址https://www.toymoban.com/news/detail-776715.html

到了这里,关于C语言K&R圣经笔记 5.6指针数组;指针的指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言--指针详解(下)--字符指针、数组指针、指针数组、函数指针、函数指针数组(转移表)

    在C语言中有一种指针类型为字符指针 char*,常用其来表示字符,使用如下: 除了上述用法之外,还可以有以下的用法: 在上面的代码中,字符 \\\" hello word \\\"是常量字符串,将\\\"hello word\\\"放入 pstr 指针的实质是将第一个字符 “ h \\\" 的地址传递给了 pstr ,通过首字符 ” h \\\" 就可以访问

    2024年02月03日
    浏览(51)
  • 【go语言基础】指针数组和数组指针

    (1)指针数组: 存储指针的数组,也叫存储地址的数组,简单说就是存储地址的。 首先它是一个数组,数组中的元素都是指针(地址)。 (2)数组指针: 首先它是一个指针,存储的是指向数组的指针。 (1)指针数组 定义: 注意:首先是一个数组,将数组中的元素定义为

    2024年02月13日
    浏览(52)
  • 【C语言】指针的基本知识详细讲解(指针数组、数组指针、函数指针....

    接着上次的函数的基本知识,今天我们来讲一讲🔍指针 目录 一、指针的概念 二、指针变量 三、野指针 四、字符指针 五、指针与数组 六、指针数组 七、数组指针  八、指针与函数 总结 一、指针的概念 1.1、变量和地址 所谓指针,也就是内存的地址;所谓指针变量,也就是

    2023年04月08日
    浏览(41)
  • C语言:指针和数组(看完拿捏指针和数组)

    目录 数组名的理解: 一维数组:  解析:  字符数组:  解析:   解析: 字符串数组:  解析:   解析:  一级指针:   解析:   解析:  二维数组:  解析:  指针笔试题: 题一:一维数组 题二: 结构体指针 题三: 一维数组 题四: 二维数组 题五: 二维数组 题

    2024年02月11日
    浏览(43)
  • 【C语言基础入门】二级指针、一维数组与指针、二维数组与指针

    在学习C语言的过程中,理解指针的概念是非常重要的。指针提供了一种直接访问内存地址的方式,使得我们可以更加灵活地管理数据和内存。在本文中,我们将介绍C语言中的二级指针、一维数组与指针,并通过通俗易懂的语言和示例代码来帮助读者理解这些概念。 二级指针

    2024年02月05日
    浏览(57)
  • 【C语言】指针进阶:字符指针&&数组指针&&函数指针

    ✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 🌹 感谢您的点赞与关注,同时欢迎各位有空来访我的 🍁平凡舍 回想之前,我们学了 指针 的一些基础👉 指针与结构体 我们知道了指针的概念: 指针就是

    2023年04月08日
    浏览(43)
  • C语言:指向数组的指针和指向数组首元素的指针

    相关阅读 C语言 https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482         指向数组的指针和指向数组首元素的指针常常被混淆,或者笼统地被称为数组指针,但它们之间是有差别的,本文就将对此进行讨论。         下面的代码首先创建了一个数组,然后创

    2024年02月02日
    浏览(52)
  • C/C++|物联网开发入门+项目实战|指针|嵌入式C语言高级|C语言内存空间的使用-学习笔记(9)

    参考: 麦子学院-嵌入式C语言高级-内存空间 内存类型资源地址、门牌号的代名词 指针:地址的代名词 指针变量:存放指针这个概念的盒子 *P char *p *p; C语言娟译器对指针这个特殊的概念,有2个疑问? 1、分配一个盒子,盒子要多大? 在32bit系统中,指针就4个字节 2、盘子里存放

    2023年04月22日
    浏览(70)
  • 《C和指针》笔记33:指针数组

    除了创建整型数组一样,也可以声明指针数组。 为了弄清这个复杂的声明,我们假定它是一个表达式,并对它进行求值。下标引用的优先级高于间接访问,所以在这个表达式中,首先执行下标引用。因此,api是某种类型的数组(它包含的元素个数为10)。在取得一个数组元素

    2024年02月07日
    浏览(29)
  • C语言的函数指针、指针函数, 函数数组

    是指向函数的指针,它允许您在程序运行时动态选择要调用的函数。函数指针可以像普通变量一样传递、存储和使用,这使得它们在许多编程场景中非常有用,如回调函数、函数表、插件架构等。 以下是一个简单的例子来说明函数指针的概念: 函数数组是一个数组,其中的

    2024年02月09日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包