40分求解3题简单C语言题
1)为什么输入字母后(或者输入数字加字母, "23a "),会死循环呢?照理说,非法输入
,每次也得都需要再输入,单步调试时, 发现遇到scanf( "%d ", &choice);跳过了,
switch语句段也跳过了。上面情况都是指输入字母后。(编译器VC6)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
int main(void)
{
int choice;
do
{
printf( "1 -- input\n ");
printf( "0 -- exit\n ");
printf( "Make your choice: ");
scanf( "%d ", &choice);
switch (choice)
{
case 1:
printf( "You select 1.\n ");
break;
case 0:
break;
default:
break;
}
}while (choice != 0);
return 0;
}
2)函数在调用结束后,会释放掉变量所占内存, 下面程序为什么在TC2.0可以
把 "1234567 "传给主函数(VC6不行)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
char *test(void)
{
char str[80] = "1234567 ";
char *resu = str;
return resu;
}
int main(void)
{
char *pstr;
pstr = test();
puts(pstr);
return 0;
}
3)分配动态一维数组问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
int main(void)
{
int *p;
int size;
int i;
printf( "请输入你要动态分配的数组的大小: ");
scanf( "%d ", &size);
p = (int *)malloc(size * sizeof(int));
for (i = 0; i < size; i++)
{
//p[i] = i + 1; 为什么把这句改下下面的就出错?
*p++ = i + 1;
}
p = &p[0];
for (i = 0; i < size; i++)
{
printf( "%d ", *p++);
}
printf( "\n ");
return 0;
}
[解决办法]
1 输入不合法的原因
2 这可能与具体编译器有关, 在DEV-C++中编译与VC一样,str[]临时变量的值在函数结束后就释放掉.
3 要注意区分指针与数组,如果要用 *p++ = i + 1;可以把p = &p[0];改成p = p - size;
[解决办法]
1 输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
fflush(stdin);
[解决办法]
问题一:scanf( "%d ", &choice);当输入不是有效数据时,choice接收的内容是乱码,满足它的while (choice != 0);循环条件,所以死循环;
问题二:str[80]由于它申请的内存在堆栈区,所以在函数调用完毕后它申请的内存空间会自动释放,所以main函数中调用返回的指针指向的一块已经释放的内存,既数据已不存在,所以才会出现问题。char* str = (char*)malloc(80);//修改,动态申请内存 就可以了
[解决办法]
1.通过单步调试可知,如果输a,变为%d形式即变成多个不可知字符,在死循时也不进行用户交互读取
scanf规则
如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。
可知,a变成了大于20个的字符,读到最大域时,进入switch。。不匹配跳出,scanf又对上一次未读外的域读取,,如此, ,造成循环
2.标准问题,VC6不允许这样的局部变量返回
3.
*p++ = i + 1; //已经改变原先地址
p = &p[0];//无法找到原来地址,打印出随机的数据。
[解决办法]
第一个问题:应该是数据溢出导致出现死循环。
第二个问题:编译器不同,没有用的内存在TC中并没有被改写。
第三个问题:p++ 已经改变了原来的p的地址,所以&p[0]无法找到原来地址,打印出随机的数据。
[解决办法]
1.非法输入需fflush(stdin)清除键盘缓冲区
default:fflush(stdin);
2.不能把编译器的偶然性与C标准混谈
3. p已经++了,后面的输出不可预料