【C语言】指针数组
题目:编写UNIX程序sort的简化版本,该程序按字母顺序对由文本行组成的集合进行排序。
思路:我们引入指针数组处理这种问题。如果待排序的文本行首尾相连地存储在一个长字符数组中,那么每个文本行可通过指向它的第一个字符的指针来访问。这些指针本身可以存储在一个数组中。这样,将指向两个文本行的指针传递给函数strcmp就可实现对这两个文本行的比较。当交换次序颠倒的两个文本行时,实际交换的是指针数组中与这两个文本行相对应的指针,而不是这两个文本行本身,如下图所示。
这种实现方法消除了因移动文本行本身所带来的复杂的存储管理和巨大的开销这两个孪生问题。
排序过程包括下列3个步骤:
- 读取所有输入行
- 对文本行进行排序
- 按次序打印文本行
代码实现:
#include <stdio.h> #include <string.h> #define MAXLINES 5000 // 定义最大的输入行数 #define MAXLEN 1000 // 每行字符最大长度 #define ALLOCSIZE 10000 // 分配的最大存储空间 char allocbuf[ALLOCSIZE]; char *allocp = allocbuf; char *lineptr[MAXLINES]; // 指针数组,其中每个元素存放的是一行 /* 读取一行输入 */ int getline(char s[], int lim) { int c, i; for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++){ s[i] = c; } if (c == '\n') { s[i++] = c; } s[i] = '\0'; return i; } // 分配存储空间 char *alloc(int n){ if(allocbuf + ALLOCSIZE -allocp >= n){ allocp += n; return allocp-n; }else{ return 0; } } /* 读取所有行输入,并存入指针数组中 */ 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(len)) == NULL){ return -1; }else{ line[len - 1] = '\0'; strcpy(p, line); lineptr[nlines++] = p; } } return nlines; } /* 打印输出 */ void writelines(char *lineptr[], int nlines){ int i; for(i = 0; i < nlines; i++){ printf("%s\n", lineptr[i]); } } /* 数据交换 */ void swap1(char *v[], int i, int j){ char *tmp; tmp = v[i]; v[i] = v[j]; v[j] = tmp; } /* 快速排序(这里取分割点为集合的中点) */ void qsort1(char *v[], int left, int right){ int i, last; if(left >= right){ return; } swap1(v, left, (left+right)/2); last = left; for(i = left+1; i<=right; i++){ if(strcmp(v[i], v[left]) < 0){ swap1(v, ++last, i); } } swap1(v, left, last); qsort1(v, left, last-1); qsort1(v, last+1, right); } /* 主函数 */ main(){ int nlines; //输入的行数 if((nlines = readlines(lineptr, MAXLINES)) >= 0){ qsort1(lineptr, 0, nlines-1); writelines(lineptr, nlines); return 0; }else{ printf("error: input too big to sort\n"); return 1; } }