《C语言程序设计教程》(一)
- 標(biāo)識符規(guī)則
- 常量變量
- 變量的初始化
- 數(shù)據(jù)類型
- 實(shí)型數(shù)據(jù)
- 字符型數(shù)據(jù)
- 基本表達(dá)式和運(yùn)算符
- sizeof
- 類型強(qiáng)制轉(zhuǎn)化
- printf格式控制字符
- 附加格式符
- putchar
- 標(biāo)準(zhǔn)輸入
- scanf調(diào)用注意點(diǎn)
- getchar
- 條件運(yùn)算條件表達(dá)式
- if條件
- for
- breakcontinue
- 判斷是否是素?cái)?shù)
- 數(shù)組
- scanf函數(shù)
- getchar方法
- 字符數(shù)組
- 字符串
- 字符串的輸入輸出
- 字符串處理函數(shù)
- 指針
- 訪問類型
- 指針變量定義
- 指針的比較
- 指針和一維數(shù)組關(guān)系
- 利用指針遍歷一維數(shù)組的兩種方法
- 2維數(shù)組指針
- 二維數(shù)組的指針變量
- 字符串指針
- 字符串指針變量使用的注意點(diǎn)
- 函數(shù)返回值是指針
- 指向函數(shù)的指針
- 二級指針
- 指針函數(shù)
- 數(shù)組指針
- 指針tip
- 結(jié)構(gòu)體
- 結(jié)構(gòu)體變量的成員引用操作
- 結(jié)構(gòu)體變量的初始化
- 結(jié)構(gòu)體與數(shù)組
- 結(jié)構(gòu)體如何訪問數(shù)組成員
- 結(jié)構(gòu)體與指針
- 結(jié)構(gòu)體鏈表
- 動態(tài)內(nèi)存分配
- 內(nèi)存釋放
- 共用體
- 共用體的定義
- 共用體的訪問對象
- 結(jié)構(gòu)體和共用體的聯(lián)合使用
- 枚舉
- typedef
- 函數(shù)的申明與調(diào)用
- 參數(shù)傳遞
- 局部變量全局變量
- 變量的存儲類別
標(biāo)識符規(guī)則
常量、變量
int c= 7; #define PAI = 3.1415926;//常量的標(biāo)識符全好是大寫。變量的初始化
可以多個(gè)同類型的一起賦值
int c= 7,b = 6;數(shù)據(jù)類型
實(shí)型數(shù)據(jù)
也稱為浮點(diǎn)數(shù)。兩種表現(xiàn)形式:
- 十進(jìn)制小數(shù)
- 指數(shù)形式
需用的注意以下幾點(diǎn):
在實(shí)型計(jì)算中,不區(qū)分單精度還是雙精度,都按照double,除非,你在數(shù)字后面指定了f或F,則認(rèn)為是float。
double 提供16位有效數(shù)字,就是7位整數(shù)。
float提供7位有效數(shù)字,就是16位整數(shù)。
字符型數(shù)據(jù)
字符常量是用單引號括起來的字符。
- 只有用單引號括起來的才是字符常量,用雙引號或者其他符號括起來不是字符常量。
- 字符常量只能是單個(gè)字符,不能是多個(gè),轉(zhuǎn)義的除外。
- 字符常量以ASCLL碼存儲,范圍0-255,字符常量是以ASCLL
等價(jià)的整數(shù)值就行運(yùn)算。
轉(zhuǎn)義字符
是一種特殊的字符常量,以\開頭,有特定的含義。
\n 回車換行
\t 橫跳下一個(gè)制表符
\b 退格
\r 回車
\f 走紙換頁
\ 反斜線\
\’ 單引號
\” 雙引號
字符變量
char o = 'a';一個(gè)字符變量占一個(gè)字節(jié)的分配空間。
一個(gè)中文漢字=兩個(gè)字符,占2個(gè)字節(jié)。
字符串常量
字符串常量是由一對雙括號括起來,系統(tǒng)會自動在每個(gè)字符串結(jié)束后面加一個(gè)字符串結(jié)束標(biāo)志’\0’。
字符常量和字符串常量區(qū)別
在c語言中,可以把一個(gè)字符常量賦值給字符變量,但是不能把一個(gè)字符串常量賦值給字符串變量,因?yàn)樵?
c中,沒有定義相應(yīng)的字符串變量,在后面會講到用字符數(shù)組來存放一個(gè)字符串常量。
字符串常量的字節(jié)數(shù),是字符串的字符個(gè)數(shù)+1,因?yàn)檫€有一個(gè)字符串結(jié)束標(biāo)識符也占一個(gè)字節(jié)。
基本表達(dá)式和運(yùn)算符
在c語言中一些基本的,我就不講。
sizeof是用來結(jié)束數(shù)據(jù)的字節(jié)數(shù)。
/:是除法運(yùn)算,如果參加運(yùn)算的都是整型,那么結(jié)果就是整型,舍去小數(shù);但是如果參加的運(yùn)算有一個(gè)是實(shí)型,那么結(jié)果就是double。
%:求余運(yùn)算,要求參加運(yùn)算的量都是整型,然后取兩數(shù)的余數(shù)。
sizeof
這個(gè)功能是求數(shù)據(jù)在內(nèi)存中所占的字節(jié)數(shù)。
int a = sizeof(10);printf("%d",a);類型強(qiáng)制轉(zhuǎn)化
double c = (double)(a+b);printf格式控制字符
附加格式符
putchar
可以用來輸入字符常量和字符變量。
putchar('a');標(biāo)準(zhǔn)輸入
scanf(“格式控制字符”,地址表列); //地址列表中給出的各變量的地址,地址是通過取地址符&后面跟變量名來獲取的。scanf調(diào)用注意點(diǎn)
getchar
這個(gè)函數(shù)執(zhí)行的時(shí)候,會等待用戶來輸入一個(gè)字符。
條件運(yùn)算、條件表達(dá)式
a>b?a:bif條件
if的條件不一定是條件表達(dá)式為true,也可以是一個(gè)常量只要不是0,就可以的。
for
使用for循環(huán)的時(shí)候,如果3個(gè)判斷條件沒有時(shí),也要要分號隔開。
for(;(c = getchar())!='\n';)break、continue
break:是跳出、結(jié)束循環(huán),continue:是繼續(xù)循環(huán)。break使用范圍,就是在while、do….while、for、switch。而continue是結(jié)束本次循環(huán) ,只能在while、do….while、for中使用,如果在while和do…while中使用,遇到continue會直接回到while后面的判斷,而執(zhí)行for的時(shí)候就直接到for循環(huán)的第三個(gè)條件表達(dá)式。
判斷是否是素?cái)?shù)
素?cái)?shù)又稱質(zhì)數(shù),是指不能被其他的整數(shù)整除的自然數(shù),其算法思想:用n去依次除以2~~n-1之間的每一個(gè)數(shù),如果每次整除,則n是素?cái)?shù);只要有一次實(shí)現(xiàn)整除,則判斷不是質(zhì)數(shù),這個(gè)就是優(yōu)化,沒必要一直看到底。
int n,i,flag;i = 2;flag = 0;n = 0;printf("請隨便輸入一個(gè)數(shù):\n");scanf("%d",&n);for(i=2;i<=n-1;i++){if(n%i==0){flag =1;break;}}if(flag==1){printf("這個(gè)數(shù)不是質(zhì)數(shù)");}else{printf("這個(gè)是質(zhì)數(shù)");}數(shù)組
c語言中的數(shù)組長度不可以用變量去定義。
scanf函數(shù)
利用scanf輸入數(shù)據(jù),一次數(shù)據(jù)輸入的結(jié)束是通過,空格,Enter,Tab 來結(jié)束一次,特別是在循壞中。
getchar()方法
這個(gè)方法是用來輸入字符的,并且返回這個(gè)字符的ascll編碼,需要注意這個(gè)方法每次輸入只能是一個(gè)字符,如果輸入多個(gè),則只接收第一個(gè)字符,另外,如果多個(gè)字符輸入在一行,它的結(jié)束標(biāo)志,就是回車,如果每輸入一個(gè)字符換行,那么連續(xù)兩次回車,就是結(jié)束標(biāo)志。此外它比scanf輸入字符好,因?yàn)榭崭袼瑯幽芴幚?#xff0c;而scanf不行,它會當(dāng)做結(jié)束符。
字符數(shù)組
char a[10]={'a''b''c''d'};如果字符數(shù)組的長度大于字符個(gè)數(shù),那么系統(tǒng)默認(rèn)會給其他數(shù)組元素為'\0'如果你在定義的時(shí)候,指定字符,那么可以不顯示指定字符數(shù)組的長度,編譯器會自動知道。字符串
c語言的字符串是指有限個(gè)組成的字符序列,它是以字符數(shù)組的形式存放,并且以’\0’作為字符串的結(jié)束標(biāo)志。
char s[10] ={"hello"}如果字符數(shù)組的長度大于字符個(gè)數(shù),那么系統(tǒng)默認(rèn)會給其他數(shù)組元素為’\0’
處理字符數(shù)組時(shí)候,一旦遇到’\0’就表示字符串已經(jīng)結(jié)束,如果字符串有多個(gè)’\0’,那么會認(rèn)為在第一個(gè)’\0’之前的是有效字符。
字符串和字符數(shù)組最顯著的區(qū)別,就是字符數(shù)組中,如果數(shù)組長度等于字符個(gè)數(shù),那么是不需要添加’\0’
在計(jì)算字符串的長度時(shí),‘\0’是不參加計(jì)算的。
如果你在定義的時(shí)候,指定字符,那么可以不顯示指定字符數(shù)組的長度,編譯器會自動知道。
只要字符串沒有字符,那么系統(tǒng)會自動加上’\0’
如果你一直給字符串賦值,那么strlen是變的,這個(gè)一定要在后面注意,這點(diǎn)和java是不一樣。
字符串的輸入輸出
char a[20];char b[20];scanf("%s",a);//使用字符控制符去輸入,字符串必須是存放在字符數(shù)組中printf("%s",a);//打印的時(shí)候也是直接數(shù)組名gets(b);//傳入數(shù)組名,這種方法和上面比,每次只能輸入一個(gè)字符串,上面可以是多個(gè)。puts(b);//輸出完成后,會自動換行。注意如何利用scanf輸入多個(gè)字符串:
scanf("%s%s",a,c);一般的在scanf遇到一個(gè)%s,就是一次,千萬不能理解這個(gè)是一次輸入兩個(gè),那就不對了,不要看他們是同一行。
字符串處理函數(shù)
char c1[80]={"sdada"};char c2[80]={"hsdkjass"};int i =0;//strcat(c1,c2);//將后面的字符串連接到前面來//后面的字符串可以是數(shù)組名,//也可以是字符串常量,但是字符串1必須是字符串?dāng)?shù)組名。//strcpy(c1,c2);//將后面的字符串復(fù)制到前面字符數(shù)組//后面的字符串可以是數(shù)組名,//也可以是字符串常量,但是字符串1必須是字符串?dāng)?shù)組名。//c1="sdasda";錯(cuò)誤的//c1 = c2;錯(cuò)誤的//int r = strcmp(c1,c2);//字符串比較函數(shù)//返回一個(gè)整數(shù)值,如果是0,代表兩個(gè)字符串相等//如果是正整數(shù),代表前面字符串大//如果是負(fù)整數(shù),代表前面的字符串小。//比較的實(shí)質(zhì),是從開始比較每一個(gè)字符的ascll//這兩個(gè)參數(shù)可以是字符數(shù)組或者字符常量//兩個(gè)字符串之間比較絕對不可以用> < == !=int t = strlen(c1);//返回字符數(shù)組的實(shí)際長度不包含結(jié)束標(biāo)識符。//sizeof是返回參數(shù)的內(nèi)存空間,也就是字節(jié)數(shù)。//該方法的參數(shù)可以是字符數(shù)組或者字符常量指針
程序運(yùn)行時(shí),所有的程序和數(shù)據(jù)都是放在內(nèi)存中,內(nèi)存是以字節(jié)為單位的連續(xù)的存儲空間,每一個(gè)內(nèi)存都有一個(gè)編號,稱為內(nèi)存地址。
一個(gè)字節(jié)就是一個(gè)存儲單元。
變量的地址是由編譯器動態(tài)分配的,對用戶是無關(guān)的。
指針:就是指向某個(gè)對象(可能是簡單變量、數(shù)組、函數(shù))所占用的存儲單元的首地址,這里說明一下,一個(gè)對象,開辟的空間一定是連續(xù)的,所以,指針就是指向這個(gè)連續(xù)空間的首地址。
指針變量:存放變量地址的變量。
訪問類型
直接通過變量名來訪問。
先找到存放該變量的地址的變量,先找到地址,在訪問。
指針變量定義
int *i_pointer;//表示指向整型變量的指針變量。其中* 表示定義指針變量,前面的類型,也稱基類型,表示指針變量所指向的變量的類型。
指針變量只能指向定義時(shí)所規(guī)定類型的變量。
不可以將任何非地址的值,賦給指針變量,除了0(NULL)必須是大寫。
int *p;*p = 0;*p =NULL;指針變量定義好了之后,必須要初始化,否則變量值不確定。
指針初值,可以賦3種形式
*是間接訪問運(yùn)算符,它是先訪問指針變量,然后在訪問它指向的變量的值。
指針變量的算術(shù)運(yùn)算。
指針p+n,是指指針p原來指向的數(shù)據(jù)單元格之后的第n個(gè)數(shù)據(jù)單元格,而數(shù)據(jù)單元格和數(shù)據(jù)類型有關(guān)。
在這里,我要說明一下,數(shù)據(jù)存儲單元和內(nèi)存單元的對比。
數(shù)據(jù)存儲單元格是人們簡化內(nèi)存單元格的。
int *p;int a;p=&a;//假如a的地址是2000,則p+1 = 2004//原因int的數(shù)據(jù)類型占4個(gè)字節(jié)所以在這,你就要理解指針變話p++,就是使p指向下一個(gè)空間。
指針的比較
在同一段連續(xù)的存儲空間,如果p的地址值小于q的地址值,那么結(jié)果為1,反之為0。
指針和一維數(shù)組關(guān)系
數(shù)組名就是指針,是數(shù)組的首地址,這個(gè)叫做靜態(tài)指針。
int a[10];int *p;p =a;//p = &a[0]兩種等價(jià)根據(jù)指針運(yùn)算p+1,就是指向數(shù)組中的下一個(gè)元素。
利用指針遍歷一維數(shù)組的兩種方法
for(i=0;i<5;i++){scanf("%d",p+i);//根據(jù)i的變化,改變指針指向的地址}for(i=0;i<5;i++){printf("%d",*(p+i));}for(p=a;p<a+5;p++){scanf("%d",p);//指針初始值指向數(shù)組的首地址,指針的地址范圍應(yīng)該是控制數(shù)組首地址加上數(shù)組的個(gè)數(shù),自增改變指針的地址。}for(p=a;p<a+5;p++){printf("%d",*p);}在一維數(shù)組中
a[i] =p[i] = p+i = a+i//都表示是指向某一個(gè)元素2維數(shù)組指針
從二維數(shù)組來看,a是二維數(shù)組名,a就代表了整個(gè)二維數(shù)組的首地址。a+1代表第一行。
a[0]+1,就代表第一列。
故:
//在這里,我們把對二維數(shù)組的處理,當(dāng)成多個(gè)1維數(shù)組來處理。
在二維數(shù)組有兩個(gè)概念
- 行地址前就加*就變?yōu)榱械刂贰?/li>
- 列地址前加&就變?yōu)樾械刂贰?/li>
- 只有在列地址前加*才能訪問該二維數(shù)組的值。
二維數(shù)組的指針變量
int a[2][2];int (*p)[2];//指針變量的括號一定不能少p =a;int i,j;for(i =0;i<2;i++){for(j = 0;j<2;j++){scanf("%d",(*(p+i)+j));}}for(i =0;i<2;i++){for(j = 0;j<2;j++){printf("%d",*(*(p+i)+j));}}字符串指針
用指針變量操作字符串,指針變量指向的是字符串的首地址,也就是第一個(gè)字符地址。
char str[]="helloworld";char *p;//定義字符串指針p = str;//指向字符串的第一個(gè)字符的首地址int i = 0;for(i = 0;*p!='\0';p++){printf("%c",*p);printf("%s",p);//注意這種操作打印字符串是通過指向第一個(gè)指針的*地址*,這里就不是值了。一直到字符串結(jié)束,這種比較方便,后面使用的比較多。}字符串指針變量使用的注意點(diǎn)
char c1[10]="hello";char *pa;pa="hello"//表示指針變量指向的是字符串的第一個(gè)字符的首地址pa+2//指向字符串的第3個(gè)字符地址,指針變量可以指向字符串的任意位置,可以隨意改變指針變量的值c1作為字符串的數(shù)組名,可以作為首地址,可以進(jìn)行加減,但是不能賦給c1,因?yàn)閿?shù)組名是地址常量,不可以改變。(這點(diǎn)和前面使用一樣,需要注意)函數(shù)返回值是指針
定義函數(shù),返回類型是指針。
定義類型
數(shù)據(jù)類型 * 函數(shù)名 (參數(shù)表) int *max(){int i = 0;int k = 0;static int data[]={1,2,34,9,0,17,8,7};for(i=0;i<8;i++){if(data[i]>data[k]){k = i;}}return &data[k]; }void test19(){int *p;p = max();//需要定義的指針變量去接收函數(shù)返回值,這里定義的指針變量需要和函數(shù)定義的返回類型一致。printf("%d",*p);}指向函數(shù)的指針
指向函數(shù)的指針,實(shí)際上就是函數(shù)執(zhí)行的入口,函數(shù)名就代表中該函數(shù)的入口地址。
數(shù)據(jù)類型 (* 指針變量名) (參數(shù)表)對函數(shù)的調(diào)用
(* 指針變量名) (實(shí)參)例子:
int max1(int data[],int n){int i = 0;int k = 0;for(i=0;i<n;i++){if(data[i]>data[k]){k = i;}}return data[k]; }void test20(){int a[4] ={2,9,8,0};int (*p)(int a[],int n);//定義指針函數(shù)int m = 0;p = max1;//在此之前,你需要申明一下max1函數(shù),這里我申明了指向函數(shù)的入口m = (*p)(a,4);//執(zhí)行函數(shù)printf("%d",m);}二級指針
定義:一個(gè)指針變量存放的是另一個(gè)指針變量地址。
int i = 78;int *p;int **pp;//定義二級指針p = &i;pp = &p;printf("%d",i);printf("%d",*p);printf("%d",**pp);指針函數(shù)
定義: 數(shù)組中的每一個(gè)元素都是指針類型。
char *a[100]={"hello","world"};int i = 0;for(i = 0;i<2;i++){printf("%s",a[i]);//a[0]就是指向第一個(gè)數(shù)組元素的(首地址)指針,所以直接打印字符串//在前面說過,如果指針指向的是字符串的首地址,打印出來,則是整個(gè)字符串}數(shù)組指針
定義:指向整個(gè)數(shù)組的指針。
int a[4]={1,2,3,4};int (*p)[4];p = a;//這個(gè)是指向整個(gè)數(shù)組的指針,這里注意區(qū)分之前用的多的是指向數(shù)組的第一個(gè)元素的指針。int a[2][3]={1,2,3,4,5,6};int (*p)[3] = a;//這里的指針是數(shù)組中存在每一個(gè)元素首地址的指針集合,而這里每一個(gè)元素?fù)Q成一行的首地址,這里需要重點(diǎn)理解一下。為什么可以指向一個(gè)二維數(shù)組呢,原因很簡單,你可以這樣理解,二維數(shù)組其實(shí),我們可以看成2行的1維數(shù)組,p[0]就是指向1,2,3的首地址1,p[1]就是指向2,3,4的首地址2,然后p[0]+2,就是指針移動指向3。printf("%d",*(p[1]));printf("%d",*(*(p+1)+1));//訪問第二行的第二個(gè)元素。指針tip
在前面我們說過,數(shù)組名是靜態(tài)指針,不可以進(jìn)行自加自減,但是可以執(zhí)行a+1等運(yùn)算操作,注意一下。
結(jié)構(gòu)體
我們前面學(xué)習(xí)了,可以利用數(shù)組進(jìn)行同一種數(shù)據(jù)類型的處理,而我們也是有可能把不同的數(shù)據(jù)類型作為一個(gè)整體,這時(shí),就可以選用結(jié)構(gòu)體來處理這種數(shù)據(jù)。
結(jié)構(gòu)體作為一種數(shù)據(jù)結(jié)構(gòu),是不太方便好去遍歷,我們可以通過鏈表去實(shí)現(xiàn)對結(jié)構(gòu)體的遍歷。鏈表是可以通過結(jié)構(gòu)體去實(shí)現(xiàn)的。
struct date{int year;int months;int days;};struct date birth;//定義一個(gè)結(jié)構(gòu)體date的變量//需要注意的是定義結(jié)構(gòu)體類型,本身不占用存儲空間,//只是說明了結(jié)構(gòu)體組織形式,只有定義結(jié)構(gòu)體;變量,才占用空間。//在本例中,結(jié)構(gòu)體占的空間,就是3個(gè)int所占空間之和。struct date birth1,birth2,birth3//定義多個(gè)結(jié)構(gòu)體變量,用逗號隔開。struct date{int year;int months;int days;} birthday;//可以在定義結(jié)構(gòu)體類型時(shí),一起定義結(jié)構(gòu)體變量。下面這是我們處理結(jié)構(gòu)體定義常用方法。利用typeof定義新的結(jié)構(gòu)體類型名代替定義的結(jié)構(gòu)體類型名。
typedef struct date{int year;int months;int days;} Date;Date birthday;//這樣定義結(jié)構(gòu)體變量就簡單,也好記。struct date birthday兩種等價(jià)結(jié)構(gòu)中定義中,可以嵌套結(jié)構(gòu)體變量。
typedef struct date{int year;int months;int days;struct birthday1;} Date;結(jié)構(gòu)體變量的成員引用操作
.是結(jié)構(gòu)體成員運(yùn)算符,在所有優(yōu)先級中是最高的。
struct StudentDate{int year;int month;int day;};struct Student{int num;char name[20];char sex[10];float score;struct StudentDate birthday;};struct Student s;//定義結(jié)構(gòu)體變量scanf("%d",&s.num);//如果直接是結(jié)構(gòu)體//的成員,直接通過.運(yùn)算符來進(jìn)行操作printf("%d",s.num);scanf("%d",&s.birthday.year);printf("%d",s.birthday.year);//如果是內(nèi)嵌結(jié)構(gòu)體成員,//則需要通過外部的結(jié)構(gòu)體變量去引//用內(nèi)部結(jié)構(gòu)體變量的成員,這里需要注意內(nèi)部結(jié)構(gòu)體變量已經(jīng)申明在外部結(jié)構(gòu)體中,不需要在定義了。結(jié)構(gòu)體變量的初始化
struct StudentDate{int year;int month;int day;} a={1996,9,10};struct StudentDate{int year;int month;int day;};struct StudentDate a ={199,9,10};//定義結(jié)構(gòu)體變量并賦值- 一定不能在結(jié)構(gòu)體內(nèi)部初始化。
- 賦值的時(shí)候一定要和結(jié)構(gòu)體中定義的順序一致。
- 如果結(jié)構(gòu)體中有內(nèi)嵌,初始化和外部結(jié)構(gòu)體一起初始化,按照順序即可。
結(jié)構(gòu)體與數(shù)組
結(jié)構(gòu)體中成員可以是數(shù)組類型
struct student{int a[10];};struct student s;scanf("%d",&s.a[1]);printf("%d",s.a[1]);結(jié)構(gòu)體數(shù)組,即該數(shù)組中每一個(gè)元素都是結(jié)構(gòu)體類型。
struct student{int a[10];};struct student s[3];//定義了一個(gè)包含3個(gè)元素//的數(shù)組,并且每一個(gè)元素都是結(jié)構(gòu)體類型scanf("%d",&s[2].a[1]);printf("%d",s[2].a[1]);結(jié)構(gòu)體數(shù)組初始化:
struct student{int a[10];} s[3]={{12},{22},{4}};結(jié)構(gòu)體如何訪問數(shù)組成員
這里演示的是通過結(jié)構(gòu)體指針去訪問,通過結(jié)構(gòu)體變量訪問比較簡單,自行看。
struct Student {int num;char name[20];float score[5]; };p->score[0]結(jié)構(gòu)體與指針
結(jié)構(gòu)體鏈表
結(jié)構(gòu)體成語可以指向本結(jié)構(gòu)體類型的指針,可以用這個(gè)來構(gòu)造比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)體,鏈表。
鏈表是由稱為節(jié)點(diǎn)的元素組成,節(jié)點(diǎn)多少根據(jù)需要來定。
每一個(gè)節(jié)點(diǎn)包含:
鏈表結(jié)構(gòu)特點(diǎn):鏈表有一個(gè)首指針,它指向鏈表的第一個(gè)節(jié)點(diǎn),最后一個(gè)節(jié)點(diǎn)稱為 “表尾”,表尾節(jié)點(diǎn)的指針為null。
動態(tài)內(nèi)存分配
malloc:從內(nèi)存中申請一塊指定字節(jié)大小的連續(xù)空間,返回該存儲地址的首地址作為函數(shù)的返回值,如果申請失敗,說明沒有足夠的空間可以分配,返回空指針。
int *p;p = (int *)malloc(sizeof(int));//通過該函數(shù)動態(tài)申請了一個(gè)int類型大小if(p!=null){*p = 23;}else{exit(1);//exit是系統(tǒng)標(biāo)準(zhǔn)函數(shù),作用是關(guān)閉//所有打開文件,并終止程序執(zhí)行。參數(shù)為0是正常結(jié)束,非0//表示不正常結(jié)束。}由于該函數(shù)返回的是void類型的指針,所以需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換,轉(zhuǎn)換為指針變量所應(yīng)該指向的數(shù)據(jù)類型。
內(nèi)存釋放
free()函數(shù)。
注意點(diǎn):
共用體
有時(shí),我們希望在不同的時(shí)刻把不同的類型數(shù)據(jù)存放到同一個(gè)內(nèi)存單元中。
共用體的定義
union un{float f;int i ;char c;};//定義共用體union un u;//定義共用體變量union un1{float f;int i ;char c;}u;//定義共用體變量和類型注意點(diǎn):
共用體的訪問對象
通過.運(yùn)算。
u.c = 'a';如果是定義的是指針,那么同樣可以通過—>去訪問對象。
- 由于共用體各個(gè)成員都共用一段存儲空間,所以在任意的時(shí)刻,只能有一種數(shù)據(jù)類型存放在共用體變量中,也就是說任意一個(gè)時(shí)刻,只有一個(gè)成員有意義。
- 在引用共用體變量時(shí),必須保證其存儲類型的一致性,在一次程序運(yùn)行時(shí),一個(gè)成員操作了申明類型,在下一次中,還必須是這種類型。
- 共用體不能作為函數(shù)參數(shù)
- 共用體不能初始化,原因很簡單,如果初始化的話,那不就是說他們同時(shí)有意義,這不符合共合體的使用。
結(jié)構(gòu)體和共用體的聯(lián)合使用
共用體可以出現(xiàn)在結(jié)構(gòu)體中,結(jié)構(gòu)體也可以出現(xiàn)在共用體中。
union un{int fivescore;float hunscore; };struct Student{int num;char name[20];char sex;int type;union un scrore;//這里將共用體定義在結(jié)構(gòu)體中,需要定義共用體變量。(如果這里是定義結(jié)構(gòu)體,那么這里就需要定義結(jié)構(gòu)體變量) };p1->scrore.hunscore = hunscore1;//訪問內(nèi)部共用體變量的時(shí)候,就需要注意,定義結(jié)構(gòu)體指針,通過—>來訪問結(jié)構(gòu)體的變量,因?yàn)檫@時(shí)得到的是共用體的變量,通過共用體變量名訪問成員,就必須是.運(yùn)算符。枚舉
枚舉類,一個(gè)變量在很小的范圍內(nèi)取值,則可以使用枚舉類。
enum Bool{Flase,True};//定義枚舉類型enum Bool bool;//定義枚舉變量enum Bool1{Flase1,True1} bool1; //在定義枚舉類型和枚舉變量printf("%d",True);//打印枚舉量的值,雖然定義和結(jié)構(gòu)體很類似,但是訪問成員不是通過.運(yùn)算。注意點(diǎn):
- 枚舉元素是常量,有固定的數(shù)值,按枚舉的順序分別是 整數(shù)0,1,2,3;不能被用作變量,即不可以出現(xiàn)在賦值號的左邊。
- 不能有兩個(gè)元素相同的枚舉元素,枚舉元素也不能與其他變量同名。
- 枚舉元素作為常數(shù)處理,遇到枚舉元素,編譯器會將其中第一個(gè)元素賦值為0,然后依次疊加。自己可以修改為枚舉元素指定值,然后排在該枚舉元素后面的值,將自動一次疊加1。
typedef
用于用戶自己定義類型說明符。
typedef int INT;INT a = 5;//等價(jià)于int a =5typedef char NAME[20];NAME a1;//等價(jià)于 char a1[20];typedef struct Student{int num;float score;} S;S student;//等價(jià)于struct Student studenttypedef char *p;p p1;//等價(jià)于 char * p1這個(gè)使用你只需要,找到原始的元素定義的變量,直接用這個(gè)變量來簡化申明你自己定義的變量。
函數(shù)的申明與調(diào)用
函數(shù)聲明
c語言編譯,是從上到下,如果被調(diào)函數(shù)不在調(diào)用函數(shù)之前,則必須顯示申明,否則報(bào)錯(cuò)。
函數(shù)類型 被調(diào)函數(shù)名(形參表列)//這種必須包括形參類型、變量名函數(shù)類型 被調(diào)函數(shù)名(形參類型表列)//這種只是形參類型,沒有變量名有些標(biāo)準(zhǔn)的庫函數(shù),只需要導(dǎo)入頭文件即可。
參數(shù)傳遞
分類:
當(dāng)形參為簡單變量時(shí),在函數(shù)調(diào)用過程中,數(shù)據(jù)只能由實(shí)參傳給形參,而不能由形參傳回給實(shí)參,這種數(shù)據(jù)傳遞方式是單向,無論形參如果修改值,都不會影響實(shí)參的值。
數(shù)組作為參數(shù)傳遞:
局部變量、全局變量
局部變量:作用域僅限于函數(shù)內(nèi)有效,離開該函數(shù)則沒有用。
- 在參數(shù)傳遞時(shí),形參就是該調(diào)用函數(shù)的局部變量。
- 在不同的函數(shù)中,可以使用相同的變量名,互相不干擾。
全局變量:是指定義在函數(shù)外的變量,作用從定義的位置到本源程序文件尾。
變量的存儲類別
變量存儲方式:
變量存儲類別
static變量。又稱之為靜態(tài)變量。在函數(shù)局部定義中的變量,函數(shù)執(zhí)行,該值仍然保留,等待下次該函數(shù)執(zhí)行,除非該函數(shù)在也不執(zhí)行,就釋放。
靜態(tài)變量在編譯時(shí),只賦初值一次,賦值為0。而自動變量,每次執(zhí)行完函數(shù),都會重新賦值。自動變量未賦值,它的值是不確定的。
雖然靜態(tài)變量的值,函數(shù)執(zhí)行結(jié)束,變量空間未釋放,但靜態(tài)變量不可以被其他函數(shù)調(diào)用。
寄存器變量。如果一個(gè)函數(shù)頻繁的使用某個(gè)變量計(jì)算,那么就可以使用寄存器變量。寄存器變量,只能給自動變量和形參定義,不可以將全局、靜態(tài)變量定義為寄存器變量。由于計(jì)算機(jī)的寄存器數(shù)目多,所以不宜定義太多寄存器變量。
extern(外部變量),這個(gè)可以類比是全局變量,但是全局變量是在該定義之后才可以使用該變量,那么在之前使用,則需要用extern申明,就可以當(dāng)成全局變量使用,否則會產(chǎn)生語法錯(cuò)誤。
總結(jié)
以上是生活随笔為你收集整理的《C语言程序设计教程》(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: snowy框架
- 下一篇: Ingress暴露服务的方式