數(shù)組和指針
Int powers[8] = {1,2,4,6,8,16,32,64};初始化僅asic C,
常量數(shù)組:const int days[months]={31,28,31,30,31,30,31,31,30,31,30,31};
在函數(shù)的內(nèi)部聲明,并且沒(méi)有使用關(guān)鍵字static,不同的存儲(chǔ)類具有不同的屬性,因此不能把本章的只是推廣到其它的存儲(chǔ)類。例如:沒(méi)有進(jìn)行初始化,一些存儲(chǔ)類的變量和數(shù)組會(huì)把它們的存儲(chǔ)單元設(shè)置為0;數(shù)組則直接讀取上面的內(nèi)容。
如果不初始化數(shù)組,數(shù)組元素和未初始化的普通變量一樣,其中存儲(chǔ)的是無(wú)用的數(shù)值;但是如果部分初始化數(shù)組,未初始化的元素則被設(shè)置為0;
如果初始化列表中的項(xiàng)目的個(gè)數(shù)大于數(shù)組大小,編譯器會(huì)毫不留情地認(rèn)為這是一個(gè)錯(cuò)誤。但是用另外一種形式可以避免受到編譯器的此類奚落:您可以省略括號(hào)中的數(shù)字,從而讓編譯器自動(dòng)匹配數(shù)組的大小,和初始化列表中的項(xiàng)目數(shù)目。
Sizeof days / sizeof days[0];
C99可以對(duì)單個(gè)數(shù)組元素賦值,
Int arr[6] = {[5] = 212};其它的都為0;
又如:
Int days[MONTHS] = {31,28,[4] = 31,30,31,[1] = 29};
結(jié)果為:31,29,0,0,31,30,31,0,0,0,0,0;

聲明數(shù)組時(shí)在方括號(hào)內(nèi)只能使用整數(shù)常量表達(dá)式,整數(shù)常量表達(dá)式是由整數(shù)常量組成的表達(dá)式,sizeof表達(dá)式被認(rèn)為是一個(gè)整數(shù)常量。而和c++不一樣,一個(gè)const值卻不是整數(shù)常量。并且該表達(dá)式的值必須大于0;

在形參的形式中
Fun(Int * char para1)等價(jià)于 fun(int para1[]);
Int * p1,*p2,*p3;這說(shuō)明int *不是一個(gè)整體,int只是修飾指針的類型,* 是指針類型(猜測(cè)),可能定義一個(gè)變量要2部分,int是第一部分,*是第二部分,平常只要第一部分。而且第二部分可以和第一部分分離。(純粹猜測(cè))
表達(dá)式 ar[i] 和*(ar+i)的意義是等價(jià)的。但是只有是指針的時(shí)候才可以 ar++;
指針的8種操作
1.賦值可以把地址賦給指針。
2.求值 *char;
3.取指針地址 &char
4.將一個(gè)整數(shù)加給指針 ptr+4
5.增加指針的值
6.從指針中減去一個(gè)整數(shù)。
7.減小指針的值。
8.求差值可以求出兩個(gè)指針間的差值。
比較比較兩個(gè)指針的大小。

變長(zhǎng)數(shù)組 VLA
2維數(shù)組的初始化:

一維數(shù)組時(shí)一行,2維是一個(gè)面,3維是一個(gè)立方體。
指針和數(shù)組
對(duì)指針+1的結(jié)果就是對(duì)該指針增加一個(gè)尺存儲(chǔ)單元,對(duì)于數(shù)組而言,地址會(huì)增加到下一個(gè)元素的地址。而不是下一個(gè)字節(jié)。
1.指針的數(shù)值就是它所指向的對(duì)象的地址,指向float的指針,地址的內(nèi)部表示方式是由硬件來(lái)決定的,很多計(jì)算機(jī)包含多個(gè)字節(jié)的數(shù)據(jù)類型,比如double類型的變量,對(duì)象的地址通常指的是其首字節(jié)的地址。
2.指針前運(yùn)用運(yùn)算符* 就可以得到該指針?biāo)赶虻膶?duì)象的數(shù)值。
3.對(duì)指針加1,等價(jià)于對(duì)指針的值加上它所指向的對(duì)象的字節(jié)大小。
在函數(shù)原型或函數(shù)定義頭的場(chǎng)合中,可以用int * ar代替int ar[],無(wú)論在任何情況下,形式int * ar都表示ar是指向int的指針。形式int ar[]也可以表示ar是指向int的指針,但只是在聲明形式參量時(shí)才可以這樣使用,使用第二中形式可以提醒讀者ar不僅指向一個(gè)Int數(shù)值,而且它指向的這個(gè)int是一個(gè)數(shù)組中的元素。
由于原型允許省略名稱因此下面的聲明是等價(jià)的:
Int sum (int *ar,int n); Int sum (int *,int); Int sum (in tar[],int n); Int sum (int [], int);
定義函數(shù)時(shí),名稱是不可以省略的,因此,在定義時(shí)下面兩種形式是等價(jià)的:
Int sum(int *ar,int n) { } Int sum (in tar[],int n) { } Int marbles[size];
Sizeof marbles 是整個(gè)數(shù)組的大小,
Sizeof ar或者sizeof tar 就是單個(gè)數(shù)組元素的大小。
也可以傳遞首指針和尾指針
Int sump(int * start,int * end) { Int total = 0; While(start < end ) { Total += *start; Start++; } }


在c中,兩個(gè)表達(dá)式 ar[i] 和*(ar+i) 的意義是等價(jià)的,而且不管ar是一個(gè)數(shù)組名還是一個(gè)指針變量,這兩個(gè)表達(dá)式都可以工作,然而只有當(dāng)ar是一個(gè)指針變量時(shí),才可以使用ar++這樣的表達(dá)式。
指針操作
指針之間的減法結(jié)果等于相對(duì)于他們的類型的值,比如
Pi+3 –pi=3,這個(gè)3相對(duì)于他們的類型int而言就是3個(gè)4字節(jié)的地址長(zhǎng)度。
指針可以直接賦值給以個(gè)指針。
計(jì)算機(jī)并不檢查指針是否依然指向某個(gè)數(shù)組元素,C保證指向數(shù)組的指針和指向數(shù)組后的第一個(gè)地址的指針都是有效的,但是如果指針在進(jìn)行了增量或減量運(yùn)算后超出了這個(gè)范圍,后果將是未知的,另外,可以對(duì)指向數(shù)組元素的指針進(jìn)行取值運(yùn)算,但不能對(duì)指向數(shù)組后的第一個(gè)地址的指針進(jìn)行取值運(yùn)算,盡管這個(gè)指針式合法的。
Int *pt;
*pt = 5;
這是不可行的,因?yàn)閜t的值是隨機(jī)的,所以隨機(jī)地址賦值為5,可能是重要的位置。
指針不能加指針。
由于參數(shù)傳遞數(shù)組的時(shí)候是傳遞地址的,所以可以改變?cè)瓟?shù)組的值,但是如果不想改變要保護(hù)原數(shù)組的話,可以在函數(shù)原型和定義的形式參量聲明中使用關(guān)鍵字const;
使用const來(lái)創(chuàng)建符號(hào)常量(const double PI = 3.14159),數(shù)組常量(const mars [3] ={1,2,3}),指針常量int * const p=&a;,以及指向常量的指針const int * p=&a;(const int a=3;)。
1)指針變量 int * p = &a;
2)指針常量 int * const a = &b; 這里的a 是個(gè)指針常量它指向變量b的地址,不能再修改它的值,a = &c;是錯(cuò)誤的。
3)指向常量的指針?biāo)亲兞恐赶虻氖且粋(gè)常量
它是一個(gè)變量,但它指向的內(nèi)容是常量。
Const int b = 1,c = 2;
Const int * a;
A = &b;a = &c,由于它本身是變量,所以可以改變它的值,再用它指向常量c.
但是它指向的內(nèi)存是常量,是不能被修改的。如: *a = 20;是錯(cuò)誤的。
還有另外一種寫(xiě)法 int const * a;const的位置,還是在*前面;
4)指向常量的指針常量它是常量,但是它指向的內(nèi)容是常量
Cons int b = 1, c = 2;
Int const * const a = &b;
看關(guān)鍵字const,const后面的不可修改。
Int * const a =&b;//則a不能被修改。
Int const * a=&b; //const后面是*a,則說(shuō)明*a不能被修改。
把常量或非常量數(shù)據(jù)的地址賦給指向常量的指針式合法的。

然而只有非常量的數(shù)據(jù)才可以賦給普通的指針:

所以要分三個(gè)點(diǎn)來(lái)看指向的是常量還是非常量,還有就是常量指針還是指針常量。
多維數(shù)組與指針

Int zippo[4][2]:
數(shù)組名zippo同事也是數(shù)組首元素的地址,本例中,zippo的首元素本省又是包含兩個(gè)int的數(shù)組,因此zippo也是包含兩個(gè)int數(shù)組的地址,
1)Zippo是數(shù)組首元素的地址,所以zippo的值和&zippo[0]相同,另一方面,zippo[0]本身是包含兩個(gè)整數(shù)的數(shù)組,因此zippo[0]的值同其首元素(一個(gè)整數(shù))的地址&zippo[0][0]相同。簡(jiǎn)單的說(shuō)zippo[0]是一個(gè)整數(shù)大小對(duì)象的地址,zippo是兩個(gè)整數(shù)大小對(duì)象的地址,因?yàn)檎麛?shù)和兩個(gè)整數(shù)組成的數(shù)組開(kāi)始同一個(gè)地址,因此zippo和zipp[0]具有相同的數(shù)值。
2)對(duì)一個(gè)指針加1,會(huì)對(duì)原來(lái)的數(shù)值加上一個(gè)對(duì)應(yīng)類型大小的數(shù)值。在這方面,zippo和zippo[0]是不一樣的,zippo所指向的對(duì)象的大小事兩個(gè)int,而zippo【0】所指向的大小事一個(gè)int,因此zippo+1和zippo[0]+1的結(jié)果不同。
3)對(duì)一個(gè)指針取值(使用運(yùn)算符*或者帶有索引的[]運(yùn)算符)得到的是該指針?biāo)赶驅(qū)ο蟮臄?shù)值,因?yàn)閦ipp[0]是其首元素zippo[0][0]的地址,所以 *(zippo[0])代表存儲(chǔ)在zippo[0][0]中的數(shù)值,即是一個(gè)int數(shù)值,同樣zippo代表其首元素的地址,但是zippo[0]本身就是int數(shù)的地址,即&zippo[0][0],因此*zippo是&zippo[0][0]。對(duì)這兩個(gè)表達(dá)式同時(shí)應(yīng)用取值運(yùn)算符將得到 **zippo等價(jià)于*&zippo[0][0],后者簡(jiǎn)化為一個(gè)int數(shù) zippo[0][0].簡(jiǎn)而言之,zippo是地址的地址,需要兩次取值才可以得到通常的數(shù)值。地址的地址或指針的指針式雙重間接地典型例子。
總結(jié):數(shù)組名是它本身元素的首地址,所以一維數(shù)組中的數(shù)組名就是數(shù)組單個(gè)元素的第一個(gè)元素的首地址,而二維數(shù)組就是一維數(shù)組的數(shù)組,所以它的名稱就是一維數(shù)組的第一組數(shù)組的地址,所以他們相加結(jié)果是不一樣的。相加就相當(dāng)于他們?cè)丶?,一維數(shù)組的元素是一個(gè)元素,而二維數(shù)組加1就相當(dāng)于一維數(shù)組的一組數(shù)組。三維一樣是二維數(shù)組的數(shù)組。它加1相當(dāng)于加一個(gè)二維數(shù)組的量。對(duì)于取值來(lái)說(shuō)二維是一維的地址,所以要經(jīng)過(guò)兩次取值才能取到數(shù)。

Int (* pz)[2] // 首先是一個(gè)指針,指向一個(gè)包含2個(gè)int值得數(shù)組。
pz指向一個(gè)包含2個(gè)int值得數(shù)組。加()是因?yàn)閇]優(yōu)先級(jí)高于*
Int說(shuō)明數(shù)組和指針都int型的。
Int * pz[] //是指2個(gè)指向int值的指針構(gòu)成的數(shù)組。
看這個(gè)名稱與誰(shuí)先結(jié)合,與【】它就是一個(gè)數(shù)組,與*就是一個(gè)指針。

最后一行說(shuō)明指針的指針不能賦給2維數(shù)組名。
Int * p1;
Const int *p2;
Const int ** pp2;
P1=p2; // 非法,把const賦值給非const指針
P2=p1;// 合法 把非const指針賦值給const指針
Pp2= &p1; //非法 為什么呢不也是非const賦值給const么
原來(lái)是2層間接賦值的時(shí)候不可以。1層間接是可以的。
二維數(shù)組的形參聲明:
Int fun(Const int (* pt) [4])
或者int fun(const pt [][4]);
Typedef int arr4[4]; Typedef arr4 arr3x4[3];
Int sum2(arr3x4 ar,int rows);等價(jià)于 Int sum2(in tar[3][4],int rows); Int sum2(in tar[][4],int rows);
一般聲明多維數(shù)組的形參時(shí)可以省略最左邊的數(shù)目。
傳統(tǒng)c向函數(shù)傳遞多維數(shù)組的方法是把數(shù)組名傳遞給相應(yīng)的類型的指針參量。指針生命需要制定各維的大小(除了最左面的不需要明確指出大小);第一個(gè)參量的維數(shù)大小通常為第二個(gè)參量來(lái)傳遞;
Void display(double ar[][12],int rows)… Display(sales,5);
變長(zhǎng)數(shù)組提供了另一種方法,兩個(gè)維大小都可以作為參數(shù)被傳遞給函數(shù)。因此函數(shù)原型和函數(shù)調(diào)用就可以如下:;
Void display(int rows,int cols,double ar[rows][cols]); …. …. Display(5,12,sales);
變長(zhǎng)數(shù)組必須是自動(dòng)存儲(chǔ)類,而且聲明時(shí)不可以進(jìn)行初始化。
變說(shuō)的是創(chuàng)建前維數(shù)可以是變量,創(chuàng)建后是不可以變的。
省略名稱的話
Int sum2d(int,int,ar[*][*]);
二維數(shù)組,
復(fù)合文字
對(duì)參量傳值,可以穿變量和常量,但是數(shù)組沒(méi)有數(shù)組常量可供傳遞,c99新增了復(fù)合文字,文字是非符號(hào)常量,5是int類型的文字,81.3是double類型的文字,’Y’是char類型的文字,”elephant”是字符串文字。如果有能夠表示數(shù)組和結(jié)構(gòu)內(nèi)容的復(fù)合文字,那么在編寫(xiě)程序時(shí)更為方便。相當(dāng)于java中的匿名數(shù)組等等
(int[2]){10,20}
相當(dāng)于一個(gè)數(shù)組,可以傳遞給參量,或者給指針賦值。
字符串和字符串函數(shù)
字符串的定義
字符串常量define “XXXXXX”,
char數(shù)組 char[]={‘c’,’d’,’\0’},char[] = “cd”;
char指針 char * s=”just a test!”;
和字符串?dāng)?shù)組char *s[]={”just a test!!”,”just a test too”}。
1)字符串常量:又成字符串文字,是指位于一對(duì)雙引號(hào)中的任何字符。雙引號(hào)里的文字加上編譯器自動(dòng)提供的結(jié)束標(biāo)志\0字符,作為一個(gè)字符串被存儲(chǔ)在內(nèi)存里。
字符串文字中間沒(méi)有間隔或者間隔是空格符,ansic會(huì)將其串連起來(lái)。
字符串常量是靜態(tài)存儲(chǔ)類,靜態(tài)存是指如果在一個(gè)函數(shù)中使用的字符串常量,即使是多次調(diào)用了這個(gè)函數(shù),該字符串在程序的整個(gè)運(yùn)行中只存儲(chǔ)一份。整個(gè)引號(hào)中的內(nèi)容作為指向該字符串存儲(chǔ)位置的指針。與數(shù)組名作為數(shù)組存儲(chǔ)位置的指針類似。

1)字符串?dāng)?shù)組及其初始化
Const char ml[40] = “Limit yourself to one line’s worth.”;
注意標(biāo)志結(jié)束的空字符,如果沒(méi)有它,得到的就只是一個(gè)字符數(shù)組而不是一個(gè)字符串。指定數(shù)組大小時(shí),一定要確保數(shù)組元素?cái)?shù)比字符串長(zhǎng)度至少多1.未被使用的元素均被自動(dòng)初始化為0,這里的0是char形式的空字符,而不是數(shù)字字符0.

Const char *m3[] = “\nEnough about me what’s your name?”;
這個(gè)聲明和下列聲明的作用幾乎相同:
Char m3[] = “\nEnough about me what’s your name?”;
都聲明了m3是一個(gè)指向給定字符串的指針。都是被引用的字符串本身決定了為字符串預(yù)留的存儲(chǔ)空間大小。
總之:數(shù)組初始化時(shí)從靜態(tài)存儲(chǔ)區(qū)把一個(gè)字符串賦值給數(shù)組,而指針初始化只是復(fù)制字符串的地址。
如:
Char heart[]=”I love Tillie!”;
Char *head =”I love Millie!”;
主要區(qū)別是:heart是個(gè)常量,而指針head則是個(gè)變量。
可以
Putchar(heart[i]); Putchar(head[i]); *(Heart+i) *(Head+i)
只有指針可以
While(*(head)!=’\0’)
Putchar(*(head++));

數(shù)組的元素師變量(除非聲明數(shù)組時(shí)帶有關(guān)鍵字const)
建議初始化一個(gè)指向字符串文字的指針時(shí)使用const修飾符:
Const char * p1=”Klingon”;
用一個(gè)字符串文字來(lái)初始化一個(gè)非const得數(shù)組,則不會(huì)導(dǎo)致此類問(wèn)題,因?yàn)閿?shù)組從最初的字符串得到一個(gè)拷貝。

這個(gè)示例說(shuō)明字符串常量是在靜態(tài)存儲(chǔ)區(qū)存儲(chǔ)的。
字符指針只是把這個(gè)地址賦值過(guò)來(lái),
而數(shù)組則把內(nèi)容復(fù)制過(guò)來(lái)。
由于字符指針指向的是字符串常量,所以不能用字符指針來(lái)修改字符串常量。
建議指向字符串的字符指針用const修飾。Const char * p2=”Klingon”;
字符串?dāng)?shù)組
Const char * mytal[5] = {“Adding numbers swiftly”,”Multiolying accurately”,
”Stashing dta”,”Following instructions to
the letter”,”Understanding the c language”};
所以mytal是一個(gè)由5個(gè)指向char的指針組成的數(shù)組。也就是說(shuō),mytal是一個(gè)數(shù)組,每個(gè)元素都是一個(gè)char類型值得地址。
也可以用字符的二維數(shù)組來(lái)聲明字符串?dāng)?shù)組。Char mytal[5][20]
兩者的不同之處是數(shù)組在內(nèi)存中連續(xù)存放,而指針數(shù)組指向的字符串不一定是連續(xù)存放的。
指針和字符串
字符指針賦值只是把指針的值也就是字符串的地址賦給了另一個(gè)指針。也就是2個(gè)指針指向了同一個(gè)地址。
字符串輸入:如果想把一個(gè)字符串讀到程序中,必須首先預(yù)留存儲(chǔ)字符串的空間,然后使用輸入函數(shù)來(lái)獲取這個(gè)字符串。
Char *name;
Scanf(“%s”,name);
這可能會(huì)通過(guò)編譯器,但是在讀入name的時(shí)候,name會(huì)覆蓋程序中的數(shù)據(jù)和代碼,并可能導(dǎo)致程序異常終止。
最簡(jiǎn)單的方法就是在聲明中明確指出數(shù)組大小。Char name[8];
獲取字符串的函數(shù),
1)scanf(),如果是%s字符串讀到(但是不包括下一個(gè)空白字符比如空格、制表符、換行符)

它遇到換行符,制表符和空格符就結(jié)束,不包括但是也不丟棄。
1)gets(),丟棄末尾的換行符,并在末尾添加\0.

說(shuō)明丟棄了回車符
返回一個(gè)字符指針,與參數(shù)數(shù)組時(shí)內(nèi)容是一樣的。如果無(wú)措就返回一個(gè)地址,如果有誤或者遇到結(jié)束符,就返回一個(gè)NULL
如果是getchar()就要用 getchar()!=EOF,
1)fgets()函數(shù)。
Char name[50];//這時(shí)候已經(jīng)為數(shù)組分配了內(nèi)存空間。
Gets(name)!=NULL;
它返回一個(gè)字符指針與傳入的字符指針是同一個(gè)。
Fgets()函數(shù)與gets()函數(shù)有三點(diǎn)不一樣的地方:
1)它需要第二個(gè)參數(shù)來(lái)說(shuō)明最大讀入字符數(shù)。
2)Fgets()讀取到換行符,就會(huì)把它存到字符串里,而不是像gets()那樣丟棄它。
3)需要第三個(gè)參數(shù)來(lái)說(shuō)明讀取哪一個(gè)文件,鍵盤(pán)上讀取,可以使用stdin。
根據(jù)特點(diǎn):gets()從鍵盤(pán)讀取文本可能要更好,因?yàn)樗菀妆皇褂茫欤腋?jiǎn)潔。

Scanf主要用于某種標(biāo)準(zhǔn)形式輸入的混合類型數(shù)據(jù)的讀取和轉(zhuǎn)換。
字符串輸出函數(shù):
1)Puts顯示字符串自動(dòng)在后面加上換行符。Puts遇到空格符就會(huì)停下來(lái)(、0).
2)fputs()的第二個(gè)參數(shù)來(lái)說(shuō)明要寫(xiě)的文件。
3)與puts()不同,fputs()并不為輸出自動(dòng)添加換行符。
注意:gets()丟掉輸入里的換行符,但是puts()為輸出添加換行符。Fgets()存儲(chǔ)輸入中的換行符,fputs()也不為輸出添加換行符。
Printf()不添加換行符。
Gets() puts(); Fgets() fputs();
自定義字符串輸出函數(shù)
Int i = 0; While(*string) Putchar(*string++);
或記錄字符數(shù)。
字符串函數(shù)
Strlen()不考慮最后的\0字符的字符串長(zhǎng)度。
Strcat 將第二個(gè)字符串的一份拷貝添加到第一個(gè)字符串的結(jié)尾,從而使第一個(gè)字符串成為一個(gè)新的組合字符串,第二個(gè)字符串并沒(méi)有給帶便。
Strncat()添加了一個(gè)字?jǐn)?shù),直到加到字?jǐn)?shù)或者遇到空字符為止,由二者中先符合的那一個(gè)來(lái)終止添加過(guò)程。基本上是第一的長(zhǎng)度減去字符串的長(zhǎng)度再減一就是可以添加的最大值。
Strcmp();比較二個(gè)字符串,比較的是二個(gè)字符串的內(nèi)容,小于為負(fù)數(shù)等于為零,大于為正數(shù)。
字符數(shù)組可以這樣初始化,但是不能這樣賦值:char tmp[40] = ”just a test”;
Char tmp[40];
Tmp = ”just a test”;
賦值可以使用strcpy函數(shù)來(lái),也可以不在第一位。
如果第一個(gè)不是數(shù)組而是指針,那么指針指向的位置可以是任何地方。
Strcpy 兩個(gè)屬性:它是char *類型,它返回的是第一個(gè)參數(shù)的值,即一個(gè)字符的地址;其次第一個(gè)參數(shù)不需要指向數(shù)組的開(kāi)始,這樣就可以只復(fù)制數(shù)組的一部分。

第一箭頭說(shuō)明復(fù)制后把第二個(gè)的結(jié)束符也帶過(guò)去了,第二個(gè)說(shuō)明函數(shù)返回的是第一個(gè)參數(shù)的地址。

箭頭后面部存在說(shuō)明這個(gè)函數(shù)不能用來(lái)拷貝字符數(shù)組,只能用來(lái)拷貝字符串。

上面說(shuō)明如果復(fù)制的位置位于目標(biāo)字符長(zhǎng)度之后,它不會(huì)去掉源字符串的結(jié)束符,并且也不會(huì)考慮復(fù)制后是不是超出了大小范圍。充分說(shuō)明C語(yǔ)言設(shè)計(jì)時(shí)要求速度和充分相信程序員。
Strncpy函數(shù):要比strcpy多注意由于源字符串被截?cái)鄰?fù)制,可能不帶有結(jié)束符。所以復(fù)制的時(shí)候大小要小一個(gè)。

字符的比較用關(guān)系運(yùn)算符。
Strncmp(list,”astro”,5);用“astro”與list的前5個(gè)字符相比較。
小結(jié):
Char *strcpy(char * s1,const char *s2):
該函數(shù)把s2指向字符串復(fù)制到s1指向的位置,返回值是s1.
Char *strncpy(char *s1,const char * s2,size_t n);
該函數(shù)把s2指向的字符復(fù)制到s1指向的位置,復(fù)制字符數(shù)不能超過(guò)n個(gè),返回值是s1,空字符后的字符不被復(fù)制。如果源字符串的字符數(shù)少于n個(gè),在目標(biāo)字符串中就以空字符填充,如果源字符串的字符串的字符數(shù)大于或等于n個(gè)。空字符就不被復(fù)制,返回值是s1.

說(shuō)明只看大小不管是不是字符串的結(jié)束。
Sprint()函數(shù)是向字符串中打印與printf函數(shù)一樣。
Char * strcat(char * s1,const char * s2);
S2指向的字符串被復(fù)制到S1指向字符串的結(jié)尾,復(fù)制過(guò)來(lái)的s2所指字符串的第一個(gè)字符覆蓋了s1所指字符串結(jié)尾的空字符。返回值是s1.程序員自己處理數(shù)組的大小。S1如果是數(shù)組必須足夠大。如果是字符串賦值的指針也是不可以的。

Char * strncat(char * s1,const char * s2,size_t n);
S2字符中的空字符及其后的任何字符都不會(huì)被復(fù)制,并且追加一個(gè)空字符到所得結(jié)果后面,返回值是s1.不要求S1的大小大于或等于復(fù)制后大小。
要牢記char * ptr;的聲明并沒(méi)有給指針?lè)峙淇臻g,所以不能用于strcate的鏈接。
Int strcmp(const char * s1,const char * s2);
Int strncmp(const char * s1,const char * s2,size_t n);
Char * strchr(const char *s,int c);該函數(shù)返回一個(gè)指向字符串S中存放字符c的第一個(gè)位置的指針(標(biāo)志結(jié)束的空字符時(shí)字符串的一部分,因此也可以搜索到它),如果沒(méi)有找到該字符,函數(shù)就返回空指針。
Char *strpbrk(const char *s1,const char *s2);
該函數(shù)返回一個(gè)指針,指向字符串S1中存放S2字符串中的任何字符的第一個(gè)位置,如果沒(méi)有找到任何字符,函數(shù)返回空指針。
排序字符串?dāng)?shù)組的時(shí)候可以用指針指向每條字符串,排序這個(gè)指針的數(shù)組;

Gets(char[n])!=NULL,遇到EOF字符,
Char[n][0]!=’\0’ 或者第一個(gè)是空行。
字符函數(shù)和字符串
Ctype.h
Toupper() 轉(zhuǎn)換為大寫(xiě)
Ispunct() 是否為符號(hào)
命令行參數(shù)
Int main(int argc,char *argv[]) { //argc參數(shù)的個(gè)數(shù),argv參數(shù)的數(shù)組 return 0; }
C編譯器允許main()沒(méi)有參數(shù),或者兩個(gè)參數(shù)(有些實(shí)現(xiàn)允許更多的參數(shù),但這將是對(duì)標(biāo)準(zhǔn)的擴(kuò)展),兩個(gè)參數(shù)時(shí),第一個(gè)參數(shù)是命令行中的字符串?dāng)?shù),但不是必須的,第二個(gè)參數(shù)是一個(gè)指向字符串指針數(shù)組。Argv[0]一般是程序名,argv[1]是第一個(gè)參數(shù),argv[2]是第二個(gè)參數(shù)。很多環(huán)境允許使用把多個(gè)單詞集中在一個(gè)參數(shù)里。例如:repeat “I am hungry” now
把字符串轉(zhuǎn)換為數(shù)字
轉(zhuǎn)換函數(shù) atoi();atof();atol();strtol();strtoul()把一個(gè)字符串轉(zhuǎn)換為unsigned long型值,strtod()把一個(gè)字符串轉(zhuǎn)換為duble型
如果字符串只是以一個(gè)整數(shù)作為開(kāi)頭,atoi函數(shù)依然可以工作,在這種情況下函數(shù)在遇到非整數(shù)部分之前一直轉(zhuǎn)換字符。
