#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#define Nmax 1000
#define Mmax 10000
char buf[Mmax];
int M=0;
int compare(void const *i, void const *j)
{
return strcmp(*(char **)i, *(char **)j);
}
int main (void)
{
int i,N;
char *a[Nmax];
for (N=0; N<Nmax; N++){
a[N]=&buf[M];
if(scanf("%s",a[N]) == EOF) break;
printf("第%d次循环\n", N+1);
M += strlen(a[N])+1;
}
for(i=0; i<N; i++)
printf("%s\n",a[i]);
qsort(a, N, sizeof(char *), compare);
printf("qsort over\n");
for(i=0; i<N; i++)
printf("%s\n",a[i]);
getch();
}
问题
程序中的一些printf是我自己加入的,为了观察程序运行
输入 d a g h e k ^Z
此时输出 第一次循环 回车 第二次循环…第六次循环(只有这些,运行好像停止了)
接着 输入 ^Z 回车^Z(图片传不上,问题就在这儿,为什么输入“^Z 回车^Z“呢?这是scanf的特性吗?我以为不用了,这个地方请详解!)
才能输出排序前后的。
还有一个问题是关于compare函数的,写成如下也可
int compare(void const *i, void const *j)
{
return strcmp((char *)i, (char *)j);
}
这两种形式有什么区别,也请详解,指针能强制转化成指针的指针然后再转换成普通指针吗?
另外一个问题就是关于 分治 的问题
评估运行时间规模时,用分治求最大值,用分治求解汉诺塔,斐波那契数列的O都不一样啊,我不是很清楚,算法高手请解。说明白的另行加分,拒绝抄袭。
2、return strcmp((char *)i, (char *)j); 这种执指针的强制转化一定要慎用,在C中可能尚不能完全抛弃,但是VC、MFC编程中这样的强制转换非常危险。强制关闭了编译器的检查。很可能编译过了在运行期出现致命错误。用staitc_cast<char *>!动态的用dynamic_cast<int>.
3、 int compare(void const *i, void const *j)函数形式的问题,void const * i ,这里的i是指针常量<指针本身是常量>。 const void * i 是常量指针。就是他的指涉物是常量。而本身不是常量。
如:const int* iPtr; <常量指针> int iTemp=10; iPtr=&iTemp; <改变指针本身是可以的>;*iPtr=iTemp;(编译报错).因为是常量指针,指向的是常量,不可重赋值!
4、compare,作为函数指针参数传递给qsort(),编译器会检测其类型,包括函数的参数数量\类型和返回值。
5、"指针能强制转化成指针的指针然后再转换成普通指针吗?"这个问题呢?有点不好说,因为不能绝对说,但是上面已经提到指针的强制转换时危险的行为。要很慎重,因为编译器是检查不出错误的。 请注意指针的级数,请注意指针是一个特殊的类型,本质是一个32整型值。其存贮的是地址。通过*反引用符号,访问其指涉物。
你的强制转换如果将一级指针转换成指向指针的指针(二级)肯定会出错的!级数这里如果不对应就一定是致命错误!行为时为可定义的!
如 int* iPtr=&int(5);可以如此转换,(void*)iPtr;<注意:还是一级>; 之后某个时候(int*)iPtr转换过来.(但是不推荐,很容易出错的当程序复杂的时候.)
但如果 (void**)iPtr; (二级指针)就一定会出错。因为现在*iptr还是一级指针而不是 int/void值!
希望能够帮到你。新手对于指针这一块是有点搞不清,慢慢就好了。
2.compare()函数的两种写法都能实现功能是因为你的第一种写法( char **)这里用的是二级指针的定义方式,而在(char **)前面又有一个 * (取指针内容)运算符,所以又变成了一个指向字符的一级指针,在你的第二种写法里面(char *)这里是直接定义一个一级指针,所以在函数strcmp()最后接到的都是同一个指向字符的指针,所以功能是一样的。
3.有关分治法的东西我不是很了解,不能帮忙了。
希望能帮上你。