C语言使用注意事项(四)
来源:互联网 发布:windows基于什么内核 编辑:程序博客网 时间:2024/06/08 02:40
转载于http://blog.csdn.net/yming0221/article/details/7247075
1、scanf()输入注意
当你使用scanf("%d",&a),然后用gets()读取下一行的一个字符串时,调用后好像gets()函数没有执行。
原因:这是由于scanf()函数不处理回车换行符。这样以来gets()函数读取的只是回车换行符。所以好像时gets()函数没有执行。
解决方法:可以在scanf()函数后插入一个getchar()函数来吃掉那个回车换行符。
2、scanf()的缓冲区问题
为什么说scanf()函数有问题呢?就因为它适用于结构化,格式相对整齐的数据输入。
例如下面的例子
- #include <stdio.h>
- int main(int argc,char **argv)
- {
- char a;
- while(1)
- {
- scanf("%c",&a);
- printf("a=%c\n",a);
- }
- return 0;
- }
当输入连续asdfg时运行结果如下:
这里可以看出scanf()读取数据到缓冲区,当缓冲区不空时从缓冲区截取,当缓冲区为空时,再读一组数据到缓冲区。所以为保证安全
*可以在每次scanf()后加一个清空缓冲区的语句fflush(stdin),但是这不是所有的编译器都支持的,VC6.0支持,但是GCC不支持。
*使用scanf()的替代功能函数。可以先用fgets()读入一整行,然后用字符串处理函数进行字符串处理(strtok(),strtol(),atoi())
3、printf()和sprintf()函数
就像scanf()函数一样,这两个函数也存在缓冲区的问题,例如输出一个字符串,当你不可预测字符串的长度时,可能存在字符串的过长导致缓冲区溢出,从而影响其他内存区。
如下例子:
- int main(int argc,char **argv)
- {
- char a[11]={0};
- const char *p="12345678901234";
- sprintf(a,"%s",p);
- printf("a= %s\n",a);
- return 0;
- }
当p的长度大于系统给a分配的内存区,这样就会导致系统错误。
*当我们知道字符串的结构,我们可以使用sprintf(a,"%10s",p);防止超越内存区。
*使用snprintf()函数原型int snprintf(char *restrict buf, size_t n, const char * restrict format, ...);
例如
- int main(int argc,char **argv)
- {
- char a[11]={0};
- const char *p="12345678901234";
- snprintf(a,sizeof(a),"%s",p);
- printf("a= %s\n",a);
- return 0;
- }
4、GCC中qsort()函数使用方法
使用方法
*对int,char,double,float等数组排序方法
- #include <stdlib.h>
- #define MY_TYPE int
- static int cmp(constvoid *a,constvoid *b)
- {
- return *(MY_TYPE *)a > *(MY_TYPE *)b ? 1 : -1;
- }
- int va[10]={6,3,2,4,7,1,9,8,5,0};
- int main(int argc,char **argv)
- {
- int i;
- for(i=0;i<10;i++)
- {
- printf("%d ",va[i]);
- }
- printf("\n");
- qsort(va,10,sizeof(va[0]),cmp);
- for(i=0;i<10;i++)
- {
- printf("%d ",va[i]);
- }
- printf("\n");
- return 0;
- }
*对结构体按一个关键字排序
- #include <stdlib.h>
- #define MY_TYPE _st
- typedef struct _st
- {
- int va;
- char c;
- };
- struct _st st[10];
- static int cmp(constvoid *a,constvoid *b)
- {
- return (*(struct MY_TYPE *)a).va > (*(struct MY_TYPE *)b).va ? 1 : -1;
- }
- int main(int argc,char **argv)
- {
- int i;
- for(i=0;i<10;i++)
- {
- st[i].va=10-i;
- }
- printf("\n");
- qsort(st,10,sizeof(st[0]),cmp);
- for(i=0;i<10;i++)
- {
- printf("%d ",st[i].va);
- }
- printf("\n");
- return 0;
- }
*对结构体多级排序
- int cmp( constvoid *a , constvoid *b )
- {
- struct In *c = (In *)a;
- struct In *d = (In *)b;
- if(c->x != d->x) return c->x - d->x;
- else return d->y - c->y;
- }
*对字符串数组排序
- #include <stdlib.h>
- #define LEN 30+1
- char str[4][LEN];
- static int cmp(constvoid *a,constvoid *b)
- {
- return strcmp((char *)a,(char *)b);
- }
- int main(int argc,char **argv)
- {
- int i;
- strcpy(str[0],"abaa");
- strcpy(str[1],"baaa");
- strcpy(str[2],"baaaa");
- strcpy(str[3],"aasasasaa");
- printf("\n");
- qsort(str,4,sizeof(str[0]),cmp);
- for(i=0;i<4;i++)
- {
- printf("%s\n",str[i]);
- }
- printf("\n");
- return 0;
- }
5、程序中条件语句中的double值的相等判断
double a,b;
.....
if( a == b )
这样不对,应该使用
- #include <math.h>
- ......
- if (fabs(a - b)<= epsilon * fabs(a))
6、C语言中取整的方法
我们知道float或double化为整型可以使用
(int)(a+0.5);但是这样对负数不合适。
应该使用这样的方法
(int)(x<0 ? x - 0.5 : x + 0.5);
7、C中数学方法获得 π 的值
可以自己定义也可以使用数学函数计算
4*atan(1.0) 或 acos(-1.0)
8、如何定义参数可变的函数
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- void __print(constchar *fmt,...)
- {
- va_list argp;
- printf("INFO: ");
- va_start(argp,fmt);
- vprintf(fmt,argp);
- va_end(argp);
- printf("\n");
- }
- int main(int argc,char **argv)
- {
- __print("%s","asddasda");
- return 0;
- }
注意参数个数至少是一个。
9、为什么有的人判断语句的写法如下
if(0 == x)
而不是if( x==0 )
当然这两个都没有错误。这是由于防止"=="写成"="。
当把变量放在前面,“==”写成“=”编译器就会报错,不至于引发不应该出现的BUG
10、如何实现控制台的“转动的小棒”来显示程序的执行进度。
这里需要使用fflush(stdout);来清空输出缓冲区。
- void print1(int ca)
- {
- switch(ca)
- {
- case 0:printf("\\");break;
- case 1:printf("/");break;
- case 2:printf("-");break;
- }
- }
- int main(int argc,char **argv)
- {
- __print("%s","asddasda");
- int i;
- for(i=0;i<10;i++)
- {
- printf("\r");
- print1(i%3);
- fflush(stdout);
- sleep(1);
- }
- return 0;
- }
- C语言使用注意事项(四)
- C语言使用注意事项(四)
- C语言使用注意事项(一)
- C语言使用注意事项(二)
- C语言使用注意事项(三)
- C语言使用注意事项(一)
- C语言使用注意事项(二)
- C语言使用注意事项(三)
- C语言使用注意事项(一)
- C语言使用注意事项(二)
- C语言使用注意事项(三)
- C语言字符串使用注意事项
- 使用C语言(四)
- OC语言注意事项四
- c语言函数指针使用注意事项
- C语言使用fopen的两点注意事项
- c 语言宏 使用的注意事项
- C语言位域使用及其注意事项
- php cannot load php5apache2_2.dll
- vs 2005 Unicode 转 ANSI
- 30+免费快速启动工具软件下载
- 静态变量和静态方法
- Animation的使用(四)
- C语言使用注意事项(四)
- activity之生命周期(笔记)
- 关于工作后定居城市的思考以及房价预测(天涯原创)
- xheditor应用
- 文件批量 复制 粘贴 删除 格式限定
- 为Extjs 树提供数据的递归算法
- <filter-mapping>中的<dispatcher>元素
- 图像处理基本算法 动态阈值分割
- 【整理】ubuntu ln命令简单学习