11-1:字符串表示和字符串I/Oswift
1.首先先經過一個總體的例子來初步瞭解創建,讀入和輸出字符串的幾種方式。數組
#include<stdio.h> #define MSG "你必定有不少智慧,告訴我一些吧!" #define LIM 5 #define LINELEN 81 int main(){ char name[LINELEN]; char talents[LINELEN]; int i ; const char m1[40] = "Limit yourself to one line's worth. "; const char m2[] = "If you can't think of anything,fake it. "; const char *m3 = "\nEnough about me - what's your name? "; const char *mytal[LIM] = { "Adding numbers swiftly", "MUltiplying accurately ", "Stashing data", "Following instructions to the letter", "Understanding the C language" }; printf("你好阿,我是電腦機器人,我有一些智慧\n"); printf("他們是什麼呢?哦,對了,這裏有部分清單:"); for(i = 0 ; i < LIM ; i++){ puts(mytal[i]); } puts(m3); gets(name); printf("哦,%s,%s\n",name,MSG); printf("%s\n%s",m1,m2); gets(talents); puts("Let's see if I've got that list: "); puts(talents); printf("謝謝你的信息,%s\n",name); return 0; }
2.定義字符串:基本的方法有字符串常量,char數組,char指針和字符串數組。函數
1)字符串常量:屬於靜態存儲,是指若是在一個函數中使用字符串常量,即便屢次調用這個函數,這個字符串在程序的整個運行過程當中只存儲一份。整個引號的內容做爲指向該字符串存儲位置的指針。spa
例如:指針
#include<stdio.h> int main(){ printf("%s,%p,%c\n","We","are",*"World"); }
顯示結果爲:We 0x2321342 Wcode
2)字符串數組及其初始化blog
第一種方法是定義數組的大小,而後給出字符串。ip
第二種方法是不給出數組的大小,而後給出字符串,大小由編譯器計算。內存
第三種方法是若是定義的數組須要在程序運行時才放入字符,那麼必需要指明數組的大小。字符串
第四種方法任何數組名都是數組首元素的地址。m1 == &m1[0]
第五種方法是用指針符號來創建字符串:例如 const char *m3 = "Hello" 它和char m3[] = "Hello" 做用幾乎相同。
3. 可是也存在區別:數組初始化是從靜態存儲區把一個字符串複製給數組,而指針初始化只是複製字符串的地址。
#include<stdio.h> int main(){ char heart[] = "I love Tillie!"; char *head = "I love Millie!"; int i ; for(i = 0 ; i < 6 ; i++){ putchar(heart[i]); } printf("\n"); for( i = 0 ; i < 6 ; i++){ putchar(head[i]); } }
4.在這個程序中,咱們學到的知識: 1)*head =head[0] 2)若是head = heart。那麼head就指向了heart字符串,那麼原來的Millie仍是存在的,可是若是沒有保存這個字符串的地址的話,就沒有辦法再訪問這個字符串了,石沉大海了。很難遇到。
這裏須要引入一個問題,char *word = "frame" , word[1] = 'l' => 這樣作容許嗎? 解答:可能編譯器容許這麼作,可是會形成內存訪問錯誤。若是編譯器使用這種單個拷貝表示法容許把第一個字符改變,那將影響到全部對這個字符串的使用,建議的作法是初始化一個指向字符串文字的指針使用const修飾符, const char *p1 = "Klingon" ;
5.字符串數組:像最上面的程序中定義了一個指針字符數組。
這樣的一個字符數組在解釋上相似於一個二維數組。
區別是前一個是存放地址的數組,後者是放着完整的字符數組。
最後要創建一種認識,絕大多數字符串使用的都是指針。觀察這個程序
#include<stdio.h> int main(){ char *mesg = "Don't be a fool!"; char *copy; copy = mesg; printf("%s",copy); printf("mesg = %s,&mesg = %p;value = %p\n",mesg,&mesg,mesg); printf("copy = %s,© = %p;value = %p\n",copy,©,copy
這個運行結果代表:兩個指針變量指向的都是同一個字符串。
11-2:字符串的輸入: gets()函數 scanf() 函數 fgets()函數
注意:在輸入字符串的時候,要提早申明一塊足夠大的區域給它,計算機是不會計算字符串的長度的,後果是會致使輸入的字符覆蓋程序中其餘的數據和代碼,致使程序異常終止。
1.gets()函數:從系統的標準輸入設備得到一個字符串,當讀到\n的時候,中止輸入,捨去\n,補充\0。gets()函數若是成功讀取字符串,會返回這個字符串的地址,例如char *ptr , ptr = gets(name);若是出錯或者遇到文件結尾,它返回一個空(或0)地址。稱爲空指針。在<stdio.h>中用NULL來表示。gets(name)!=NULL
2.fgets()函數:fgets()函數要求指定最大的字符數,fgets(name,MAX,stdin) ,若是遇到換行符,也會把它讀取,而不會扔掉。若是成功讀取了字符串,會返回這個字符串的地址。若是出錯或者遇到文件結尾,它會返回一個空(或0)地址。
3.scanf()函數:比較的約束,%s,遇到空白符(空格,製表符,換行符)等都會中止。若是%10s,那麼函數就會讀取10個或如下中止。若是成功讀取了字符,它會返回讀取字符的個數,不然返回EOF。
最後總結:gets()函數讀取文本更快更好,scanf()函數主要以某種標準輸入的混合類型數據的讀取和轉換。