1、定義的時候直接用字符串賦值
char a[10]="hello";
注意:不能先定義再給它賦值剃法,如char a[10]; a[10]="hello";這樣是錯誤的矾睦!
2、對數(shù)組中字符逐個賦值
char a[10]={'h','e','l','l','o'};
3剧罩、利用strcpy
char a[10]; strcpy(a, "hello");
易錯情況:
1栓拜、char a[10]; a[10]="hello";//一個字符怎么能容納一個字符串座泳?況且a[10]也是不存在的!
2幕与、char a[10]; a="hello";//這樣的情況easy出現(xiàn)挑势,a盡管是指針,可是它已經(jīng)指向在堆棧中分配的10個字符空間啦鸣,如今這個情況a又指向數(shù)據(jù)區(qū)中的hello常量潮饱,這里的指針a出現(xiàn)混亂,不同意诫给!
還有:不能使用關(guān)系運算符“==”來比較兩個字符串香拉,僅僅能用strcmp() 函數(shù)來處理。
C語言的運算符根本無法操作字符串中狂。在C語言中把字符串當(dāng)作數(shù)組來處理凫碌,因此,對字符串的限制方式和對數(shù)組的一樣胃榕,特別是盛险,它們都不能用C語言的運算符進行復(fù)制和比較操作。
直接嘗試對字符串進行復(fù)制或比較操作會失敗。比如苦掘,假定str1和str2有例如以下聲明:
char str1[10], str2[10];
利用=運算符來把字符串拷貝到字符數(shù)組中是不可能的:
str1 = "abc"; /*** WRONG ***/
str2 = str1; /*** WRONG ***/
C語言把這些語句解釋為一個指針與還有一個指針之間的(非法的)賦值運算换帜。可是鹤啡,使用=初始化字符數(shù)組是合法的:
char str1[10] = "abc";
這是由于在聲明中惯驼,=不是賦值運算符。
試圖使用關(guān)系運算符或判等運算符來比較字符串是合法的揉忘,但不會產(chǎn)生預(yù)期的結(jié)果:
if (str1==str2) ... /*** WRONG ***/
這條語句把str1和str2作為指針來進行比較跳座,而不是比較兩個數(shù)組的內(nèi)容。由于str1和str2有不同的地址泣矛,所以表達式str1 == str2的值一定為0疲眷。
動態(tài)數(shù)組的定義使用:
數(shù)組究竟應(yīng)該有多大才合適,有時可能不得而知您朽。所以希望可以在執(zhí)行時具有改變數(shù)組大小的能力狂丝。
動態(tài)數(shù)組就行在不論什么時候改變大小。
通俗的說靜態(tài)數(shù)組就是在定義數(shù)組的時候哗总,由操作系統(tǒng)分配的空間几颜,比方
int a[10];
這就是在定義時由系統(tǒng)給你分配了10個int類型的空間,這個空間是能夠初始化的讯屈,比方
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}蛋哭;
那么在這個定義之后,系統(tǒng)會首先分配10個int類型的存儲空間涮母,然后把大括號中面的數(shù)字分別的谆趾,按順序放到這10個空間里。你所做的僅僅是寫這么一句叛本,而數(shù)組賦值的操作就由系統(tǒng)完畢了沪蓬。當(dāng)然,初始化與否看你的需求来候,初始化不是強制性操作跷叉,想初始化就初始化,不想也沒問題营搅,還是上面的樣例繼續(xù):
int a[10];
這里定義了云挟,可是沒初始化,這沒有不論什么問題转质,以后你能夠自己往里面賦值园欣,比方
a[1] = 8;
a[5] = 3;
或者
for(int i = 0; i < 10; i++)
a[i] = i;
等等
對于動態(tài)數(shù)組,不能被初始化峭拘,由于動態(tài)數(shù)組在定義時僅僅是個指針俊庇,比方
int *a;
這里變量a僅僅是個指向int類型的指針狮暑,而不是數(shù)組。動態(tài)分配有10個int類型元素的數(shù)組辉饱,例如以下:
a = (int * ) malloc(10*sizeof(int));
非常明顯搬男,指針a在定義的時候不能被初始化,比方這樣寫就是錯誤的:
int a = {1,2,3,4,5,6,7,8,9,10}; / 錯誤彭沼! */
由于a是僅僅有4個字節(jié)的指針缔逛,沒有可用的存儲空間給須要初始化的變量。
在C語言編程中姓惑,當(dāng)我們聲明一個字符串?dāng)?shù)組的時候褐奴,常常需要把它初始化為空串∮诒校總結(jié)起來有以下三種方式:
(1) char str[10]="";
(2) char str[10]={'\0'};
(3) char str[10]; str[0]='\0';
第(1)(2)種方式是將str數(shù)組的所有元素都初始化為'\0'敦冬,而第(3)種方式是只將str數(shù)組的第一個元素初始化為'\0'。如果數(shù)組的size非常大唯沮,那么前兩種方式將會造成很大的開銷脖旱。
所以,除非必要(即我們需要將str數(shù)組的所有元素都初始化為0的情況)介蛉,我們都應(yīng)該選用第(3)種方式來初始化字符串?dāng)?shù)組萌庆。
1. 基本問題
數(shù)組可以初始化,即在定義時币旧,使它包含程序馬上能使用的值践险。
例如,下面的代碼定義了一個全局數(shù)組吹菱,并用一組Fibonacci數(shù)初始化:
1 int iArray[10]={1巍虫,1,2毁葱,3垫言,5贰剥,8倾剿,13,21蚌成,34前痘,55); //初始化
2 void main()
3 {
4 //...
5 }
初始化數(shù)組的值的個數(shù)不能多于數(shù)組元素個數(shù)担忧,初始化數(shù)組的值也不能通過跳過逗號的方式來省略芹缔,這在C中是允許的,但在C++中不允許瓶盛。
初始化值的個數(shù)可少于數(shù)組元素個數(shù)最欠。當(dāng)初始化值的個數(shù)少于數(shù)組元素個數(shù)時示罗,前面的按序初始化相應(yīng)值, 后面的初始化為0(全局或靜態(tài)數(shù)組)或為不確定值(局部數(shù)組)芝硬。
2.初始化字符數(shù)組
初始化字符數(shù)組有兩種方法蚜点,一種是:
char array[10]={"hello"};
另一種是:
char array[10]={'h','e','l','l','\0'}拌阴;
第一種方法用途較廣绍绘,初始化時,系統(tǒng)自動在數(shù)組沒有填值的位置用迟赃,'\0'補上陪拘。另外, 這種方法中的花括號可以省略纤壁,即能表示成:
char array[10]="hello"左刽;
第二種方法一次一個元素地初始化數(shù)組,如同初始化整型數(shù)組酌媒。這種方法通常用于輸入不容易在鍵盤上生成的那些不可見字符悠反。
例如,下面的代碼中初始化值為若干制表符:
char chArray[5]={'\t','\t','\t','\t','\0')馍佑;
這里不要忘記為最后的斋否,'\0'分配空間。如果要初始化一個字符串"hello"拭荤,那為它定義的數(shù)組至少有6個數(shù)組元素茵臭。
例如,下面的代碼給數(shù)組初始化舅世,但會引起不可預(yù)料的錯誤:
char array[5]="hello"旦委;
該代碼不會引起編譯錯誤,但由于改寫了數(shù)組空間以外的內(nèi)存單元雏亚,所以是危險的缨硝。
3.省略數(shù)組大小
有初始化的數(shù)組定義可以省略方括號中的數(shù)組大小。
例如罢低,下面的代碼中數(shù)組定義為5個元素:
int a[]={2查辩,4,6网持,8宜岛,10};
編譯時必須知道數(shù)組的大小功舀。通常萍倡,聲明數(shù)組時方括號內(nèi)的數(shù)字決定了數(shù)組的大小。有初始化的數(shù)組定義又省略方括號中的數(shù)組大小時辟汰,編譯器統(tǒng)計花括號之間的元素個數(shù)列敲,以求出數(shù)組的大小阱佛。
例如,下面的代碼產(chǎn)生相同的結(jié)果:
static int a1[5]={1戴而,2瘫絮,3,4填硕,5};
static int a2[]={1麦萤,2,3扁眯,4壮莹,5};
讓編譯器得出初始化數(shù)組的大小有幾個好處姻檀。它常常用于初始化一個元素個數(shù)在初始化中確定的數(shù)組命满,提供程序員修改元素個數(shù)的機會。
在沒有規(guī)定數(shù)組大小的情況下绣版,怎么知道數(shù)組的大小呢? sizeof操作解決了該問題胶台。
1、字符數(shù)組的定義與初始化
字符數(shù)組的初始化杂抽,最容易理解的方式就是逐個字符賦給數(shù)組中各元素诈唬。
char str[10]={ 'I',' ','a','m',' ',‘h’,'a','p','p','y'};
即把10個字符分別賦給str[0]到str[9]10個元素
如果花括號中提供的字符個數(shù)大于數(shù)組長度,則按語法錯誤處理缩麸;若小于數(shù)組長度铸磅,則只將這些字符數(shù)組中前面那些元素,其余的元素自動定為空字符(即'\0' )杭朱。
2阅仔、字符數(shù)組與字符串
在c 語言中,將字符串作為字符數(shù)組來處理弧械。(c++中不是)在實際應(yīng)用中人們關(guān)心的是有效字符串的長度而不是字符數(shù)組的長度八酒,例如,定義一個字符數(shù)組長度為100刃唐,而實際有效字符只有40個羞迷,為了測定字符串的實際長度,C 語言規(guī)定了一個“字符串結(jié)束標(biāo)志”闭树,以字符'\0’代表耸棒。如果有一個字符串,其中第10個字符為'\0'与殃,則此字符串的有效字符為9個碍现。也就是說,在遇到第一個字符'\0'時昼接,表示字符串結(jié)束,由它前面的字符組成字符串慢睡。
系統(tǒng)對字符串常量也自動加一個'\0'作為結(jié)束符。例如"C Program”共有9個字符漂辐,但在內(nèi)存中占10個字節(jié),最后一個字節(jié)'\0'是系統(tǒng)自動加上的髓涯。(通過sizeof()函數(shù)可驗證)
有了結(jié)束標(biāo)志'\0'后,字符數(shù)組的長度就顯得不那么重要了纬纪,在程序中往往依靠檢測'\0'的位置來判定字符串是否結(jié)束,而不是根據(jù)數(shù)組的長度來決定字符串長度滑肉。當(dāng)然包各,在定義字符數(shù)組時應(yīng)估計實際字符串長度,保證數(shù)組長度始終大于字符串實際長度靶庙。(在實際字符串定義中髓棋,常常并不指定數(shù)組長度,如char str[ ])說明:'\0代表ASCII 碼為0的字符惶洲,從ASCII 碼表中可以查到ASCII 碼為0的字符不是一個可以顯示的字符按声,而是一個“空操作符”,即它什么也不干恬吕。用它來作為字符串結(jié)束標(biāo)志不會產(chǎn)生附加的操作或增加有效字符签则,只起一個供辨別的標(biāo)志。
對C 語言處理字符串的方法由以上的了解后铐料,再對字符數(shù)組初始化的方法補充一種方法——即可以用字符串常量來初始化字符數(shù)組:
char str[ ]={"I am happy"};
可以省略花括號渐裂,如下所示
char str[ ]="I am happy";
注意:上述這種字符數(shù)組的整體賦值只能在字符數(shù)組初始化時使用,不能用于字符數(shù)組的賦值钠惩,字符數(shù)組的賦值只能對其元素一一賦值柒凉,下面的賦值方法是錯誤的
char str[ ];
str="I am happy";//錯誤,字符數(shù)組的賦值只能按元素一一賦值
不是用單個字符作為初值篓跛,而是用一個字符串(注意:字符串的兩端是用雙引號“”而不是單引號‘’括起來的)作為初值膝捞。顯然,這種方法更直觀方便愧沟。(注意:數(shù)組str 的長度不是10蔬咬,而是11鲤遥,這點請務(wù)必記住,因為字符串常量"I am happy"的最后由系統(tǒng)自動加上一個'\0')
因此林艘,上面的初始化與下面的初始化等價
char str[ ]={'I',' ','a','m',' ','h','a','p','p','y','\0'};
而不與下面的等價
char str[ ]={'I',' ','a','m',' ','h','a','p','p','y'};
前者的長度是11盖奈,后者的長度是10.
說明:字符數(shù)組并不要求它的最后一個字符為'\0',甚至可以不包含'\0'狐援,向下面這樣寫是完全合法的钢坦。
char str[5]={'C','h','i','n','a'};
可見,用兩種不同方法初始化字符數(shù)組后得到的數(shù)組長度是不同的啥酱。
include <stdio.h>
void main(void)
{
char c1[]={'I',' ','a','m',' ','h','a','p','p','y'};
char c2[]="I am happy";
int i1=sizeof(c1);
int i2=sizeof(c2);
printf("%d\n",i1);
printf("%d\n",i2);
}
結(jié)果:10 11
3场钉、字符串的表示形式
在C 語言中,可以用兩種方法表示和存放字符串:
(1)用字符數(shù)組存放一個字符串
<span style="color:#330033;">char str[ ]="I love China";</span>
(2)用字符指針指向一個字符串
<span style="color:#330033;">char* str="I love China";</span>
對于第二種表示方法懈涛,有人認為str 是一個字符串變量逛万,以為定義時把字符串常量"I love China"直接賦給該字符串變量,這是不對的批钠。C 語言對字符串常量是按字符數(shù)組處理的宇植,在內(nèi)存中開辟了一個字符數(shù)組用來存放字符串常量,程序在定義字符串指針變量str 時只是把字符串首地址(即存放字符串的字符數(shù)組的首地址)賦給str埋心。
兩種表示方式的字符串輸出都用
printf("%s\n",str);
%s 表示輸出一個字符串,給出字符指針變量名str(對于第一種表示方法拷呆,字符數(shù)組名即是字符數(shù)組的首地址茬斧,與第二種中的指針意義是一致的),則系統(tǒng)先輸出它所指向的一個字符數(shù)據(jù)绣溜,然后自動使str 自動加1怖喻,使之指向下一個字符岁诉,如此,直到遇到字符串結(jié)束標(biāo)識符" \0 "哗蜈。
4恬叹、對使用字符指針變量和字符數(shù)組兩種方法表示字符串的討論
雖然用字符數(shù)組和字符指針變量都能實現(xiàn)字符串的存儲和運算同眯,但它們二者之間是有區(qū)別的,不應(yīng)混為一談硅确。
4.1菱农、字符數(shù)組由若干個元素組成,每個元素放一個字符循未;而字符指針變量中存放的是地址(字符串/字符數(shù)組的首地址)的妖,絕不是將字符串放到字符指針變量中(是字符串首地址)
4.2嫂粟、賦值方式:
對字符數(shù)組只能對各個元素賦值吟吝,不能用以下方法對字符數(shù)組賦值
char str[14];
str="I love China"; //錯誤镊讼,不是初始化,這是賦值护糖,只能一一進行嚼松。
(但在字符數(shù)組初始化時可以,即char str[14]="I love China";)
而對字符指針變量寝受,采用下面方法賦值:
char* a;
a="I love China";//指針賦值很澄,可以
或者是char* a="I love China"; 都可以
4.3甩苛、對字符指針變量賦初值(初始化):
char* a="I love China";
等價于:
char* a;
a="I love China";
而對于字符數(shù)組的初始化
char str[14]="I love China";
不能等價于:
char str[14];
str="I love China"; (這種不是初始化,而是賦值痊土,而對數(shù)組這樣賦值是不對的)
4.4赁酝、如果定義了一個字符數(shù)組旭等,那么它有確定的內(nèi)存地址,不能進行多次賦值;而定義一個字符指針變量時隙袁,它并未指向某個確定的字符數(shù)據(jù)菩收,并且可以多次賦值坛梁。
5腊凶、字符串處理函數(shù)
5.1 字符串連接
char *strcat(char *str1,const char *2 );
char *strcat(char *strDestination,const char *strSource );
功能:函數(shù)將字符串str2 連接到str1的末端钧萍,并返回指針str1
注:連接前兩個字符串的后面都有一個' \0 ',連接時將字符串1后面的' \0 ‘去掉队魏,只在新串最后保留一個' \0 ‘
5.2 字符串復(fù)制
char *strcpy(char *str1,const char *2 );
char *strcpy(char *strDestination,const char *strSource );
功能:復(fù)制字符串strSource 中的字符到字符串strDestination胡桨,包括空值結(jié)束符瞬雹。返回值為指針strDestination。
注:
1呢诬、“字符數(shù)組1”必須寫成數(shù)組名形式,“字符串2"可以是字符數(shù)組名阀圾,也可以是一個字符串常量
2狗唉、復(fù)制時連同字符串后面的' \0 ' 一起復(fù)制到數(shù)組1中
3、不能用賦值語句直接將一個字符串常量或者字符數(shù)組直接賦給一個字符數(shù)組(同普通變量數(shù)組是一樣的)账月,而只能用strcpy 函數(shù)處理。
4剧劝、可以用strcpy 函數(shù)將字符串2中的前若干個字符復(fù)制到字符數(shù)組1中去。