天天看點

C語言使用注意事項(四)

原創作品,轉載請标明http://blog.csdn.net/yming0221/article/details/7247075

更多檢視

C語言使用注意事項(一)

C語言使用注意事項(二)

C語言使用注意事項(三)

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時運作結果如下:

C語言使用注意事項(四)

這裡可以看出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配置設定的記憶體區,這樣就會導緻系統錯誤。

C語言使用注意事項(四)

*當我們知道字元串的結構,我們可以使用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;
}
           
C語言使用注意事項(四)

4、GCC中qsort()函數使用方法

使用方法

*對int,char,double,float等數組排序方法

#include <stdlib.h>

#define MY_TYPE int
static int cmp(const void *a,const void *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;
}
           
C語言使用注意事項(四)

*對結構體按一個關鍵字排序

#include <stdlib.h>

#define MY_TYPE _st
typedef struct _st
{
        int va;
        char c;
};
struct _st st[10];

static int cmp(const void *a,const void *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;
}
           
C語言使用注意事項(四)

比較函數也可以寫成如下形式

static int cmp(const void *a,const void *b)
{
        return ((struct MY_TYPE *)a)->va > ((struct MY_TYPE *)b)->va ? 1 : -1;
}
           

*對結構體多級排序

int cmp( const void *a , const void *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(const void *a,const void *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;
}
           
C語言使用注意事項(四)

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(const char *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;
}
           
C語言使用注意事項(四)

注意參數個數至少是一個。

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;
}
           

繼續閱讀