1、printf格式輸出函數(shù)
如果格式控制說(shuō)明項(xiàng)數(shù)多于輸出表列個(gè)數(shù),則會(huì)輸出錯(cuò)誤數(shù)據(jù);
如果輸出表列個(gè)數(shù)多于格式控制說(shuō)明數(shù),則多出數(shù)不被輸出。
%md,m指的是輸出字段的寬度。如果輸出字段位數(shù)小于m,則左端以空格補(bǔ)齊,若大于m,則按照實(shí)際位數(shù)輸出。
%-md,基本同上,只不過(guò)不同之處在于,空格在右端補(bǔ)齊
printf參數(shù)可以是常量,變量或表達(dá)式,VC++ 6.0中采用從右向左順序求值,從左向右輸出如
int x = 5;
printf("%4d%4d%4d", x, ++x, ++x);
輸出的是7,7,6. 而不是5,6,7
注意,不同的編譯器可能輸出不同結(jié)果,直接用gcc編譯結(jié)果為7,7,7
2、0-9數(shù)字轉(zhuǎn)為字符
數(shù)字為m,則m+‘0'即為m的字符形式‘m'
3、小寫(xiě)字母變?yōu)榇髮?xiě)字母
char c; c為小寫(xiě)字母,則c-'a'+'A'即為對(duì)應(yīng)的大寫(xiě)字母
4、switch
如果找到匹配的case入口,則執(zhí)行后面的語(yǔ)句,執(zhí)行完語(yǔ)句之后,并不像if語(yǔ)句那樣退出,如果沒(méi)有遇到break語(yǔ)句,將逐條執(zhí)行后面所有的case語(yǔ)句,不再進(jìn)行條件判斷。
case入口后面的語(yǔ)句可以是一句,也可以是多句,并且不需要大括號(hào)。
5、字符數(shù)組存儲(chǔ)字符串
當(dāng)char str[5]=new {"china"};時(shí),程序會(huì)出問(wèn)題,輸出的時(shí)候會(huì)在china后帶亂碼,這是因?yàn)閏hina字符串后還有一位'/0',因此應(yīng)該給str數(shù)組多一位。即char str[6]=new {"china"};
且'/0'只表示字符串的結(jié)束,并不會(huì)輸出。
scanf("%s",str);不能存入空格,因?yàn)檎J(rèn)為空格代表字符串的結(jié)束。gets(str);可以在字符串中間加入空格。
puts(str);在輸出字符串后自動(dòng)加入換行
6、字符串操作函數(shù)
字符串拷貝函數(shù):strcy(str1,str2); 將字符串str2拷貝到str1中。
字符串連接函數(shù):strcat(str1,str2); 將str2連同'/0'一起連接到str1的最后一個(gè)字符(非'/0')后面,結(jié)果放在str1中。
字符串比較函數(shù):strcmp(str1,str2); 比較str1和str2的大小,如果str1==str2,則返回0;如果str1>str2,則返回正整數(shù);如果str1<str2,則返回負(fù)整數(shù)。
字符串長(zhǎng)度函數(shù):strlen(str); 返回字符串str的實(shí)際長(zhǎng)度,不包括末尾的'/0'。
7、函數(shù)的參數(shù)和單向值傳遞
函數(shù)的參數(shù)分為實(shí)參和形參。形參出現(xiàn)在函數(shù)定義中,在整個(gè)函數(shù)體中使用,離開(kāi)函數(shù)體則不能使用。實(shí)參出現(xiàn)在主調(diào)函數(shù)中,進(jìn)入被調(diào)函數(shù)后,實(shí)參不能被使用。
形參只有被調(diào)用時(shí)才被編譯系統(tǒng)分配內(nèi)存單元,在調(diào)用結(jié)束時(shí)候,編譯系統(tǒng)即刻釋放所分配的內(nèi)存單元,因此形參只在函數(shù)內(nèi)部有效,函數(shù)調(diào)用結(jié)束返回主調(diào)函數(shù)后則不能再使用;
單向傳值:只能把實(shí)參的值傳遞給形參,不能把形參的值反向傳遞給實(shí)參,叫做單向值傳遞。
因此,函數(shù)調(diào)用過(guò)程中,形參的值發(fā)生改變,實(shí)參的值不會(huì)改變
8、數(shù)組作為參數(shù)
數(shù)組名可以作為函數(shù)實(shí)參,這時(shí)候形參可以是數(shù)組或者指針。且形參是一維數(shù)組時(shí)候可以不指定長(zhǎng)度。形參是二維數(shù)組時(shí)候,第一維大小可以省略,要指定第二維的大小。
9、變量的存儲(chǔ)方式
(1)局部變量
局部變量在每次函數(shù)調(diào)用時(shí),系統(tǒng)會(huì)在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)為他們重新分配內(nèi)存單元,隨著函數(shù)的頻繁調(diào)用,某個(gè)變量的存儲(chǔ)位置會(huì)隨著程序的運(yùn)行不斷變化,所以未賦值的局部變量的值是不確定的。函數(shù)中的局部變量不能作為返回值,因?yàn)楹瘮?shù)結(jié)束后,局部變量要被回收。
(2)static類(lèi)型
靜態(tài)變量在編譯的時(shí)候被分配內(nèi)存、賦初值,并且只會(huì)被賦初值一次。未賦初值的靜態(tài)變量,系統(tǒng)自動(dòng)賦初值0(或'0')。靜態(tài)變量在內(nèi)存靜態(tài)存儲(chǔ)區(qū)占用固定的內(nèi)存單元。即使它所在的函數(shù)調(diào)用結(jié)束,也不會(huì)釋放存儲(chǔ)單元,其值也會(huì)繼續(xù)保留,下次調(diào)用,會(huì)繼續(xù)使用該值。靜態(tài)變量分為靜態(tài)局部變量和靜態(tài)全局變量,靜態(tài)全局變量就是定義在函數(shù)體外的靜態(tài)變量,靜態(tài)局部變量就是定義在函數(shù)體內(nèi)的靜態(tài)變量。
如下:
#include<stdio.h>
void f()
{
static int a=0; //編譯時(shí)被賦初值,且整個(gè)過(guò)程只被賦初值一次
++a;
printf("%-2d",a);
}
main()
{
f();
f();
f();
}
以上程序的輸出結(jié)果為1 2 3
因?yàn)閷?duì)static變量賦初值是在編譯時(shí)完成,而且只賦值一次,之后在調(diào)用函數(shù)不會(huì)執(zhí)行賦初值操作,因此輸出1 2 3 ;若去掉static關(guān)鍵字,那么結(jié)果就會(huì)變?yōu)? 1 1 ;由此看出,函數(shù)反復(fù)調(diào)用多次,局部變量每次都會(huì)被賦初值,而靜態(tài)變量只是在第一次被調(diào)用的時(shí)候賦初值。
此處特變注意:java中是沒(méi)有靜態(tài)局部變量的,只會(huì)有針對(duì)類(lèi)的靜態(tài)全局變量。
(3)寄存器類(lèi)型
定義形式: register 數(shù)據(jù)類(lèi)型 變量名;寄存器類(lèi)型局部變量的作用域、生存期與局部變量相同。
寄存器的個(gè)數(shù)有限,寄存器的存儲(chǔ)數(shù)據(jù)位數(shù)有限,所以寄存器類(lèi)型的變量不能太多,而且有整型變量和字符型變量才能被定義為寄存器類(lèi)型的局部變量。現(xiàn)在的優(yōu)化系統(tǒng)可以自動(dòng)的判斷把相關(guān)變量存到寄存器中。
(4)外部變量
10、編譯預(yù)處理
#include<文件名>和#include"文件名"的區(qū)別是:使用尖括號(hào)時(shí),編譯預(yù)處理程序只在系統(tǒng)指定的文件夾中尋找;而使用雙引號(hào),編譯預(yù)處理程序首先在當(dāng)前文件所在的文件夾中尋找,如果找不到,則在系統(tǒng)指定的文件夾中再尋找。
11、&和*
優(yōu)先級(jí)都屬于第二級(jí),從右向左運(yùn)算
12、*與++、--運(yùn)算符
都屬于第二級(jí),從右向左計(jì)算
*p++ 等價(jià)于 *(p++)
*++p 等價(jià)于 *(++p)
13、[ ]和*
[ ]優(yōu)先級(jí)高于*
13、二維數(shù)組的行地址和列地址
int a[2][2]={1,2,3,4};
則a為首地址,第一行首地址;*a和a[0]都是第一行第一個(gè)元素的地址
a+1為第二行行地址
*(a+1)為第二行第一個(gè)元素地址,a[1]也為第二行第一個(gè)元素地址
14、指向數(shù)組的指針變量(數(shù)組指針)
int *(p) [4];表示一個(gè)指向含有4個(gè)int元素的數(shù)組的指針。
(1)p指向一維數(shù)組的首行地址
main()
{
int a[2]={1,2};
int (*p)[2];
p=&a;//p是指向數(shù)組的指針,即行指針,因此要用&a給其賦值,&a為數(shù)組地址
printf("%d/n",**p);//取第一個(gè)元素,其中p為行地址,*p為元素地址,**p為元素值
printf("%d/n",*(*p+1));//取第二個(gè)元素
//也可以如下取值
printf("%d/n",(*p)[0]);//(*p)可以取代a
printf("%d/n",(*p)[1]);
}
(2)p指向二維數(shù)組的首行地址
main()
{
int a[2][2]={1,2,3,4};
int (*p)[2];
p=a;//p指向二維數(shù)組的首行地址
printf("%d/n",**p);//*p是元素的地址,**p則為元素內(nèi)容
printf("%d/n",*(*(p+1)+1));
}
15、指針數(shù)組
int *p[4];表示一個(gè)數(shù)組中含有4個(gè)int型指針。
char *p[4];表示一個(gè)數(shù)組中含有4個(gè)char型數(shù)組,或則4個(gè)字符串
16、二維數(shù)組中的各個(gè)地址
int a[2][3];
則a為首行地址,*a為首行第一個(gè)元素地址,**a為首行第一個(gè)元素的值
a+1為第二行地址,*(a+1)為第二行第一個(gè)元素的地址,**(a+1)為第二行第一個(gè)元素的值
*(a+1)與a[1]等價(jià):都代表第二行第一個(gè)元素的地址
例子:
main()
{
int a[2][2]={1,2,3,4};
printf("a=%d/n",a);
printf("*a=%d/n",*a);
printf("**a=%d/n",**a);
printf("*a+1=%d/n",*a+1);
printf("a+1=%d/n",a+1);
printf("a[1]=%d/n",a[1]);
printf("a[1]+1=%d/n",a[1]+1);
printf("*a[1]=%d/n",*a[1]);
}
17、字符指針變量在接受輸入字符串時(shí),必須先開(kāi)辟存儲(chǔ)空間
char *cp;
scanf("%s",cp);
以上是錯(cuò)誤的。
可以改為:
char cp[20];
scanf("%s",cp);
或者
char *cp,str[20];
cp=str;
scanf("%s",cp);
總之,一定要先開(kāi)辟空間,再接受字符串
18、c和c++中的返回值不能是數(shù)組,java返回值可以是數(shù)組
19、指針函數(shù)和函數(shù)指針
指針函數(shù):int * function();
函數(shù)指針:
int (*p) ();
int max(int a,int b);
p=max;
int a=(*p)(2,3);
20、關(guān)于變量的生命周期
函數(shù)中定義的局部變量是不能作為返回值的,因?yàn)楹瘮?shù)結(jié)束后,局部變量就被回收了。
21、結(jié)構(gòu)體
結(jié)構(gòu)體中可以嵌套結(jié)構(gòu)體,但不能是其本身。且成員結(jié)構(gòu)體的定義必須在主結(jié)構(gòu)體之前。
22、malloc
malloc函數(shù)位于stdlib.h中,函數(shù)原型為void * malloc(unsigned size);
eg: struct student *p=(struct student *)malloc(sizeof(struct student));
因?yàn)閙alloc返回的是一個(gè)void類(lèi)型的指針,所以要強(qiáng)制轉(zhuǎn)換。
23、free
該函數(shù)原型為
void free(void * ptr)
釋放有指針ptr指向的動(dòng)態(tài)分配的內(nèi)存空間。為保證動(dòng)態(tài)存儲(chǔ)區(qū)的有效利用,當(dāng)某個(gè)存儲(chǔ)空間不再使用時(shí),就應(yīng)該及時(shí)釋放它。
24、結(jié)構(gòu)體和共用體
(1)結(jié)構(gòu)體
結(jié)構(gòu)體可以作為函數(shù)的參數(shù)和返回值。
結(jié)構(gòu)體只有在初始化的時(shí)候才能直接用大括號(hào){}形式賦值;當(dāng)先聲明,后賦值時(shí)候,就只能單個(gè)元素賦值,不能再用大括號(hào)形式了。這個(gè)跟數(shù)組的賦值類(lèi)似。舉例如下
struct student
{
int bh;
char *name;
};
struct student stu={1,'typ'};//是正確的
但是下面的是錯(cuò)誤的
struct student stu;
stu={1,"typ"};//是錯(cuò)誤的
此時(shí)這能stu.bh=1;stu.name="typ"
(2)共用體
共用體不能作為函數(shù)的參數(shù)和返回值
共用體不能同時(shí)存放,每一時(shí)刻只能存放一個(gè)成員,以最后一次存放的成員為有效成員。共用體的大小是最大元素所占用的大小;
共用體可以出現(xiàn)在結(jié)構(gòu)體類(lèi)型中,反之,結(jié)構(gòu)體也可以出現(xiàn)在共用體的類(lèi)型中
25、枚舉類(lèi)型
enum color {red,green,blue};
enum color c=red;
int i=red;//值為0
26、類(lèi)型標(biāo)識(shí)符的重定義
c語(yǔ)言中用關(guān)鍵字typedef來(lái)聲明新的類(lèi)型名
typedef int INTEGER;
INTEGER x,y;
等價(jià)于
int x , y;
又比如結(jié)構(gòu)體定義:
typedef struct
{
int num;
char name[10];
float score;
}student;
student stu1, stu2, *s;
另外,typedef只是進(jìn)行類(lèi)型重定義,只是為該類(lèi)型命名一個(gè)別名,并不產(chǎn)生新的數(shù)據(jù)類(lèi)型
27、位運(yùn)算
包括(與、或、異或、取反)。
其中,位運(yùn)算符進(jìn)行運(yùn)算時(shí),數(shù)都是以補(bǔ)碼形式參加運(yùn)算,且符號(hào)位參與運(yùn)算。
異或:相同為0,不同為1
a^a=0;a^0=a;a^~a=1;
此處可以用異或來(lái)實(shí)現(xiàn)兩數(shù)的交換
a=a^b;
b=b^a;
a=a^b;
這樣避免引入臨時(shí)變量
28、移位運(yùn)算
(1)a<<b,表示a的二進(jìn)制值左移b位
(2)a>>b,表示a的二進(jìn)制值右移b位
移位運(yùn)算具體實(shí)現(xiàn)有3種形式:
(1)循環(huán)移位:移入的位等于移出的位
(2)邏輯移位:移出的位丟失,移入的位取0
(3)算術(shù)移位:移出的位丟失,左移入的位取0,右移入的位取符號(hào)位,符號(hào)位保持不變
C語(yǔ)言的移位運(yùn)算與具體的C編譯系統(tǒng)有關(guān),如VC++6.0采用的是算術(shù)移位
注意:移位操作并不會(huì)改變?cè)僮鲾?shù)的值。例如a>>2運(yùn)算后,a的值保持不變,除非通過(guò)賦值a=a>>2來(lái)改變a的值。
29、文件
(1)C語(yǔ)言中文件是字節(jié)流文件.
(2)C中為用戶(hù)定義的文件類(lèi)型是FILE,FILE文件類(lèi)型是結(jié)構(gòu)體類(lèi)型,F(xiàn)ILE結(jié)構(gòu)是用關(guān)鍵字typedef定義出的一種結(jié)構(gòu)。
struct _iobuf
{
char * _ptr;
int _cnt;
char *base;
int _flag;
int _file;
.........
};
typedef struct _iobuf FILE;
(3)文件打開(kāi)與關(guān)閉
文件指針 = fopen("文件路徑//文件名", "文件操作方式");
操作方式分為r,w,a,r+,w+,a+
如果fopen打開(kāi)失敗,則返回NULL
如果緩沖區(qū)未滿(mǎn)512B,那么不會(huì)寫(xiě)到磁盤(pán)中,萬(wàn)一程序異常終止,則緩沖區(qū)中數(shù)據(jù)丟失,導(dǎo)致文件不完整。只有對(duì)打開(kāi)文件執(zhí)行關(guān)閉操作時(shí),才能強(qiáng)制把緩沖區(qū)中不足512B的數(shù)據(jù)寫(xiě)到磁盤(pán)文件中,保證文件的完整性。fclose函數(shù)用來(lái)關(guān)閉文件
fclose(文件指針);
返回值是一個(gè)整數(shù)值,若為0,表示正常關(guān)閉,否則表示無(wú)法正常關(guān)閉文件。
(4)文件的輸入和輸出
讀寫(xiě)一個(gè)字符:char fgetc(文件指針);EOF fputc(字符,文件指針)
讀寫(xiě)一個(gè)字符串:fgets(字符串s,讀入字符個(gè)數(shù)n,文件指針)--->在中途遇到/n或者EOF停止,讀n-1個(gè)字符,在末尾加'/0';fputs(字符串,文件指針)--->字符串的結(jié)束標(biāo)記不會(huì)寫(xiě)入文件
格式化讀寫(xiě):fscanf(fp, "%d%s", &i, s)--->從文件中讀取數(shù)據(jù)保存到變量;fprintf(fp, "%d%c", j, c)--->按指定格式向文件寫(xiě)入數(shù)據(jù)
成塊讀寫(xiě):fread(buffer,size,count,fp)和fwrite(buffer,size,count,fp)
buffer是一個(gè)指針,fread()中表示存放“輸入數(shù)據(jù)”的變量首地址,fwrite()中表示存放“輸出數(shù)據(jù)”的變量首地址
size表示數(shù)據(jù)塊的字節(jié)數(shù)
count表示數(shù)據(jù)塊個(gè)數(shù)
fp文件指針
返回值都是count值
(4)其他文件操作的函數(shù)
feof(fp)判斷文件的末尾標(biāo)志,到達(dá)末尾返回1,否則返回0
rewind(fp)用于定位,是文件的位置指針?lè)祷匚募_(kāi)頭。
fseek(fp, offset, base)用來(lái)控制文件內(nèi)部位置指針移動(dòng)。base是位置移動(dòng)的基準(zhǔn)點(diǎn)。offset是偏移量
ftell(fp)用于獲取位置指針的位置,相對(duì)于文件開(kāi)頭。