查看: 2220|回复: 0

[Linux技术] C语言使用注意事项(四)

[复制链接]
  • TA的每日心情

    2014-4-10 13:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-1-23 08:56:21 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 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 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-17 00:40 , Processed in 0.107046 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.