1、字符串的表示形式
在C程序中,可以用兩種方法訪問一個字符串:(1)用字符數組存放一個字符串,然后輸出該字符串;(2)用字符指針指向一個字符串。
//定義一個字符數組,對它初始化,然后輸出該字符串 #include<stdio.h> int main(){ char string[]="I love China!"; printf("%s\n",string); return 0; }
和前面介紹的數組屬性一樣,string 是數組名,它代表字符數組的首元素的地址。string[4]代表數組中序號為4的元素(它的值是字母v),實際上string[4]就是善(string+4),string+4是一個地址,它指向字符“v”。
//可以不定義字符數組,而定義一個字符指針。用字符指針指向字符串中的字符。 #include<stdio.h> int main(){ char *string="I love China!"; printf("%s\n",string); return 0; }
在這里沒有定義字符數組,在程序中定義了一個字符指針變量string,用字符串常量“I love China!"對它初始化。C語言對字符串常量是按字符數組處理string的,在內存中開辟了一個字符數組用來存故該字符串常量。對字符指針C變量string初始化,實際上是把字符串第1個元素的地址(即存放字符串的字符數組的首元素地址)賦string。有人誤認為皮,string是一個字符串變量,以為在定義時把“I love China!"這幾個字符賦給該字符串變量,這是不對的。定義string的部分:
char *string="I love China!"
等價於:
char *string; string="I love China!";
可以看到string被定義為一個指針變量,指向字符型數據,請注意它只能指向一個字符變量或其他字符類型數據,不能同時指向多個字符數據,更不是把“I love China!"這些字符存放到string中(指針變量只能存放地址),也不是把字符串賦給* string。只是把“I love China!"的第1個字符的地址賦給指針變量string。
輸出時用printf("%s\n",string);,%s是輸出字符串時所用的格式符,在輸出項中給出字符指針變量名string,則系統先輸出它所指向的一個字符數據,然后自動使string加1,使之指向下一個字符,然后再輸出一個字符.....如此直到遇到字符串結束標志'\0'為止。注意,在內存中,字符串的最后被自動加了一個‘\0',因此在輸出時能確定字符串的終止位置。說明:通過字符數組名或字符指針變量可以輸出一個字符串。而對一個數值型數組,是不能企圖用數組名輸出它的全部元素的。
//將字符串a復制為字符串b #include<stdio.h> int main(){ int i; char a[]="I am a boy!",b[20]; for(i=0;*(a+i)!='\0';i++) *(b+i)=*(a+i); *(b+i)='\0'; printf("string a is:%s\n",a); printf("string b is:"); for(i=0;*(b+i)!='\0';i++) printf("%c",b[i]); printf("\n"); return 0; }
運行結果:
程序中a和b都定義為字符數組,可以通過地址訪問其數組元素。在for語句中,先檢查a[i]是否為'\0'(今a[i]是以*(a+i)形式表示的)。如果不等於'\0’,表示字符串尚未處理完,就將a[i]的值賦給b[i],即復制一個字符。在for循環中將a串全部復制給了b串。最后還應將'\ 0復制過去,即:*(b+i)='\0'。
//也可以用指針變量,用它的值的來改變來指向字符串中不同的字符 #include<stdio.h> int main(){ char a[]="I am a boy!",b[20],*p1,*p2; int i; p1=a; p2=b; for(;*p1!='\0';p1++,p2++) *p2=*p1; *p2='\0'; printf("string a is:%s\n",a); printf("string b is:"); for(p2=b;*p2!='\0';p2++) printf("%c",*p2); printf("\n"); return 0; }
p1、p2是指向字符型數據的指針變量。先使p1和p2的值分別為字符串a和b第1個字符的地址。* p1最初的值為‘I’,賦值語句“*p2=*p1的作用是將字符'I'(a串中第1個字符)賦給p2所指向的元素,即b[0]。然后p1和p2分別加1,指向其下面的一個元素,直到*pl的值為'\0'止。注意p1和p2的值是不斷在改變的,程序必須保證p1和p2同步移動。
2、字符指針作函數參數
//用函數調用實現字符串的復制,用字符數組作參數 #include<stdio.h> void copy(char a[],char b[]){ int i=0; while(a[i]!='\0'){ b[i]=a[i]; i++; } b[i]='\0'; } int main(){ char a[]="I am a teacher!"; char b[]="You are a student!"; printf("string a=%s\nstring b=%s",a,b); printf("\ncopy string a to b:\n"); copy(a,b); printf("string a=%s\nstring b=%s",a,b); return 0; }
運行結果:
注意:b數組最后3個元素仍保留原狀。在輸出b時由於按%s(字符串)輸出,遇'\0'即告結束,因此第一個'\0'后的字符不輸出。如果不采取%s格式輸出而用%c逐個字符輸出是可以輸出后面這些字符的。在main函數中也可以用字符型指針變量作實參,先使指針變量a和b分別指向兩個字符串。函數可改寫如下:
#include<stdio.h> void copy(char a[],char b[]){ int i=0; while(a[i]!='\0'){ b[i]=a[i]; i++; } b[i]='\0'; } int main(){ char m[]="I am a teacher!"; char n[]="You are a student!"; char *a=m,*b=n; printf("string a=%s\nstring b=%s",a,b); printf("\ncopy string a to b:\n"); copy(a,b); printf("string a=%s\nstring b=%s",a,b); return 0; }
以下程序是以形參用字符指針變量實現的:
#include<stdio.h> void copy(char *a,char *b){ for(;*a!='\0';a++,b++){ *b=*a; } *b='\0'; } int main(){ char a[]="I am a teacher!"; char b[]="You are a student!"; printf("string a=%s\nstring b=%s",a,b); printf("\ncopy string a to b:\n"); copy(a,b); printf("string a=%s\nstring b=%s",a,b); return 0; }