回答

收藏

[原创] C语言使用注意事项(四)

飞凌嵌入式 飞凌嵌入式 2741 人阅读 | 0 人回复 | 2014-01-23

本帖最后由 forlinx2013 于 2014-1-24 09:23 编辑

欢迎大家来到飞凌爱板网专区,对嵌入式技术感兴趣的朋友不妨多多关注一下,我们提供了公司所有开发板的所有资料,也会更新大量技术文章,欢迎大家一块学习提高!!!

1scanf()输入注意
当你使用scanf("%d",&a),然后用gets()读取下一行的一个字符串时,调用后好像gets()函数没有执行。
原因:这是由于scanf()函数不处理回车换行符。这样以来gets()函数读取的只是回车换行符。所以好像时gets()函数没有执行。
解决方法:可以在scanf()函数后插入一个getchar()函数来吃掉那个回车换行符。

2scanf()的缓冲区问题
为什么说scanf()函数有问题呢?就因为它适用于结构化,格式相对整齐的数据输入。
例如下面的例子
1 #include <stdio.h>  
2   
3 int main(int argc,char **argv)  
4 {         
5         char a;  
6         while(1)  
7         {  
8                 scanf("%c",&a);  
9                 printf("a=%c\n",a);  
10         }  
11         return 0;  
12 }  

当输入连续asdfg时运行结果如下:
这里可以看出scanf()读取数据到缓冲区,当缓冲区不空时从缓冲区截取,当缓冲区为空时,再读一组数据到缓冲区。所以为保证安全
*可以在每次scanf()后加一个清空缓冲区的语句fflush(stdin),但是这不是所有的编译器都支持的,VC6.0支持,但是GCC不支持。
*使用scanf()的替代功能函数。可以先用fgets()读入一整行,然后用字符串处理函数进行字符串处理(strtok(),strtol(),atoi())

3printf()sprintf()函数
就像scanf()函数一样,这两个函数也存在缓冲区的问题,例如输出一个字符串,当你不可预测字符串的长度时,可能存在字符串的过长导致缓冲区溢出,从而影响其他内存区。
如下例子:
13 int main(int argc,char **argv)  
14 {  
15         char a[11]={0};  
16         const char *p="12345678901234";  
17         sprintf(a,"%s",p);  
18         printf("a= %s\n",a);  
19   
20         return 0;  
21 }  

p的长度大于系统给a分配的内存区,这样就会导致系统错误。
*当我们知道字符串的结构,我们可以使用sprintf(a,"%10s",p);防止超越内存区。
*使用snprintf()函数原型int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...);
例如
22 int main(int argc,char **argv)  
23 {  
24         char a[11]={0};  
25         const char *p="12345678901234";  
26         snprintf(a,sizeof(a),"%s",p);  
27         printf("a= %s\n",a);  
28   
29         return 0;  
30 }  


4GCCqsort()函数使用方法
使用方法
*int,char,double,float等数组排序方法
31 #include <stdlib.h>  
32   
33 #define MY_TYPE int  
34 static int cmp(const void *a,const void *b)  
35 {  
36         return *(MY_TYPE *)a > *(MY_TYPE *)b ? 1 : -1;  
37 }  
38 int va[10]={6,3,2,4,7,1,9,8,5,0};  
39   
40 int main(int argc,char **argv)  
41 {  
42         int i;  
43         for(i=0;i<10;i++)  
44         {  
45                 printf("%d ",va);  
46         }  
47         printf("\n");  
48         qsort(va,10,sizeof(va[0]),cmp);  
49         for(i=0;i<10;i++)  
50         {  
51                 printf("%d ",va);  
52         }  
53         printf("\n");  
54         return 0;  
55 }  
*对结构体按一个关键字排序
56 #include <stdlib.h>  
57   
58 #define MY_TYPE _st  
59 typedef struct _st  
60 {  
61         int va;  
62         char c;  
63 };  
64 struct _st st[10];  
65   
66 static int cmp(const void *a,const void *b)  
67 {  
68         return (*(struct MY_TYPE *)a).va > (*(struct MY_TYPE *)b).va ? 1 : -1;  
69 }  
70 int main(int argc,char **argv)  
71 {  
72         int i;  
73         for(i=0;i<10;i++)  
74         {  
75                 st.va=10-i;  
76         }  
77         printf("\n");  
78         qsort(st,10,sizeof(st[0]),cmp);  
79         for(i=0;i<10;i++)  
80         {  
81                 printf("%d ",st.va);  
82         }  
83         printf("\n");  
84         return 0;  
85 }  
比较函数也可以写成如下形式
86 static int cmp(const void *a,const void *b)  
87 {  
88         return ((struct MY_TYPE *)a)->va > ((struct MY_TYPE *)b)->va ? 1 : -1;  
89 }  


*对结构体多级排序
90 int cmp( const void *a , const void *b )   
91 {   
92 struct In *c = (In *)a;   
93 struct In *d = (In *)b;   
94 if(c->x != d->x) return c->x - d->x;   
95 else return d->y - c->y;   
96 }   
*对字符串数组排序
97 #include <stdlib.h>  
98 #define LEN 30+1  
99   
100 char str[4][LEN];  
101   
102 static int cmp(const void *a,const void *b)  
103 {  
104         return strcmp((char *)a,(char *)b);  
105 }  
106 int main(int argc,char **argv)  
107 {  
108         int i;  
109         strcpy(str[0],"abaa");  
110         strcpy(str[1],"baaa");  
111         strcpy(str[2],"baaaa");  
112         strcpy(str[3],"aasasasaa");  
113   
114   
115         printf("\n");  
116         qsort(str,4,sizeof(str[0]),cmp);  
117         for(i=0;i<4;i++)  
118         {  
119                 printf("%s\n",str);  
120         }  
121         printf("\n");  
122         return 0;  
123 }  

5、程序中条件语句中的double值的相等判断
double a,b;
.....
if( a == b )
这样不对,应该使用
124 #include <math.h>  
125 ......  
126 if (fabs(a - b)<= epsilon * fabs(a))  

6C语言中取整的方法
我们知道floatdouble化为整型可以使用
(int)(a+0.5);但是这样对负数不合适。
应该使用这样的方法
(int)(x<0 ? x - 0.5 : x + 0.5);
7C中数学方法获得 π 的值
可以自己定义也可以使用数学函数计算
4*atan(1.0) acos(-1.0)
8、如何定义参数可变的函数
127 #include <stdio.h>  
128 #include <stdlib.h>  
129 #include <stdarg.h>  
130   
131 void __print(const char *fmt,...)  
132 {  
133         va_list argp;  
134         printf("INFO: ");  
135         va_start(argp,fmt);  
136         vprintf(fmt,argp);  
137         va_end(argp);  
138         printf("\n");  
139 }  
140 int main(int argc,char **argv)  
141 {  
142         __print("%s","asddasda");  
143         return 0;  
144 }  
注意参数个数至少是一个。
9、为什么有的人判断语句的写法如下
if(0 == x)
而不是if( x==0 )
当然这两个都没有错误。这是由于防止"=="写成"="
当把变量放在前面,“==”写成“=”编译器就会报错,不至于引发不应该出现的BUG
10、如何实现控制台的“转动的小棒”来显示程序的执行进度。
这里需要使用fflush(stdout);来清空输出缓冲区。
145 void print1(int ca)  
146 {  
147         switch(ca)  
148         {  
149                 case 0:printf("\\");break;  
150                 case 1:printf("/");break;  
151                 case 2:printf("-");break;  
152         }  
153 }  
154 int main(int argc,char **argv)  
155 {  
156         __print("%s","asddasda");  
157         int i;  
158         for(i=0;i<10;i++)  
159         {  
160                 printf("\r");  
161                 print1(i%3);  
162                 fflush(stdout);  
163                 sleep(1);  
164         }  
165         return 0;  
166 }  
分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条