c语言的常见问题(一)

来源:互联网 发布:java软件开发的书籍 编辑:程序博客网 时间:2024/06/01 10:41

1,,scanf() 永远都不能越过错误的非数字字符而处理后边的合法数字 字符。

如果用户在数字格式的scanf 如%d 或%f 中输入字符‘x’,当你回车之后(系统默认你输入结束了)则这个x不会被输入进去。


#include <stdio.h>
main()
{
int a=0;
char x=98;
scanf_s("%d",&a);
printf("%d",a);
printf("%8d",x);
}


2,若两个scanf()一起输入,第二个scanf是读取一个字符或者字符串,则会出现问题。因为上一个scanf结束的标志\n会被保存在输入流中,而被
下一个scanf读取。因此,你第二个scanf读取的不是你想输入的,而是\n。

#include <stdio.h>
main()
{
int a=0;
char x=98;
scanf_s("%d",&a);
scanf_s("%c",&x);
printf("%d",a);
printf("%8d",x);
}

解决方法可以是,把scanf_s("%c",&x);改成scanf_s("\n%c",&x);或者在两个scanf之间加scanf_s("%c",&x);或者getchar().当然你可能问,gets()行不行。如果一定要这样,来证明你还知道gets这个函数的话,你可以先定义一个字符数组或者字符串,然后把地址放进去。如char b[4];gets(b);

3.a[3]="abc"是一个合法的字符吗?

不是的,因为字符串的结尾总是\0(不是0),因此你应该定义一个a[4]去存放。另外,如果你可以尝试去查a的地址,看看会发生什么。

4.数组的边界

#include <stdio.h>
main()
{
int value1 = 44;//0x006ff8f0我的电脑中的地址,你们的可能不一样
int arr[4];//0x006ff8d8~0x006ff8e4
int value2 = 88;//0x006ff8cc
int i;
printf("value1=%d,value2=%d\n", value1, value2);
for (i = -4; i <= 8; i++)
arr[i] = 2 * i + 1;
for (i = -4; i < 8; i++)
printf("%2d %d\n", i, arr[i]);
printf("value1=%d,value2=%d\n", value1, value2);
return 0;
}

输出结果是
value1=44,value2=88
-4 -7
-3 -5
-2 -3
-1 -1
 0 1
 1 3
 2 5
 3 7
 4 9
 5 11
 6 13
 7 15
value1=13,value2=-5

不同编译器会不一样。我们发现,value的值被改变了。所以,我们结合debug(我上面已经在注释给出地址)可以发现,程序简单地利用我们给数组的索引去给
数组赋值,也就是说程序不会去识别数组的索引是否超出边界。这是因为程序保持对程序员的信任,为了加快运行速度,才不去判断索引。当然并非每个程序员都像
笔者一样可信,一种比较好的办法是,尽量不要定义一个变长数组(虽然笔者的编译器还不支持变长数组),定义一个常数范围的数组,然后把常数宏定义具体的值。
这样就起到提醒作用。另外注意数组从0开始,到n-1结束。

5.写一个返回字符串的函数


#include <stdio.h>
char*string(void)
{
char *str = "qiou";//字符串的一个指针,和数组一样,指向第一个字符
return str;
}
main()
{
printf("address = %p,string = %s", string(), string());//打印这个指针和这个指针指向的内容,为什么不用*string()呢?因为首先我们打印格式是%s,其次确实字符串就是在这种意义上就是指针。不求甚解。别再追问了,看下一个,有*号
}
第二个

#include <stdio.h>
char*string(void)
{
char *str = "qiou";//或者char str[5]={'q','i','a','o'};
return str;
}
main()
{
printf("address = %p,string = %c", string(), *(string()+1));//这个时候我们写的格式是c,也就是这个指针指向的字符,也就是第一个字符,和数组一样,这时候我们地址+1,输出的就是i
}

0 0
原创粉丝点击