C语言高手进,关于EOF scanf

#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都不一样啊,我不是很清楚,算法高手请解。说明白的另行加分,拒绝抄袭。

1、输入^Z运行好像停止的原因。我机器上面是正常的啊。你 的 char *a[Nmax]; a 是char*的数组。scanf("%s",a[N]) == EOF 用来存贮字符串没问题的呀。我运行的时候输入了1 2 3 ^Z 也同样输出了。没问题的。请参考MSDN scanf()函数用法,这里没有错的。而且尽量不要使用#define Nmax 1000 #define Mmax 10000 这样的定义字面常量。用const int 1000。这个东西在编译器分析的时候会进行优化,不要担心空间开销问题。再者,定义超大数组时不好的风格,如果为了输入的个数足够的话。AcAarry<int,int> 的模板。
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值!
希望能够帮到你。新手对于指针这一块是有点搞不清,慢慢就好了。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-12-06
1.scanf()函数的特性我不是很了解,只知道在ACM竞赛中经常会用到EOF来判断输入的结束,EOF的使用来自" 文件" 的结束经常用EOF标识,因为ACM的自动判题系统会使用文件对比技术,所以会用到语句( scanf(.....) != EOF)来决定输入的终止,至于为什么是输入Ctrl+Z代表输入的是EOF,可能是操作系统定义的,在Linux环境下也能这样,EOF的定义在头文件stdio.h中。
2.compare()函数的两种写法都能实现功能是因为你的第一种写法( char **)这里用的是二级指针的定义方式,而在(char **)前面又有一个 * (取指针内容)运算符,所以又变成了一个指向字符的一级指针,在你的第二种写法里面(char *)这里是直接定义一个一级指针,所以在函数strcmp()最后接到的都是同一个指向字符的指针,所以功能是一样的。
3.有关分治法的东西我不是很了解,不能帮忙了。
希望能帮上你。

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网