C語言程式設計:現代方法5

13.字串

自己設計的字串輸入函式需要考慮的問題:
1.在儲存函式之前應該跳過那些空白嘛。
2.什麼字元會導致結束,空白字元,換行符還是某個字元,這些要儲存起來嘛。
3.輸入太多了怎麼辦,是擷取還是留給下次讀入。

//string.h中包含了很多的字串操作:複製,比較,選擇子串,合併等。
//strncpy會安全些,都是返回的目標指標
char* strcpy(char* dest, const char* src);
//得足夠大的
char* strcat();
//比較情況,完全一致比長短,否則按ASCII碼大小,'\0'與0一致
int strcmp(const char* s1, const char* s2);
//字串長度
size_t strlen(const char* s1);
//輸出到字串
int sprintf(day_str, "%2d", str);

這裡寫圖片描述

/* 一些字串操作的慣用法 */
//字串末尾定位
while(*s  )
;
//複製字串
//這個賦值運算子,整體為賦值的值,和這個逗號表示式類似
while(*s   = *p  )
;
/*字串陣列的一種不浪費空間的方法 */
char* p[] = {"23123", "asdasd", "asd6767"};
p[i][j] = 'M'//來尋搜尋元素
/* 命令列引數 */
//argc代表命令列引數的個數,0預設為程式名
main(int argc, char* argv[])

C中的字串字面量不是常量,它的每個字元元素也不是常量,所以字元元素的不可變性僅僅表現在語義層面,但在語法和約束條件上沒有要求。而C 中的字串字面量是常量,每個字元元素也是常量,因此在語義和約束條件兩方面都要求不能改變其中的每個字元元素;另外,處於相容性考慮C 還存在著特殊情況下的向非const指標的轉換。

我們針對字串使用時當然要有空字元結尾,然而有些其他用途包括字元翻譯表就不需要用這個操作。
prinf(某字串時),其實這很危險,如果該字元包含%,輸出結果將非常危險

//檔案尾或錯誤
(ch = getchar()) != '\n'  && (ch != EOF)

14.前處理器

預處理是一個小軟體,他可以在編譯前編輯C語言程式,適度使用。
三種型別:巨集定義,檔案包含,條件編譯。
巨集定義太長可以用\來表示,還有下一行。
巨集會更通用,不像函式引數一樣有型別。

/* 介紹#和##這兩個騷操作 */
//#可以為巨集定義時顯示標籤,將x轉為字串字面型
#define PRINT_INT(x)  printf(#x " =%d", x)
PRINT_INT(i/j);
//##作為粘合劑,即標識之間粘合起來
//GENERIC_MAX(float),有點函式模板的味道了
#define GENERIC_MAX(type)      \
type type##_max(type x, type y)\
{                              \
return x > y ? x : y;       \
}                              

一個巨集的作用範圍為出現到檔案結尾,當然我們可以#undef。

//建立一些很長的巨集
#define ECHO(s) (gets(s), puts(s))
//或者是語句,利用do while必須加分號的騷操作
#define ECHO(str) \
do{               \
gets(s);        \
puts(s);        \
}while(0)         \

還有assert可以幫我們定位錯誤的資訊,比如檔名字及行數。

//一些很有意思的預定義巨集
printf("%s--%s",__TIME__,__DATE__);
//條件編譯
#define DEBUG 1
#if DEBUG
#endif
//巨集測試
#ifdef DEBUF
#endif
//下面介紹條件編譯幾個應用
1.多種作業系統之間互相移植
#if defined(WINDOWS)
#elif  defined(DOS)
#endif
2.C語言編譯器
#if defined(__STDC__)
#else
endif
3.為巨集提供預設定義
#ifndef BUFFSIZE
#define BUFFSIZE 256
#endif
4.巢狀註釋

一些不常用的巨集指令:
1.#pragma
編譯器包含需要執行的指令
2.#error
輸出某些錯誤資訊

#if INT_MAX < 100000000
#error int type is too small
#endif

如果遇到巨集名之前出現過,是不會巨集展開的,否則會無限迴圈。
對於##和#的巢狀使用,大家也要多加註意,一般的技巧是定義新的巨集。
這個if define非常靈活,可以測試多個巨集了。