/* 注解: 在处理字符串时, 我们通常使用一个指向包含那个字符串的缓冲区的指针, 如上图, 应为指针要比长度大小可变的字符串自身更容易操纵 输入完后: 对于这个程序理解, 1. 首先定义了一个用于存储字符串数组的 缓冲区字符串 2. a是个字符串指针类型的数组 3. a[N]表示了含有N个字符串的指针 如果这个文件后缀名写为cpp, 那么编译的时候会出错, 因为CPP 和C的函数的压栈顺序不一样, 所以 qsort( particles, n, sizeof( particle ), &cmp );这一行一直没能编译通过,报的错误是error C2664: “qsort” : 不能将参数 4 从“int (const FILEINFO *,const FILEINFO *)”转换为“int (__cdecl *)(const void *,const void *)” 还好能从网上找到答案,按照下面的格式定义cmp就可以在C++中运行了:int __cdecl cmp(const void* p1, const void* p2 ), 还有说法是将cmp定义成static类型也是可以 __cdecl 是C DECLaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。 _stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调 用的函数在返回后清除,使用的指令是 retnX,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define Nmax 1000 #define Mmax 10000 char buf[Mmax]; int M = 0; int compare(void *i, void *j) { return strcmp(*(char **)i, *(char **)j); } int main () { int i,N; char* a[Nmax]; for (N = 0; N < Nmax; N++) { a[N] = &buf[M]; //将a[N]赋值为""(空的字符串), buf 是一个容量足够大的字符串容器 if (scanf("%s",a[N])== EOF)//这样的输入以后, 会默认在字符数组后面加上' '字符 break; M += strlen(a[N])+1;//M统计了中的字符串数组中字符的个数, 而N表示了buf中具有的字符串的个数 } qsort(a, N, sizeof(char *), compare); for (i=0; i < N; i++) { printf("%s ",a[i]); } return 0 ; }
这个程序的运行结果
注解: 在处理字符串时, 我们通常使用一个指向包含那个字符串的缓冲区的指针, 如上图, 应为指针要比长度大小可变的字符串自身更容易操纵