'\0' 在 ASCII 中對應數字 0 ;
2. 字面值是程序中表示字符串的一種寫法,用雙引號表示,不可以被修改。
多個相同內容的字面值在程序運行時都是同一個地址。
多個連續的字符串在編譯時會被合併成一個。
char *p = "abc"; // p 表示字符串首地址,該值不能被修改
char *p1 = 'a'; // 錯誤,提示整數類型不可以賦值給指針,傳遞的是 a 對應的 ASCII 值;
// 如果是 char *p1 = "a"; 則正確;傳遞的是 a 在內存中的地址;
printf("%s\n", p);
*p = 'm'; // 錯誤,字符串字面值不可以修改
printf("%p\n", "abc"); // 此處打印出來的地址和上面 p 打印出來的地址一樣
printf("%s\n", "abc""xyz"); // 輸出爲一個字符串:abcxyz;
字符數組也可以表示字符串,它存儲在棧中。可以被修改,可以使用多種方式初始化。
char str[] = "abc";
char str1[3] = "abc"; // 這個寫法不對,因爲 '\0' 沒處放;
char str2[] = {'a', 'b', 'c'}; // 錯誤,沒有 0 ,不可以當數組用
char str3[] = {'a', 'b', 'c', 0}; // 正確
printf("%s\n", str); // 輸出爲:abc
printf("%d\n", sizeof(str) / sizeof(str[0]));
// 計算出字符串數組大小,輸出爲:4。因爲後面還有一個 '\0',在編譯的時候計算機自動加上。
str[0] = 'm'; // 數組表示的字符串可以改動,和上面的字面值不一樣
str[1] = 0;
printf("%s\n", str); // 輸出爲:m,因爲第二個爲 0,所以計算機自動停止
3. 字符串數組常用操作:(denglu.c)
首先,字符串數組要包含頭文件: #include <string.h>
fgets 函數用來從鍵盤讀取字符串,不會出現字符數組溢出問題;
strlen 計算字符串長度(實際長度);
strcat 合併兩個字符串,第二個參數的首字符必須爲 char 類型;
此函數容易導致合併後長度過長,溢出。
strncat 合併字符串,且避免溢出。
strcpy 賦值字符串,同樣容易溢出。
strncpy 賦值字符串,且避免溢出。
strcmp 通過 ASCII 比較字符串大小。前者大,返回 1;後者大返回 -1;一樣大返回 0。
strncmp 比較兩字符串中前 n 個字符大小。
#include <string.h>
char buf[10] = {0};
fgets(buf, 10, stdin); // 若輸入字符超過9個,只提取前面9個,最後留一個0位置。若少於9個,那麼會把\n讀進去。
printf("%d\n", strlen(buf)); // 計算字符串有效字符長度(不包括 “\0”)
char str[10] = "abc";
strcat(str, "x0yz"); // str = str + "x0yz";
strcpy(str, "wqq"); // str = "wqq";
strcmp("abc","acd"); // 返回 -1
char arr[10];
printf ("%d\n", sizeof (arr)); // 10
printf ("%d\n", strlen (arr)); // 9
4. main函數參數(瞭解即可,很少使用)
int main(int argc, char *argv[])
5. 預處理命令 #define 專門給數字取名字,如給 3.14 取名字:
#define PI 3.14f // 後面不可以加分號,也不可以加賦值等號。
用#define取的名字叫宏,如此處 PI 即爲宏;名字之間不能有空格,即不能寫爲:P I;
另外一種宏定義方式:
在gcc(終端)裏面輸入:gcc -D PI=3014 code.c
6. 宏不僅可以定義數字,還可以定義公式等,即帶參數宏:
#define PI 3.14f
#define CIRCLE(r) 2 * PI * (r) // 一般給參數加個(),保證參數先運算
#define SQRE (60 * 60) // 若是個計算式,記得加個括號
#define SQUARE(n) ((n) * (n))
#define STR(n) #n // 把參數字符串化,相當於 “n”,如:STR(6+3),輸出結果爲:6+3
#define PTR(n) p_##n // 重命名標誌符,如:PTR(value),輸出結果爲:p_value
宏的參數既是輸入參數,又是輸出參數;且參數要用()。
不要使用自增或自減作爲參數傳遞給宏。
編譯器預定義的一些宏:
printf("%d\n", __LINE__); // 顯示當前行號
printf("%s\n", __FILE__); // 當前文件名
printf("%s\n", __DATE__); // 當前編譯日期
printf("%s\n", __TIME__); // 當前編譯時間
printf("%s\n", __STDC__ ? "符合" : "不符合"); // 查看編譯器是否符合C標準,如果符合打印“符合”,反之“不符合”;
問:論述含參數的宏與函數的優缺點 ?
答: 帶參宏 函數
---------------------------
處理時間 編譯時 程序運行時
參數類型 沒有參數類型問題 定義實參、形參類型
處理過程 不分配內存 分配內存
程序長度 變長 不變
運行速度 不佔運行時間 調用和返回佔用時間
7. 條件編譯:
#ifdef 宏名稱 // 或者(#ifndef 宏名稱)
***
#else
***
#endif
舉例如下:
#define ONE
int main()
{
#ifdef ONE // 如果定義了ONE宏,則運行下面語句,打印one,否則運行else,打印two
printf("one");
#else
printf("two");
#endif
retrun 0;
}
類似形式如下:
#define ONE
int main()
{
#ifndef ONE // 如果沒定義ONE,打印one,否則打印two。
printf("one");
#else
printf("two");
#endif
retrun 0;
}
8. 條件編譯:
#if 條件表達式 // 這樣的條件編譯範圍變大,#ifdef 相當於 #if defined(宏名稱) ,此條件表達式末尾沒有符號
***
#else
***
#endif
多條件編譯:
#if 條件表達式
***
#elif 條件表達式
***
***
#else
***
#endif