日本欧美一区-日本欧美一区二区三区片-日本强好片久久久久久AAA-日本-区一区二区三区A片-日本人伦一区二区三区-日本人妻A片成人免费看

電子開(kāi)發(fā)網(wǎng)

電子開(kāi)發(fā)網(wǎng)電子設(shè)計(jì) | 電子開(kāi)發(fā)網(wǎng)Rss 2.0 會(huì)員中心 會(huì)員注冊(cè)
搜索: 您現(xiàn)在的位置: 電子開(kāi)發(fā)網(wǎng) >> 編程學(xué)習(xí) >> C語(yǔ)言 >> 正文

C語(yǔ)言詳細(xì)入門(mén)教學(xué)_c語(yǔ)言教程_C語(yǔ)言入門(mén)教程

作者:佚名    文章來(lái)源:網(wǎng)絡(luò)    點(diǎn)擊數(shù):    更新時(shí)間:2023/10/10

目錄

第1章 什么是C語(yǔ)言

第2章 算法

第3章 最簡(jiǎn)單的C程序設(shè)計(jì)

3.1 數(shù)據(jù)類(lèi)型

3.1.1 常量

3.1.2 變量

3.1.3 數(shù)據(jù)類(lèi)型

3.2 運(yùn)算符和表達(dá)式

3.3 數(shù)據(jù)的輸入輸出

3.3.1數(shù)據(jù)的輸入

3.3.2數(shù)據(jù)的輸出

第4章 選擇結(jié)構(gòu)程序設(shè)計(jì)

4.1 if條件選擇

4.2 switch多分枝選擇

第5章 循環(huán)結(jié)構(gòu)程序設(shè)計(jì)

5.1 for循環(huán)結(jié)構(gòu)

5.2 while循環(huán)結(jié)構(gòu)

第6章 數(shù)組

6.1 一維數(shù)組

6.2 二維數(shù)組

6.3 字符數(shù)組

第7章 函數(shù)的使用

7.1 為什么使用函數(shù)

7.2 函數(shù)的定義

7.3 函數(shù)的調(diào)用方式

7.4 數(shù)組作為函數(shù)參數(shù)

7.5 內(nèi)部函數(shù)和外部函數(shù)

7.5.1 局部變量

7.5.2 全局變量

內(nèi)部函數(shù)

外部函數(shù)

第8章 指針

8.1 什么是指針

8.2 指針變量

8.3 指針的使用方式

8.3.1指針變量的使用

8.3.2 指針變量作為函數(shù)參數(shù)

8.3.3 通過(guò)指針引用數(shù)組

8.3.4 通過(guò)指針引用字符串

8.3.5 指向函數(shù)的指針(函數(shù)指針變量)

8.3.6返回指針值的函數(shù)

8.3.7 指針數(shù)組

8.3.8 動(dòng)態(tài)內(nèi)存分配與指向它的指針變量

第9章 自定義數(shù)據(jù)類(lèi)型

9.1 結(jié)構(gòu)體類(lèi)型

9.2 共用體類(lèi)型

9.3 枚舉類(lèi)型

第10章 對(duì)文件的輸入輸出(主要討論數(shù)據(jù)文件)

10.1 什么是文件

10.2 文件分類(lèi)

10.3 文件的使用


第1章 什么是C語(yǔ)言


C語(yǔ)言的先祖是BCPL語(yǔ)言。它是由美國(guó)貝爾實(shí)驗(yàn)室的D.M.Ritchie在1972-1973年間設(shè)計(jì)出來(lái)的計(jì)算機(jī)編程語(yǔ)言。C語(yǔ)言還是目前使用最為廣泛的計(jì)算機(jī)編程語(yǔ)言之一,由于它學(xué)習(xí)起來(lái)簡(jiǎn)單、使用方便、功能強(qiáng)大和容易上手等特點(diǎn),普遍被廣大程序設(shè)計(jì)者使用。



第2章 算法

算法需要有以下特性:(1)有窮性:有限的操作步驟;(2)確定性:每個(gè)步驟都是確定的,不能含糊;(3)有零個(gè)或多個(gè)輸入:從外界獲取必要輸入信息;(4)有一個(gè)或多個(gè)輸出:一個(gè)沒(méi)輸出的算法沒(méi)有意義;(5)有效性:每個(gè)步驟都能有效執(zhí)行;



第3章 最簡(jiǎn)單的C程序設(shè)計(jì)

3.1 數(shù)據(jù)類(lèi)型

3.1.1 常量

常量包括以下幾種:整形常量、實(shí)型常量、字符常量、字符串常量和符號(hào)常量。整形常量如100等;實(shí)型常量有兩種形式,一種是十進(jìn)制小數(shù)形式如10.21,另一種是指數(shù)形式如12.34e3(代表12.34×10*3);字符常量包括普通字符如‘a(chǎn)’,和轉(zhuǎn)義字符‘\n’。字符串常量是使用雙撇號(hào)把若干個(gè)字符括起來(lái),如“boy123”。符號(hào)常量是指使用#define指令,指定一個(gè)符號(hào)代表一個(gè)常量,如#define P1 3.12,這時(shí)P1代表3.12。

3.1.2 變量

變量代表一個(gè)有名字的、具有特定屬性的一個(gè)存儲(chǔ)單元,存儲(chǔ)單元里的值是可以改變的,所以變量的值可以改變。在使用變量時(shí)必須先定義,后使用。在有些情況下我們不希望變量的值被改變,這時(shí)可以將變量定義為常變量。使用const可以將變量定為常變量,如const int P1=12,之后P1的值將不會(huì)被改變。

3.1.3 數(shù)據(jù)類(lèi)型

在定義變量和函數(shù)時(shí),需要指定相應(yīng)的數(shù)據(jù)類(lèi)型,數(shù)據(jù)類(lèi)型包括:整型類(lèi)型、浮點(diǎn)類(lèi)型、枚舉類(lèi)型(enum)、空類(lèi)型(void)和派生類(lèi)型。

整型類(lèi)型:注意整型中,區(qū)分有無(wú)符號(hào)的整型,無(wú)符號(hào)需要加上unsigned,如unsigned int a;

類(lèi)型 字節(jié)
基本整形(int) 2或4
短整型(short) 2
長(zhǎng)整型(long int) 4
雙長(zhǎng)整型(long long int) 8
字符型(char) 1
布爾型(bool)值true 和 false 1

浮點(diǎn)類(lèi)型:

類(lèi)型 字節(jié)
單精度浮點(diǎn)型(float) (有效6位) 4
雙精度浮點(diǎn)型(double) (有效8位) 8
長(zhǎng)雙精度浮點(diǎn)型(long double) 有效(16位) 16
復(fù)數(shù)浮點(diǎn)型 (不常用)

派生類(lèi)型:

指針類(lèi)型(*) 數(shù)組類(lèi)型([ ]) 結(jié)構(gòu)體類(lèi)型(struct) 共用體類(lèi)型(union) 函數(shù)類(lèi)型

數(shù)據(jù)以補(bǔ)碼的形式存儲(chǔ)再存儲(chǔ)空間中。

補(bǔ)碼求法:正·數(shù)的補(bǔ)碼就是其二進(jìn)制碼如5的補(bǔ)碼是0000 0000 0000 0101,負(fù)數(shù)的補(bǔ)碼是其正數(shù)的二進(jìn)制碼取反,再加1,如-5,它的正數(shù)是5,5的二進(jìn)制碼是0000 0000 0000 0101,取反為1111 1111 1111 1010,再加1,得-5的補(bǔ)碼是1111 1111 1111 1011。


3.2 運(yùn)算符和表達(dá)式

經(jīng);祀鹊倪\(yùn)算符有:/(除法運(yùn)算符)、%(求余運(yùn)算符)、++和--(自增和自減運(yùn)算符),例如++i(--i),它們?cè)谑褂胕之前,先使i的值加(減)1;i++(i--),它們?cè)谑褂胕之后,使i的值加(減)1。

強(qiáng)制類(lèi)型轉(zhuǎn)換符:使用強(qiáng)制類(lèi)型轉(zhuǎn)換符可以使一個(gè)表達(dá)式轉(zhuǎn)換成所需的類(lèi)型,一般形式如:(類(lèi)型名)(表達(dá)式),例如(double)a,(float)(5%3)將5%3的值轉(zhuǎn)換為float類(lèi)型。

需要注意的運(yùn)算符:= 賦值運(yùn)算符、== 等于運(yùn)算符、?:條件運(yùn)算符、(sizeof)求字節(jié)數(shù)運(yùn)算符、,->成員運(yùn)算符、<<左移運(yùn)算符、復(fù)合的賦值運(yùn)算符,例如j×=y+8,等價(jià)于j=j×(y+8)等。

左移運(yùn)算符(<<)

將一個(gè)運(yùn)算對(duì)象的各二進(jìn)制位全部左移若干位(左邊的二進(jìn)制位丟棄,右邊補(bǔ)0)。

例:a = a << 2 將a的二進(jìn)制位左移2位,右補(bǔ)0,

左移1位后a = a * 2;

若左移時(shí)舍棄的高位不包含1,則每左移一位,相當(dāng)于該數(shù)乘以2。

右移運(yùn)算符(>>)

將一個(gè)數(shù)的各二進(jìn)制位全部右移若干位,正數(shù)左補(bǔ)0,負(fù)數(shù)左補(bǔ)1,右邊丟棄。

操作數(shù)每右移一位,相當(dāng)于該數(shù)除以2。

例如:a = a >> 2 將a的二進(jìn)制位右移2位,

左補(bǔ)0 or 補(bǔ)1 得看被移數(shù)是正還是負(fù)。

注意: 當(dāng)一個(gè)占多字節(jié)的整型數(shù)據(jù),給一個(gè)占少字節(jié)的整型變量或字符變量賦值時(shí),只能將它的低字節(jié)原封不動(dòng)的送到被賦值變量,例如:a占4個(gè)字節(jié),b占2個(gè)字節(jié),當(dāng)b=a時(shí),只能把a(bǔ)的2位低字節(jié)賦給b。



3.3 數(shù)據(jù)的輸入輸出

3.3.1數(shù)據(jù)的輸入

通過(guò)標(biāo)準(zhǔn)的輸入函數(shù)完成,系統(tǒng)函數(shù)庫(kù)中標(biāo)準(zhǔn)的輸入函數(shù)有:scanf(格式輸入)、gets(輸入字符串)、getchar(輸入字符)。

scanf函數(shù)的一般形式:scanf(格式控制,地址列表),如scanf(“a=%f,b=%f”,&a,&b);

gets函數(shù)的一般形式:gets(地址),如int a[10],gets(a),從鍵盤(pán)輸入字符串,送到數(shù)組a中。

getchar函數(shù)的一般形式:a=getchar(),從鍵盤(pán)輸入一個(gè)字符,送到字符變量a。

3.3.2數(shù)據(jù)的輸出

標(biāo)準(zhǔn)輸出函數(shù)有:printf(格式輸出)、puts(輸出字符串)、putchar(輸出字符)

printf函數(shù)的一般格式:printf(格式控制,輸出列表),如printf(“a=%d,ch[]=%s”,a,ch);a是變量名,ch是數(shù)組ch[]的數(shù)組名。

puts函數(shù)的一般格式:puts(地址),如int a[10],puts(a),這地址是指要輸出數(shù)組的地址。

putchar函數(shù)的一般格式:putchar(字符),如char c=‘a(chǎn)’,putchar(c),輸出字符變量c的值。

printf 的格式字符(scanf的格式基本一樣)

d,i o x,X u c s f e,E g,G
十進(jìn)制輸出整數(shù) 八進(jìn)制 十六進(jìn)制 無(wú)符號(hào)十進(jìn)制輸出整數(shù) 字符輸出 字符串輸出 小數(shù)形式輸出單、雙精度數(shù) 指數(shù)形式輸出實(shí)數(shù) 選用%f或%e中輸出寬度較短的一種格式

printf 和scanf 的格式附加字符

printf printf printf scanf scanf
l m(代表一個(gè)正整數(shù)) n(代表一個(gè)正整數(shù)) l h
用于長(zhǎng)整型整數(shù),可加于d,0,x,u前面 數(shù)據(jù)最小寬度 對(duì)實(shí)數(shù)時(shí),表示輸出n個(gè)小數(shù),字符串時(shí),表示截取字符個(gè)數(shù) 用于輸入長(zhǎng)整型數(shù)據(jù),如%ld,%lx,%lo 用于輸入短整型數(shù)據(jù),如%hd,%ho,%hx


第4章 選擇結(jié)構(gòu)程序設(shè)計(jì)

4.1 if條件選擇

if語(yǔ)句的一般形式是:if(表達(dá)式)語(yǔ)句1,如if(a+b>10) printf("yes");表達(dá)的意思是,如果a+b的值大于10,則執(zhí)行printf函數(shù)輸出yes。通過(guò)判斷if表達(dá)式的真假,來(lái)判斷是否執(zhí)行語(yǔ)句1。


if語(yǔ)句一般與else語(yǔ)句一起使用,以實(shí)現(xiàn)更多功能,例如

if(表達(dá)式) 語(yǔ)句1;

else 語(yǔ)句;

例如 if(a>b) a=b;

else b=a;

這里表示如果a>b,則a=b,否則b=a;


if和else還可以嵌套使用,例如

if(number>50) a=1;
else if(number>40) a=2;
else if(number>30) a=3;
else if(number>20) a=4;
else a=5;

注意 : 關(guān)系運(yùn)算符的優(yōu)先級(jí)低于算術(shù)運(yùn)算符

關(guān)系運(yùn)算符的優(yōu)先級(jí)高于賦值運(yùn)算符

&& ||
邏輯非 邏輯與 邏輯或

。ㄟ壿嫹牵,如果a為真,則!a為假,如果a為假,則!a為真。

優(yōu)先級(jí):。ǚ牵>&&(與)>||(或)

優(yōu)先級(jí):。ǚ牵>算術(shù)運(yùn)算符>關(guān)系運(yùn)算符>&&(與)>||(或)>賦值運(yùn)算符



4.2 switch多分枝選擇

switch語(yǔ)句是多分枝選擇語(yǔ)句,switch的一般形式如下:

switch(表達(dá)式)
{
    case 常量1 :語(yǔ)句1
    case 常量2 :語(yǔ)句2
    case 常量n :語(yǔ)句n
    default :語(yǔ)句n+1
}

注意:switch后面括號(hào)內(nèi)的“表達(dá)式”,其值的類(lèi)型應(yīng)為整數(shù)類(lèi)型(字符型)

在執(zhí)行switch語(yǔ)句時(shí),根據(jù)switch表達(dá)式的值找到相應(yīng)的入口標(biāo)號(hào),然后從相應(yīng)的case中執(zhí)行語(yǔ)句,在執(zhí)行完入口標(biāo)號(hào)的case語(yǔ)句后,程序會(huì)繼續(xù)往下執(zhí)行下面的case標(biāo)號(hào)的語(yǔ)句,直到switch程序結(jié)束,所以一般情況下需要在case子句后面,應(yīng)用break語(yǔ)句,使程序跳出switch結(jié)構(gòu)。如果沒(méi)有與switch表達(dá)式相匹配的case常量,流程會(huì)轉(zhuǎn)去執(zhí)行default標(biāo)號(hào)后面的語(yǔ)句。

switch語(yǔ)句使用例子:

#include<stdio.h>
int mian()
{
char ch;
int a=0;
ch=getchar();
    switch(ch)
    {
        case 'a' : printf("a");break;
        case 'b' : printf("b");break; 
        case 'c' : printf("c");break;
        default :  printf("d");
    }
return 0;
}



第5章 循環(huán)結(jié)構(gòu)程序設(shè)計(jì)

5.1 for循環(huán)結(jié)構(gòu)

for循環(huán)的一般形式: for(表達(dá)式1;表達(dá)式2;表達(dá)式3) 語(yǔ)句,例如

for(i=1;i<10;i++)

sum=sum+i;

其中表達(dá)式1可以省略,如for(;i<10;i++),但分號(hào)不能省。但是當(dāng)表達(dá)式2省略時(shí),表示無(wú)限循環(huán)。

for循環(huán)實(shí)現(xiàn)冒泡算法:

void xunhuan(int r[],int n)
{
    int i,j,temp=0;
    for(i=1;i<n;i++)
        for(j=1;j<=n-i;j++)
        if(r[j]>r[j+1])
            {
                temp=r[j];
                r[j]=r[j+1];
                r[j+1]=temp;
            }
}

5.2 while循環(huán)結(jié)構(gòu)

while實(shí)現(xiàn)循環(huán)有兩種方式,一種是使用do.....while結(jié)構(gòu),另一種是使用while結(jié)構(gòu)。


do.....while語(yǔ)句的一般形式為:

do

{語(yǔ)句}

while(表達(dá)式);

例如:

#include<stdio.h>
int main()
{
    int i=1,sum=0;
    do
        {
        sum=sum+i;
        i++;
        }while(i<=100);
printf("sum=%d\n",sum);
return 0;
}


while語(yǔ)句的一般形式為:

while(表達(dá)式)語(yǔ)句;

例如,使用while和for語(yǔ)句實(shí)現(xiàn)的冒泡算法

#include<stdio.h>
int main()
{
    int i=0,j=0,flag=1,temp=0;
    int a[5]={10,2,57,7,98};
    while((i<4)&&flag)
        {
            flag=0
            for(j=0;j<4-i;j++)
                if(a[j]>a[j+1])
                {
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                    flag=1;
                }
             i++;
        } 
    for{i=0;i<4;i++} 
        printf("%d ",a[i]);
    return 0;
}

注意:break語(yǔ)句和continue語(yǔ)句的區(qū)別是,在執(zhí)行for或while循環(huán)語(yǔ)句時(shí),通過(guò)break語(yǔ)句可以提前終止循環(huán),跳出循環(huán)體。而continue語(yǔ)句只是提前結(jié)束本次循環(huán),而不是終止整個(gè)循環(huán),然后繼續(xù)執(zhí)行下一次循環(huán)。



第6章 數(shù)組

6.1 一維數(shù)組

數(shù)組是一組有序數(shù)據(jù)的集合,數(shù)組中的每個(gè)元素都是同一種類(lèi)型。通過(guò)數(shù)組可以存儲(chǔ)一組數(shù)據(jù)或多組數(shù)據(jù)。定義一維數(shù)組的一般形式為:類(lèi)型符 數(shù)組名 [常量表達(dá)式];例如int a[10],定義了一個(gè)名為a的數(shù)組,它包含10個(gè)元素,它第一個(gè)元素是a[0]。當(dāng)數(shù)組常量表達(dá)式為空時(shí),數(shù)組的長(zhǎng)度由初始化列表中元素的個(gè)數(shù)決定,例如int a[ ]={1,2},這時(shí)a數(shù)組的長(zhǎng)度為2。


數(shù)組的常量表達(dá)式可以是常量和符號(hào)常量(#define P1 3.12,其中P1代表符號(hào)常量),但不能是變量。如果數(shù)組是在被調(diào)用的函數(shù)里面(不包括主函數(shù))定義的數(shù)組,其長(zhǎng)度可以是變量或非常量表達(dá)式。例如:

void fun(int n)
{
  int a[2*n];//合法,n的值從實(shí)參傳來(lái)
.
.
.
}

這種情況稱(chēng)為“可變長(zhǎng)數(shù)組”,允許每次調(diào)用fun函數(shù)時(shí),n有不同的值,但在執(zhí)行fun函數(shù)時(shí),n的值是不變的。如果指定fun函數(shù)中的a數(shù)組為靜態(tài)(static)存儲(chǔ)方式,則不能用“可變長(zhǎng)數(shù)組”,例如:static int a[2*n];這是不合法的,即可變長(zhǎng)數(shù)組不能定義為靜態(tài)存儲(chǔ)方式。


一維數(shù)組的數(shù)組名代表數(shù)組的起始地址。一維數(shù)組的初始化可以用“初始化列表”或給數(shù)組元素逐個(gè)賦值,其中“初始化列表”的方式,如:int a[10]={0,1,2,3,4};,把初始化列表的數(shù)值,逐個(gè)賦給a數(shù)組的前5個(gè)元素,系統(tǒng)會(huì)自動(dòng)給后面5個(gè)元素賦初值為0。給數(shù)組元素賦值,如a[0]=1;

數(shù)組中的元素引用,可以通過(guò)數(shù)組名加下標(biāo)的方式,一般形式為:數(shù)組名[下標(biāo)],下標(biāo)可以是整型常量、整型的符號(hào)常量、整型表達(dá)式或者是整型變量,如int i=1; b=a[i]。


數(shù)組實(shí)現(xiàn)的冒泡算法

#include<stdio.h>
int main()
{
  int a[10];
  int i,j,t;
  printf("input 10 numbers :\n");
  for(i=0;i<10;i++)
     scanf("%d",&a[i]);
  printf("\n");
  for(i=0;i<9:i++)
     for(j=0;j<9-i;j++)
         if(a[j]>a[j+1])
           {t=a[j];a[j]=a[j+1];a[j+1]=t;}
  printf("the sorted numbers :\n");
  for(j=0;j<10;j++)
     {
        printf("%d",a[j]);
     }
  printf("\n");
  return 0;
}


6.2 二維數(shù)組


二維數(shù)組定義的一般形式:類(lèi)型符 數(shù)組名[常量表達(dá)式1][常量表達(dá)式2];

例如:float a[3][4],定義一個(gè)3×4(3行4列)的數(shù)組a,常量表達(dá)式1表示數(shù)組的行數(shù),常量表達(dá)式2表示數(shù)組的列數(shù)。


二維數(shù)組可以看成一個(gè)特殊的一維數(shù)組,它的元素又是一個(gè)一維數(shù)組,例如,把a(bǔ)看為一維數(shù)組,它有3個(gè)元素:a[0],a[1],a[2],每個(gè)元素又是一個(gè)包含4個(gè)元素的一維數(shù)組,如a[0]包含:a[0][0],a[0][1],a[0][2],a[0][3]。a[0]、a[1]、a[2]可以看作三個(gè)一維數(shù)組名。二維數(shù)組元素的存放是按行存放的,先放第一行,再放第二行。在內(nèi)存中二維數(shù)組的各元素是連續(xù)存放的,不是二維的,是線性的。


二維數(shù)組初始化和引用數(shù)組元素

二維數(shù)組的初始化形式:

1、給二維數(shù)組部分元素賦初值:如

int a[3][4]={ {1,2},[5],{9}}; 表示給第一行的1、2列分別賦值1和2,給第二、三行的第1列,分別賦值5和9,其余元素值自動(dòng)為0;

2、把所有數(shù)據(jù)寫(xiě)在一個(gè)花括號(hào)中,按數(shù)組元素在內(nèi)存中的排列順序?qū)Ω髟刭x初值。

如int a[2][2]={1,2,3,4};

3、分行給二維數(shù)組賦初值。

例如:int a[2][2]={ {1,2},{3,4}};

4、如果給數(shù)組全部元素賦初值(即提供全部初始化數(shù)據(jù)),定義二維數(shù)組時(shí),第1維(行)的長(zhǎng)度可以不指定,但第2維(列)的長(zhǎng)度不能省略。

如:a[ ][2]={1,2,3,4}; 定義一個(gè)2×2的數(shù)組a

二維數(shù)組元素的引用:二維數(shù)組元素表示形式,數(shù)組名[下標(biāo)1][下標(biāo)2],下標(biāo)應(yīng)是整型表達(dá)式,如 a[0][1]=1;b=a[0][1]; 把數(shù)組a的第0行,第1列的元素賦值給b,b=1。



6.3 字符數(shù)組

字符數(shù)組的一般形式與一維數(shù)組和二維數(shù)組的一樣的,只是數(shù)據(jù)類(lèi)型不同,例如,char a[2]={'I','k'};char a[ ]={I','k'};,這兩個(gè)數(shù)組的長(zhǎng)度都是一樣的。char a[2][2]={ {'b','a'},{'c','d'}}; char a[][2]={ {'b','a'},{'d'}};,當(dāng)字符數(shù)組初值的個(gè)數(shù)小于數(shù)組長(zhǎng)度時(shí),只將這些字符賦給數(shù)組中前面的元素,其余的元素自動(dòng)定為空字符(即‘\0’)。

在C系統(tǒng)中,使用字符數(shù)組存儲(chǔ)字符串常量時(shí)會(huì)自動(dòng)加一個(gè)'\0'作為結(jié)束符,C語(yǔ)言規(guī)定了'\0'作為字符串結(jié)束標(biāo)志,'\0'代表ASCII碼為0的字符。例如char c[ ]={"C program"},字符串是存放在一維數(shù)組中的,在數(shù)組中它占10個(gè)字節(jié),最后一個(gè)字節(jié)'\0'是由系統(tǒng)自動(dòng)加上的。

注意:char c[ ]={"Cab"};不等于char c[3]={‘C’,'a','b'};前式長(zhǎng)度為4,后式長(zhǎng)度為3。


字符串的輸入輸出

字符串輸入
char c[10];
方式1   使用格式輸入函數(shù)scanf()
scanf("%s",c) ; //c是數(shù)組名,代表數(shù)組c的地址
方式2  使用gets()輸入字符串函數(shù)
gets(c);   //c是數(shù)組名,代表數(shù)組c的地址
字符串輸出
char c[10];
方式1   使用格式輸出函數(shù)printf()
printf("%s",c) ; //c是數(shù)組名,代表數(shù)組c的地址
方式2  使用puts()輸出字符串函數(shù)
puts(c);   //c是數(shù)組名,代表數(shù)組c的地址

字符串處理函數(shù),使用時(shí)需要加頭文件#include<string.h>

1、gets(字符數(shù)組) 輸入字符串函數(shù) gets(c); //c是數(shù)組名,代表數(shù)組c的地址
2、puts(字符數(shù)組) 輸出字符串函數(shù) puts(c); //c是數(shù)組名,代表數(shù)組c的地址

3、strcat函數(shù)——字符串鏈接函數(shù) strcat(字符數(shù)組1,字符數(shù)組2)

char str1[30]={"ABC"};
char str2[]={"DE"};
printf("%s",strcat(str1,str2));
輸出:ABCDE
(1)字符數(shù)組1必須足夠大,以便容納連接后的新字符串。如果字符數(shù)組1不夠大,會(huì)出現(xiàn)問(wèn)題。
(2)連接前兩個(gè)字符串的后面都有'\0',連接時(shí)將字符串1后面的'\0'取消,只在新字符串最后保留'\0'。
(3)連接的新串放在字符數(shù)組1中,函數(shù)最后返回的是字符數(shù)組1的地址。

4、strcpy和strncpy函數(shù)——字符串復(fù)制函數(shù) strcpy(字符數(shù)組1,字符串2)

char str1[10],str2[ ]={"china"};
strcpy(str1,str2);

執(zhí)行后str1的狀態(tài)如下:

c h i n a \0 \0 \0 \0 \0

說(shuō)明:

(1)、字符數(shù)組1的長(zhǎng)度不應(yīng)小于字符串2。

(2)、字符數(shù)組1必須寫(xiě)成數(shù)組形式,字符串2可以是字符數(shù)組名,也可以是字符串常量。

(3)、如果字符數(shù)組1沒(méi)被賦初值,它各字節(jié)中的內(nèi)容是未知的,復(fù)制時(shí)將str2中的字符串和其后的‘\0’一起復(fù)制到字符數(shù)組1中,取代其前6個(gè)字符,str1的最后4個(gè)字符并不一定為'\0',而是其原有的最后4個(gè)字節(jié)的內(nèi)容。

(4)、不能使用賦值語(yǔ)句直接把字符串常量或字符數(shù)組給一個(gè)字符數(shù)組。

(5)、可以使用strncpy函數(shù)將字符串2中的前n個(gè)字符復(fù)制到字符數(shù)組1中,但n不應(yīng)多于str1中原有的字符(不包括'\0')。


5、strcmp函數(shù)——字符串比較函數(shù) strcmp(字符串1,字符串2)

strcmp(str1,str2);
strcmp(str1,"Beijing");
strcmp("China","Korea");

說(shuō)明

(1)比較規(guī)則,兩個(gè)字符串自左至右逐個(gè)字符相比較(按ASCII碼值大小比較),直至出現(xiàn)不同字符或遇到'\0'為止。

(2)全部字符相同,則兩個(gè)字符串相等;

(3)若出現(xiàn)不同的字符,則以第1對(duì)不相同的字符的比較結(jié)果為準(zhǔn)。

(4)字符串1=字符串2,則函數(shù)值為0;字符串1>字符串2,則函數(shù)值為一個(gè)正整數(shù);字符串1<字符串2,則函數(shù)值為一個(gè)負(fù)整數(shù)。


6、 strlen函數(shù)——測(cè)字符串長(zhǎng)度的函數(shù) strlen(字符數(shù)組)

函數(shù)的值為字符串中的實(shí)際長(zhǎng)度(不包括'\0'在內(nèi)),例如

char str[10]={"china"};
printf("%d",strlen(str));
輸出:5

7、strlwr函數(shù)——轉(zhuǎn)換為小寫(xiě)函數(shù) strlwr(字符串)

8、strupr函數(shù)——轉(zhuǎn)換為大寫(xiě)函數(shù) strupr(字符串)



第7章 函數(shù)的使用

7.1 為什么使用函數(shù)

在編寫(xiě)一個(gè)程序時(shí),往往不是只實(shí)現(xiàn)一個(gè)或兩個(gè)功能,當(dāng)程序功能多且復(fù)雜時(shí),如果還是把功能的實(shí)現(xiàn)放在主函數(shù)里,會(huì)使得主程序變得復(fù)雜,使思路變得復(fù)雜,不利于查看和檢查,而且有時(shí)一個(gè)程序需要多人一起完成,如果把系統(tǒng)功能實(shí)現(xiàn)放在主程序中,這樣會(huì)不利于團(tuán)隊(duì)的合作。通過(guò)函數(shù)可以把程序的各功能分別在子函數(shù)中實(shí)現(xiàn),然后通過(guò)主函數(shù)調(diào)用各子函數(shù)就可以實(shí)現(xiàn)系統(tǒng)的功能,在團(tuán)隊(duì)合作中,每個(gè)人只需把他需要完成的功能寫(xiě)在子函數(shù)中,最后通過(guò)主函數(shù)調(diào)用就能實(shí)現(xiàn)系統(tǒng)功能。使用函數(shù)可以大大簡(jiǎn)化程序功能的實(shí)現(xiàn),有助理清思路,各功能可以互不干預(yù)。

7.2 函數(shù)的定義

定義無(wú)參函數(shù):

類(lèi)型名 函數(shù)名() 或 類(lèi)型名 函數(shù)名(void)

{ {

函數(shù)體 函數(shù)體

} }


定義有參函數(shù):

類(lèi)型名 函數(shù)名(形式參數(shù)列表)

{

函數(shù)體

}

int max(int x,int y)
{
int z;         //聲明部分
z=x>y?x:y;     //執(zhí)行語(yǔ)句部分
return(z);
}

函數(shù)體包括聲明部分語(yǔ)句部分。定義函數(shù)時(shí)的類(lèi)型名是指定函數(shù)返回值的類(lèi)型

定義空函數(shù):類(lèi)型名 函數(shù)名() { } 例如void fun() { }



7.3 函數(shù)的調(diào)用方式

如果函數(shù)在主函數(shù)后定義,在函數(shù)調(diào)用前,需要對(duì)函數(shù)進(jìn)行聲明,聲明方式是:類(lèi)型名 函數(shù)名();例如:int max(int x,int y);,根據(jù)函數(shù)在程序中的位置和形式,函數(shù)調(diào)用分三種形式:

(1)函數(shù)調(diào)用語(yǔ)句 例如:fun();

(2)函數(shù)表達(dá)式 例如:c=2*max(a,b);

(3)函數(shù)參數(shù) 例如:m=max(a,max(b,c));

函數(shù)調(diào)用時(shí),用到的實(shí)參和形參是直傳遞的,即形參的改變不會(huì)影響到實(shí)參。當(dāng)形參類(lèi)型是指針、數(shù)組、或變量的&引用時(shí),形參的改變才會(huì)影響到實(shí)參。


函數(shù)的嵌套調(diào)用:

函數(shù)的嵌套調(diào)用是指,在主函數(shù)中調(diào)用a函數(shù)(子函數(shù)),然后在a函數(shù)中調(diào)用b函數(shù)(別的子函數(shù)),函數(shù)的執(zhí)行流程是:在主程序中遇到a函數(shù)調(diào)用,則跳到a函數(shù)執(zhí)行,在a函數(shù)遇到b函數(shù)調(diào)用,下一步跳到b函數(shù)執(zhí)行,在b函數(shù)執(zhí)行完后,程序返回a函數(shù)繼續(xù)執(zhí)行,a函數(shù)執(zhí)行完后,程序返回主函數(shù)繼續(xù)執(zhí)行,直到整個(gè)主函數(shù)執(zhí)行完畢。


函數(shù)的遞歸調(diào)用:

在調(diào)用一個(gè)函數(shù)的過(guò)程中又出現(xiàn)直接或間接地調(diào)用本函數(shù)本身,稱(chēng)為函數(shù)的遞歸調(diào)用。

int age(int n)
 {
    int c;
    if(n==1) c=10;
    else  c=age(n-1)+2;
    return(c);
 }


7.4 數(shù)組作為函數(shù)參數(shù)

函數(shù)的實(shí)參可以是常量、變量或表達(dá)式,數(shù)組元素當(dāng)實(shí)參與變量相當(dāng),向形參傳遞數(shù)組元素的值,從實(shí)參傳到形參,單向傳遞(值傳遞)。此外,數(shù)組名也可以當(dāng)實(shí)參和形參,傳遞的是數(shù)組第一個(gè)元素的地址(首地址),即實(shí)參和形參數(shù)組的地址相同,它們操作同一片存儲(chǔ)空間,所以當(dāng)形參改變時(shí),實(shí)參也會(huì)跟著改變。



7.5 內(nèi)部函數(shù)和外部函數(shù)

7.5.1 局部變量

局部變量包括:在函數(shù)內(nèi)部定義的變量(包括主函數(shù))、在復(fù)合語(yǔ)句內(nèi)定義的變量、形參也是局部變量。它的作用域是定義函數(shù)內(nèi)部、定義復(fù)合語(yǔ)句內(nèi)部,例如在fun函數(shù)內(nèi)定義的變量,它的作用域是fun函數(shù)。在for循環(huán)里定義的變量,它的作用域是for循環(huán)里面。

7.5.2 全局變量

在函數(shù)之外定義的變量稱(chēng)為外部變量,外部變量是全局變量,它的作用域是從定義變量的位置開(kāi)始到本源文件結(jié)束,全局變量可以為本文件中其他函數(shù)所共用。

當(dāng)定義的全局變量和局部變量同名時(shí),在局部變量的作用域內(nèi),同名的全局變量會(huì)被同名的局部變量所屏蔽。例如在全局變量a=10,局部變量a=5,在局部變量a的作用域內(nèi),b=a,則b的值為5。


變量的存儲(chǔ)方式:動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式

靜態(tài)存儲(chǔ)方式:指在程序運(yùn)行期間由系統(tǒng)分配固定的存儲(chǔ)空間的方式。

動(dòng)態(tài)存儲(chǔ)方式:指在程序運(yùn)行期間根據(jù)需要進(jìn)行動(dòng)態(tài)的分配存儲(chǔ)空間的方式。

供用戶(hù)使用的存儲(chǔ)空間分3部分:(1)程序區(qū);(2)靜態(tài)存儲(chǔ)區(qū);(3)動(dòng)態(tài)存儲(chǔ)區(qū)。數(shù)據(jù)分別存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū)和動(dòng)態(tài)存儲(chǔ)區(qū)中,全局變量全部存放在靜態(tài)存儲(chǔ)區(qū),在程序開(kāi)始執(zhí)行時(shí)給全局變量分配存儲(chǔ)區(qū),程序執(zhí)行完畢就釋放。在程序執(zhí)行過(guò)程中它們占據(jù)固定的存儲(chǔ)單元,而不是動(dòng)態(tài)地進(jìn)行分配和釋放。

動(dòng)態(tài)存儲(chǔ)區(qū)中存放以下數(shù)據(jù):

(1)函數(shù)形式參數(shù)。在調(diào)用函數(shù)時(shí)給形參分配存儲(chǔ)空間。

(2)函數(shù)中定義的沒(méi)有用關(guān)鍵字static聲明的變量,即自動(dòng)變量(auto變量)。

(3)函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保護(hù)和返回地址。

以上這些數(shù)據(jù),在函數(shù)調(diào)用開(kāi)始時(shí)分配動(dòng)態(tài)存儲(chǔ)空間,函數(shù)結(jié)束時(shí)釋放這些空間。在程序執(zhí)行過(guò)程中,這種分配和釋放是動(dòng)態(tài)的。


在c語(yǔ)言中,每個(gè)變量和函數(shù)都有兩個(gè)屬性:數(shù)據(jù)類(lèi)型和數(shù)據(jù)的存儲(chǔ)類(lèi)別。在定義和聲明變量和函數(shù)時(shí),一般應(yīng)同時(shí)指定其數(shù)據(jù)類(lèi)型和存儲(chǔ)類(lèi)別,也可以采用默認(rèn)方式指定(系統(tǒng)自動(dòng)指定為某一種存儲(chǔ)類(lèi)別)。數(shù)據(jù)類(lèi)別指的是:數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式(靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ))。

C的存儲(chǔ)類(lèi)別包括4種,自動(dòng)的(auto),靜態(tài)的(statis)、寄存器的(register)、外部的(extern)。


1、自動(dòng)變量(auto變量)

函數(shù)中的局部變量,如果不專(zhuān)門(mén)聲明為static(靜態(tài))存儲(chǔ)類(lèi)別,都是動(dòng)態(tài)地分配存儲(chǔ)空間的,數(shù)據(jù)存放在動(dòng)態(tài)存儲(chǔ)區(qū)中。函數(shù)中的形參和函數(shù)中定義的局部變量(包括復(fù)合語(yǔ)句中定義的局部變量)都是自動(dòng)變量(auto變量)。

int fun(int a)
{
int b=3;        //省略auto時(shí),系統(tǒng)隱含指定為“自動(dòng)存儲(chǔ)類(lèi)別(auto)”,b為自動(dòng)變量
auto int c=2;       //定義c為自動(dòng)變量
.
.
}

當(dāng)定義的自動(dòng)變量不賦初值時(shí),它的值是未知的。


2、靜態(tài)局部變量(static)

靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)類(lèi)別,存放在靜態(tài)存儲(chǔ)區(qū)內(nèi)分配的單元。對(duì)靜態(tài)局部變量賦初值是在編譯時(shí)完成的(即只賦初值一次),在以后函數(shù)調(diào)用時(shí),不再重新賦初值,而是保留上一次調(diào)用函數(shù)結(jié)束時(shí)的值。例如

int a()
{
static int i=1;
printf{"%d",i};
i=i+1;
}

第一次調(diào)用a函數(shù)時(shí),i的初值為1,輸出i為1;第二次調(diào)用a函數(shù)輸出的i為2,保留上一次函數(shù)結(jié)束時(shí)的值。

當(dāng)定義的靜態(tài)局部變量不賦初值時(shí),編譯時(shí)自動(dòng)賦初值為0(對(duì)數(shù)值型變量)或'\0'(對(duì)字符變量)


3、寄存器變量(register變量)

寄存器變量存放在CPU中的寄存器中,它不是存放在內(nèi)存中的。由于寄存器變量存放在cpu中的寄存器中,所以數(shù)據(jù)的存取速度遠(yuǎn)高于存放在內(nèi)存中的數(shù)據(jù)的存取。使用寄存器變量可以提高執(zhí)行效率。定義寄存器變量的一般形式:register int f;


4、全局變量(外部變量)

全局變量都是存放在靜態(tài)存儲(chǔ)區(qū)中的。它的作用域一般是從定義全局變量處開(kāi)始,到本程序文件的末尾。當(dāng)定義外部變量的位置,不是位于文件開(kāi)頭時(shí),在外部變量定義處之前的程序是不能引用外部變量的,如果要引用外部變量,需要在引用之前使用關(guān)鍵字extern對(duì)該變量進(jìn)行“外部變量聲明”

把外部變量的作用域擴(kuò)展到其他文件的方式,可以在其他文件中使用extern對(duì)外部變量進(jìn)行聲明。例如

文件file1.c
#include<stdio.h>
int a;    //定義外部變量
int b;    //定義外部變量
int main()
{
    .
    .
    .
}
文件file2.c
extern int a;    //把文件file1.c中的外部變量a的作用域擴(kuò)展到file2.c中
extern b;    //把文件file1.c中的外部變量b的作用域擴(kuò)展到file2.c中
int fun()
{
    .
    .
    .
}

把外部變量的作用域限定在本文件中,只能被本文件引用,而不能被其他文件引用,可以通過(guò),在定義外部變量時(shí)加一個(gè)statis聲明來(lái)實(shí)現(xiàn)。通過(guò)statis定義的靜態(tài)外部變量只能作用于本文件,當(dāng)其他文件也定義了相同名字的外部變量時(shí),它們之間的互不干預(yù)的。例如

文件file1.c
#include<stdio.h>
static int a;    //定義靜態(tài)外部變量
int main()
{
    .
    .
    .
}

5、小結(jié)

(1)從作用域角度分,有局部變量和全局變量。它們的存儲(chǔ)類(lèi)別如下:

局部變量 自動(dòng)變量,即動(dòng)態(tài)局部變量(離開(kāi)函數(shù),值就消失)
靜態(tài)局部變量(離開(kāi)函數(shù),值仍然保留)
寄存器變量(離開(kāi)函數(shù),值就消失)
形式參數(shù)可以定義為自動(dòng)變量或寄存器變量
全局變量 靜態(tài)外部變量(只限本文件引用)
外部變量(即非靜態(tài)的外部變量,允許其他文件引用)

(2)從變量生存時(shí)間(生存期)來(lái)區(qū)分,有動(dòng)態(tài)存儲(chǔ)和靜態(tài)存儲(chǔ)兩種類(lèi)型。

動(dòng)態(tài)存儲(chǔ) 自動(dòng)變量(本函數(shù)內(nèi)有效)
寄存器變量(本函數(shù)內(nèi)有效)
形式參數(shù)(本函數(shù)內(nèi)有效)
靜態(tài)存儲(chǔ) 靜態(tài)局部變量(函數(shù)內(nèi)有效)
靜態(tài)外部變量(本文件內(nèi)有效)
外部變量(用extern聲明后,其他文件可引用)

(3)從變量值存放的位置來(lái)區(qū)分。

內(nèi)存中靜態(tài)存儲(chǔ)區(qū) 靜態(tài)局部變量
靜態(tài)外部變量(函數(shù)外部靜態(tài)變量)
外部變量(可為其他文件引用)
內(nèi)存中動(dòng)態(tài)存儲(chǔ)區(qū) 自動(dòng)變量和形式參數(shù)
CPU中寄存器 寄存器變量


內(nèi)部函數(shù)

如果一個(gè)函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱(chēng)為內(nèi)部函數(shù)(又稱(chēng)靜態(tài)函數(shù),因?yàn)樗褂胹tatic聲明的),它的作用域只局限于所在文件。這樣,在不同文件中即使有同名的內(nèi)部函數(shù),也互不干擾。一般形式:static 類(lèi)型名 函數(shù)名(形參列表),例如static int a(int a){...}



外部函數(shù)

如果在定義函數(shù)時(shí),在函數(shù)首部的最左端加關(guān)鍵字extern,則此函數(shù)是外部函數(shù),可供其他文件調(diào)用。函數(shù)首部可以為:extern int fun(int a,int b)。C語(yǔ)言規(guī)定,如果在定義函數(shù)時(shí)省略extern,則默認(rèn)為外部函數(shù)。



第8章 指針

8.1 什么是指針

指針指的是地址,一個(gè)變量的地址稱(chēng)為該變量的指針。一個(gè)變量專(zhuān)門(mén)用來(lái)存放另一個(gè)變量的地址,稱(chēng)為指針變量。指針變量的值是地址。

8.2 指針變量

存放地址的變量是指針變量,它用來(lái)指向另一個(gè)對(duì)象(如變量、數(shù)組、函數(shù)等)。定義指針變量的一般形式:類(lèi)型名 *指針變量名;如int *a;char *b;定義了指向整型變量的指針變量a和定義了指向字符變量的指針變量b;

指針變量的初始化,可以在定義的同時(shí)初始化,也可以在定義后初始化,例如:

int a=0;
int *b=a;    //定義指針變量時(shí)初始化
int *c;
c=&a;        //定義指針變量后初始化,意思是把a(bǔ)的地址賦值給指針變量c,指針變量c指向變量a
錯(cuò)誤賦值方式:int *d=&a;  //錯(cuò)誤,*d不是指針變量,d才是指針變量,
所以應(yīng)該改為int *d=a;

一個(gè)變量的指針的含義包括兩方面:一是以存儲(chǔ)單元編號(hào)表示的地址,一是它指向的存儲(chǔ)單元的數(shù)據(jù)類(lèi)型。



8.3 指針的使用方式

8.3.1指針變量的使用

當(dāng)指針變量指向一個(gè)變量時(shí),那么指針變量就存儲(chǔ)著所指向變量的地址,通過(guò)對(duì)指針變量的使用可以實(shí)現(xiàn)它所指向變量的功能。例如

int a=12;
int *put=a;    //定義指向變量a的指針變量put
printf("a=%d ",a);
printf("a=%d",*put);    輸出指針變量put所指向的變量的值
結(jié)果:a=12 a=12

指針變量的使用例子:

輸入兩個(gè)數(shù),按先大后小輸出
#include<stdio.h>
int main()
{
  int *p1,*p2,*p,a,b;
  printf("please enter two integer numbers:");
  scanf("%d,%d",&a,&b);
  p1=&a;
  p2=&b;
  if(a<b)
    {p=p1;p1=p2;p2=p;}
  printf("a=%d,b=%d\n",a,b);
  printf("max=%d,min=%d\n",*p1,*p2);
  return 0;
}
結(jié)果:please enter two integer numbers:5,9
a=9,b=5
max=9,min=5


8.3.2 指針變量作為函數(shù)參數(shù)

指針變量作為函數(shù)參數(shù),例如:

#include<stdio.h>
int mian()
{
int fun(int *a);    //聲明函數(shù)fun
int a=8;
int *b=a;
fun(&a);
fun(b);
return 0;
}
int fun(int *a);
{
printf("%d ",*a);
}
運(yùn)行結(jié)果:8 8

當(dāng)指針變量作為形參時(shí),因?yàn)樾螀⒑蛯?shí)參所操作的存儲(chǔ)單元是同一個(gè)的(它們指向同一個(gè)存儲(chǔ)單元),所以形參值的修改也會(huì)導(dǎo)致實(shí)參值的修改。


8.3.3 通過(guò)指針引用數(shù)組

所謂數(shù)組元素的指針就是數(shù)組元素的地址,可以用一個(gè)指針變量指向一個(gè)數(shù)組元素,例如:

int a[5]={1,2,3,4,5}; int *p; p=&a[0]; 使指針變量p指向a數(shù)組的第0號(hào)元素。

在引用數(shù)組元素時(shí)指針的運(yùn)算。因?yàn)橹羔樀闹凳菙?shù)組元素的地址,當(dāng)指針p指向數(shù)組中的一個(gè)元素時(shí),則p+1指向同一數(shù)組中下一個(gè)元素,p-1指向同一數(shù)組中的上一個(gè)元素。注意:執(zhí)行p+1時(shí),并不是將p的值(地址)簡(jiǎn)單的加1,而是加上一個(gè)數(shù)組元素所占用的字節(jié)數(shù)。例如,數(shù)組元素是float型,每個(gè)元素占4個(gè)字節(jié),則p+1意味著是p的值(地址)加4個(gè)字節(jié)。


通過(guò)指針引用數(shù)組元素

指針?lè)ǎ喝?*(a+i)或*(p+i),其中a是數(shù)組名,p是指向數(shù)組元素的指針變量,其初值p=a。

通過(guò)數(shù)組名計(jì)算數(shù)組元素地址,找出元素的值。例如:

#include<stdio.h>
int main()
{
  int a[10];
  int i;
  printf("please enter 10 integer numbers:");
  for(i=0;i<10;i++)
      scanf("%d",&a[i]);
  for(i=0;i<10;i++)
  printf("%d ",*(a+i));    //通過(guò)數(shù)組名和元素序號(hào)計(jì)算元素地址,再找到該元素
  printf("\n");
  return 0;
}
第10行中(a+i)是a數(shù)組中序號(hào)為i的元素的地址,*(a+i)是該元素的值。

用指針變量指向數(shù)組元素

#include<stdio.h>
int main()
{
  int a[10];
  int i,*p;
  printf("please enter 10 integer numbers:");
  for(i=0;i<10;i++)
      scanf("%d",&a[i]);
  for(p=a;p<(a+10);p++)
      printf("%d ",*p);    //通過(guò)數(shù)組名和元素序號(hào)計(jì)算元素地址,再找到該元素
  printf("\n");
  return 0;
}

注意:*p++,由于++和*同優(yōu)先級(jí),結(jié)合方向?yàn)樽杂蚁蜃?/SPAN>,因此它等價(jià)于*(p++),先引用p的值,實(shí)現(xiàn)*p的運(yùn)算,然后再使p自增1(p+1).


數(shù)組名作為函數(shù)參數(shù):

int main()
{
void fun(int arr[],int n);    //聲明fun函數(shù)
int array[10];
    .
    .
    .
fun(array,10);
return 0;
}
void fun(int arr[],int n)
{
    .
    .
    .
}

變量名和數(shù)組名作為函數(shù)參數(shù)比較:

實(shí)參類(lèi)型 變量名 數(shù)組名
要求形參的類(lèi)型 變量名 數(shù)組名或指針變量
傳遞的信息 變量值 實(shí)參數(shù)組首元素的地址
通過(guò)函數(shù)調(diào)用能否改變實(shí)參的值 不能改變實(shí)參變量的值 能改變實(shí)參數(shù)組的值

通過(guò)指針引用多維數(shù)組,以int a[3][4]為例,a代表首行的首地址,a+1代表序號(hào)為1的行的首地址,a+1指向a[1](代表a數(shù)組的元素,但它又是一維數(shù)組,或者說(shuō)a+1的值是a[1]的首地址。a[0],a[1],a[2]代表一維數(shù)組名,因此a[0]代表一維數(shù)組a[0]的第0列的地址(即&a[0][0])。

a[0]+3代表a[0][3]的地址(&a[0][3]),“a[0]+3中的a[0]代表數(shù)組名(地址)”。

a[0](代表一維數(shù)組a的元素,但它又是一維數(shù)組)和*(a+0)等價(jià),a[ i ]和*(a+i)等價(jià)。因此a[0]+1和*(a+1)+1等價(jià),都是&a[0][1]。進(jìn)一步分析,a[0][1]的值,使用地址法為:*(*(a+0)+1)或*(*a+1)和*(a[0]+1)。

二維數(shù)組名(如a)指向行的。在指向行的指針前加一個(gè)*,就轉(zhuǎn)換為指向列的指針,例如a+1(行指針),第一行的指針;*(a+1)為列指針,第一行第0列的指針。反之在列的指針前加&,就成為指向行的指針,例如&a[0],由于a[0]和*(a+0)等價(jià),因此&a[0]和&*a等價(jià),它是指向第0行的指針。


指向多維數(shù)組元素的指針變量

#include<stdio.h>
int main()
{
int a[3][4]={....};
int *p;
for(p=a[0];p<a[0]+12;p++)    //a[0]是a[0][0]的地址,指針p指向a[0][0]元素
    printf("%4d",*p);    //輸出p指的數(shù)組元素的指
return 0;
}


定義指向“由n個(gè)元素組成的一維數(shù)組”的指針變量

#include<stdio.h>
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4],j,i;
p=a;
printf("please enter row and colum :");
scanf("%d,%d",&i,&j);
printf("[%d,%d]=%d\n",i,j,*(*(p+i)+j));  
return 0;
}
結(jié)果:please enter row and colum:1,2
a[1,2]=13


用指向數(shù)組的指針作函數(shù)參數(shù)

#include<stdio.h>
int main()
{
void a(int *a);
void b(int (*b)[4]);
int c[3][4]={...};
a(*c);    //*c是數(shù)組c的第0行第0列的地址
b(c);     //c是數(shù)組c的第0行的地址
return 0
}

8.3.4 通過(guò)指針引用字符串

例子:

#include<stdio.h>
int main()
{
char *string="I love china!";
printf("%s",string);
return 0;
}
輸出:I love china!

注意:char *string="I love china!"; 等價(jià)于char *string; string="I love china!",把字符串第一個(gè)元素的地址賦值給字符指針變量string。

字符指針作函數(shù)參數(shù),例如: void fun(char *p),調(diào)用時(shí),實(shí)參可以是字符指針變量、字符數(shù)組名。

void fun(char a[ ]),調(diào)用時(shí),實(shí)參可以是字符指針變量、字符數(shù)組名。

用字符指針作函數(shù)參數(shù)時(shí),實(shí)參和形參的類(lèi)型對(duì)應(yīng)關(guān)系如下

實(shí)參 形參 實(shí)參 形參
字符數(shù)組名 字符數(shù)組名 字符指針變量 字符指針變量
字符數(shù)組名 字符指針變量 字符指針變量 字符數(shù)組名

用字符指針變量指向一個(gè)格式字符串,可以用它代替printf函數(shù)中的格式字符串,例如:

char *format;
format="a=%d,b=%f\n";
printf(format,a,b);
它相當(dāng)于 printf("a=%d,b=%f\n",a,b);
因此只要改變指針變量format所指的字符串,就可以改變輸入輸出的格式。
這種printf函數(shù)稱(chēng)為“可變格式輸出函數(shù)”

8.3.5 指向函數(shù)的指針(函數(shù)指針變量)

函數(shù)代碼也有存儲(chǔ)空間,這段存儲(chǔ)空間的起始地址稱(chēng)為這個(gè)函數(shù)的指針。定義一個(gè)指針變量指向函數(shù),存放某一函數(shù)的起始地址,因?yàn)榇酥羔樧兞恐赶蛟摵瘮?shù)。這就是指向函數(shù)的指針(函數(shù)指針變量)。函數(shù)指針變量定義方式:類(lèi)型名 (*指針變量名)(函數(shù)參數(shù)列表);例如:int (*p)(int ,int);,定義一個(gè)指向函數(shù)的指針變量p,它可以指向函數(shù)的類(lèi)型為整型且有兩個(gè)整型參數(shù)的函數(shù)。

可以通過(guò)指向函數(shù)的指針(函數(shù)指針變量)調(diào)用函數(shù),例如

int max(int a,int b)
{...}
int (*p)(int ,int);
p=max;
這時(shí)調(diào)用函數(shù):max(1,2);等價(jià)于(*p)(1,2);

指向函數(shù)的指針變量可以作為函數(shù)參數(shù)。例如

void fun(int (*a)(int))  {...}
int flie1(int a) {...}
int (*b)(int);
b=flie1;    //指向flie1函數(shù)
fun(b);    //指向函數(shù)的指針變量作實(shí)參
fun(flie1);        //函數(shù)名作實(shí)參,函數(shù)名代表該函數(shù)存儲(chǔ)空間的起始地址

8.3.6返回指針值的函數(shù)

定義返回指針值的函數(shù)的一般形式:類(lèi)型名 *函數(shù)名(參數(shù)列表),

例如 int *fun(int n){...},

int *fun(int n)
{
    int *p;
    n=n+1;
    p=n;
    return(p);    //返回指針變量p所指的地址
}

8.3.7 指針數(shù)組

定義一維指針數(shù)組的一般形式:類(lèi)型名 *數(shù)組名[數(shù)組長(zhǎng)度],例如int *p[5],char *name[ ]={"abc","bcd"};

指向指針數(shù)據(jù)的指針變量的定義為 :類(lèi)型名 **指針名,如char **p,p=name,其中name是指針數(shù)組的數(shù)組名,*p代表指針數(shù)組中存儲(chǔ)的指針,**p代表指針數(shù)組中存儲(chǔ)的指針?biāo)傅膯卧闹怠?/P>

指針數(shù)組作main函數(shù)的形參:int main(int argc,char *argv[ ]),其中argc,argv,它們是程序的命令行參數(shù)(這是在系統(tǒng)操作命令下完成),argc是參數(shù)的個(gè)數(shù)。命令行的一般形式:命令名 參數(shù)1 參數(shù)2 ....參數(shù)n,其中命令名是可執(zhí)行文件名,如,可執(zhí)行文件flie1.exe,現(xiàn)想將兩個(gè)字符串“china”,“beijing”作為傳送給mian函數(shù)的參數(shù),命令行可寫(xiě)為 flie1 china beijing,這時(shí)argc的值為3,參數(shù)的個(gè)數(shù)為3,argv[0]指向flie1字符串。


8.3.8 動(dòng)態(tài)內(nèi)存分配與指向它的指針變量

內(nèi)存中的動(dòng)態(tài)存儲(chǔ)區(qū)也稱(chēng)之為"棧區(qū)"。在C語(yǔ)言中還允許建立內(nèi)存動(dòng)態(tài)分配區(qū)域,以存放一些臨時(shí)用的數(shù)據(jù),這些數(shù)據(jù)不必在程序的聲明部分定義,可以隨時(shí)開(kāi)辟和關(guān)閉,這些數(shù)據(jù)是臨時(shí)存放在一個(gè)特別的自由存儲(chǔ)區(qū),稱(chēng)之為“堆(heap)區(qū)”

對(duì)內(nèi)存的動(dòng)態(tài)分配是通過(guò)系統(tǒng)提供的庫(kù)函數(shù)來(lái)實(shí)現(xiàn)的,主要有malloc,calloc,free,realloc這4個(gè)函數(shù),在使用這些函數(shù)時(shí),需要添加頭文件stdlib.h。

malloc函數(shù),其函數(shù)原型為:void *malloc(unsigned int size),其作用是在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配一個(gè)長(zhǎng)度為size的連續(xù)空間,形參size是無(wú)符號(hào)整型,不允許有負(fù)數(shù),該函數(shù)的返回值是所分配的第一個(gè)字節(jié)的地址。注意,指針的基類(lèi)型為void,即不指向任何類(lèi)型的數(shù)據(jù),只提供地址。如果該函數(shù)未能成功執(zhí)行(例如內(nèi)存空間不足),則返回空指針(NULL)。

calloc函數(shù),其函數(shù)原型為:void *calloc(unsigned n,unsigned size),其作用是在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配n個(gè)長(zhǎng)度為size的連續(xù)空間,這空間一般比較大,足可以保存一個(gè)數(shù)組?梢允褂胏alloc為一維數(shù)組開(kāi)辟動(dòng)態(tài)存儲(chǔ)空間,n代表數(shù)組元素個(gè)數(shù),每個(gè)元素的長(zhǎng)度為size。這是動(dòng)態(tài)數(shù)組,該函數(shù)返回的是所分配域的起始位置的指針,如果分配不成功,則返回NULL。

free函數(shù)(無(wú)返回值),其函數(shù)原型為:void free(void *p),其作用是釋放指針變量p所指向的動(dòng)態(tài)空間,使這部分空間能重新被其他變量使用。p應(yīng)是最近一次調(diào)用calloc和malloc函數(shù)時(shí)得到的函數(shù)返回值。例如free(p)。

realloc函數(shù),其函數(shù)原型為:void *realloc(void *p,unsigned int size);其作用是改變通過(guò)malloc和calloc函數(shù)獲得的動(dòng)態(tài)空間的大小,通過(guò)realloc函數(shù)重新分配。用法說(shuō)明:用realloc函數(shù)將p所指向的動(dòng)態(tài)空間的大小改變?yōu)閟ize,p的值不變。如果重新分配不成功,返回NULL。例如:realloc(p,50);

void 指針類(lèi)型,定義一個(gè)void類(lèi)型的指針變量,它不指向任何類(lèi)型的數(shù)據(jù),它是空類(lèi)型或不指向確定類(lèi)型,例如void *p; p=&a, printf("%d",*p),錯(cuò)誤,因?yàn)閜是無(wú)指向,不能指向a。

指針變量可以有空值,即不指向任何變量,例如p=NULL。

#include<stdio.h>
#include<stdlib.h>
int main()
{
void check(int *p);
int *p1,i;
p1=(int *)malloc(5*sizeof(int));
for(i=0;i<5;i++)
scanf("%d",p1+i);
check(p1);
free(p1);
return 0
}
void check(int *p)
{
int i;
printf("They are fail:");
for(i=0;i<5;i++)
if(p[i]<60) printf("%d",p[i]);
printf("\n");
}
結(jié)果:
67 98 59 78 57
They are fail:59 57

有關(guān)指針變量的歸納:

變量定義 類(lèi)型表示 含義
int i; int 定義整型變量
int *p; int * 定義p為指向整型數(shù)據(jù)的指針變量
int a[5 ]; int [5] 定義整型數(shù)組a,它有5個(gè)元素
int *p[4]; int *[4] 定義指針數(shù)組p,它由4個(gè)指向整型數(shù)據(jù)的指針元素組成
int (*p)[4]; int (*)[4] p為指向包含4個(gè)元素的的一維數(shù)組的指針變量
int f(); int () f為返回整型函數(shù)值的函數(shù)
int *p(); int *() p為返回一個(gè)指針的函數(shù),該指針指向整型數(shù)據(jù)
int (*p)(); int (*) p為指向函數(shù)的的指針變量,該函數(shù)返回一個(gè)整型值
int **p; int ** p是一個(gè)指針變量,它指向一個(gè)指向整型數(shù)據(jù)的指針變量
void *p void * p是一個(gè)指針變量,基類(lèi)型為void(空類(lèi)型),不指向具體的對(duì)象


第9章 自定義數(shù)據(jù)類(lèi)型

9.1 結(jié)構(gòu)體類(lèi)型

結(jié)構(gòu)體類(lèi)型,是由用戶(hù)根據(jù)自己的需要建立的數(shù)據(jù)類(lèi)型。聲明一個(gè)結(jié)構(gòu)體類(lèi)型的一般形式:struct 結(jié)構(gòu)體名 {成員列表};例如:

struct student
{
  int num;
  char name[20];
  char sex;
  int ahe;
  float score;
  char addr[30];
  struct Date birthday;    //該成員的數(shù)據(jù)類(lèi)型為Date結(jié)構(gòu)類(lèi)型
};

花括號(hào)內(nèi)是該結(jié)構(gòu)體的成員,成員列表也稱(chēng)為“域表”,每個(gè)成員是結(jié)構(gòu)體中的一個(gè)域。成員名命名規(guī)則與變量名相同。它的成員可以是另一個(gè)結(jié)構(gòu)體類(lèi)型。


定義結(jié)構(gòu)體類(lèi)型變量

在建立結(jié)構(gòu)體類(lèi)型時(shí),它只相當(dāng)于一個(gè)模型,并沒(méi)有定義變量,其中并無(wú)具體數(shù)據(jù),系統(tǒng)不會(huì)對(duì)其分配存儲(chǔ)單元。定義結(jié)構(gòu)體類(lèi)型變量的三種方式:

1、先聲明結(jié)構(gòu)體類(lèi)型,再定義該類(lèi)型的變量 例如:struct student student1;

2、在聲明類(lèi)型的同時(shí)定義變量:例如

struct student
{
    成員列表
}student1,student2;    //定義結(jié)構(gòu)體變量student1和student2

3、不指定類(lèi)型名而直接定義結(jié)構(gòu)體類(lèi)型變量

其一般形式為
struct
{
成員列表
}變量名列表;

初始化結(jié)構(gòu)體變量

#include<stdi.h>
int main()
{
  struct student
  {
    long int num;
    char name[20];
    char sex;
  }a={10101,"xiaoming",'m'};    //定義結(jié)構(gòu)體變量a并初始化
  return 0;
}
struct student a={10101,"xiaoming",'m'};    //定義結(jié)構(gòu)體變量a并初始化
struct student a={.name="xiaoming"};    //定義結(jié)構(gòu)體變量a,并對(duì)其成員a初始化,其他未被
指定初始化的數(shù)值型成員被系統(tǒng)初始化為0,字符型成員被系統(tǒng)初始化為'\0',指針型成員被系統(tǒng)初始化
為NULL。

引用結(jié)構(gòu)體變量的成員:結(jié)構(gòu)體變量名.成員名 例如studen1.num=10101;

如果成員本身又是結(jié)構(gòu)體類(lèi)型,則要使用若干個(gè)成員運(yùn)算符,一級(jí)一級(jí)地找到最低的一級(jí)的成員。例如,student1.birthday.month(結(jié)構(gòu)體變量student1中的成員birthday中的成員month)

同類(lèi)的結(jié)構(gòu)體變量可以互相賦值,如student1=student2;

可以引用結(jié)構(gòu)體變量成員的地址,也可以引用結(jié)構(gòu)體變量的地址。例如

scanf("%d",&student1.num); printf("%o",&student1); (輸出結(jié)構(gòu)體變量student1的首地址)


結(jié)構(gòu)體數(shù)組

定義結(jié)構(gòu)體數(shù)組和定義一般數(shù)組的方式類(lèi)似,它的一般形式為:結(jié)構(gòu)體類(lèi)型 數(shù)組名[數(shù)組長(zhǎng)度],或struct 結(jié)構(gòu)體名 { 成員列表 } 數(shù)組名[數(shù)組長(zhǎng)度];,它的每個(gè)成員都是結(jié)構(gòu)體類(lèi)型。

對(duì)結(jié)構(gòu)體數(shù)組初始化的形式是在定義數(shù)組后面加上:={ 初值列表 };

例如:struct person leader[3]={ {“Li”,0},{"Zhang",0},{"Sun",0}};


結(jié)構(gòu)體指針

指向結(jié)構(gòu)體變量的指針,稱(chēng)為結(jié)構(gòu)體指針,一個(gè)結(jié)構(gòu)體變量的起始地址就是該結(jié)構(gòu)體變量的指針。指向結(jié)構(gòu)體變量的指針變量既可指向結(jié)構(gòu)體變量,也可指向結(jié)構(gòu)體數(shù)組中的元素。

如果p指向一個(gè)結(jié)構(gòu)體變量stu,以下3種用法等價(jià):

(1) stu.成員名(如stu.num)

(2) (*p).成員名(如(*p).num) //*p表示p指向的結(jié)構(gòu)體變量

(3) p->成員名(如p->num)

(++p)->num //先使p自加1,然后得到p指向的數(shù)組元素中的num成員的值。


結(jié)構(gòu)體變量和結(jié)構(gòu)體變量的指針作函數(shù)參數(shù)

(1) 結(jié)構(gòu)體變量的成員作實(shí)參,用法和普通的變量作實(shí)參一樣。(值傳遞)

(2)結(jié)構(gòu)體變量作實(shí)參。(值傳遞)

(3)用指向結(jié)構(gòu)體變量(或數(shù)組元素)的指針作實(shí)參,將結(jié)構(gòu)體變量的地址傳給形參。


用指針處理鏈表

鏈表是一種常見(jiàn)的重要的數(shù)據(jù)結(jié)構(gòu)。它是動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配的一種結(jié)構(gòu)。鏈表可以根據(jù)需要開(kāi)辟內(nèi)存單元。鏈表有一個(gè)“頭指針”變量head,它存放一個(gè)地址,該地址指向一個(gè)元素。鏈表中每一個(gè)元素稱(chēng)為“結(jié)點(diǎn)”,每個(gè)結(jié)點(diǎn)都應(yīng)包含兩個(gè)部分:(1)用戶(hù)需要用的實(shí)際數(shù)據(jù);(2)下一個(gè)結(jié)點(diǎn)的地址。

在這里插入圖片描述


鏈表中各元素在內(nèi)存中的地址可以不連續(xù),要找某一元素,可以通過(guò)它的上一個(gè)元素中的地址尋找。如果不提供頭指針(head),則整個(gè)鏈表都無(wú)法訪問(wèn)。通過(guò)結(jié)構(gòu)體變量建立鏈表最合適。例如:

struct student

{int num;

float score;

struct student *next; //next是指針變量,指向結(jié)構(gòu)體變量,鏈表中用來(lái)指向下一個(gè)結(jié)點(diǎn)

};


建立簡(jiǎn)單的靜態(tài)鏈表:

#include<stdio.h>
struct student
{
int num;
struct student *next;
};
int main()
{struct student a,b,c,*head,*p;
a.num=1; b.num=2; c.num=3;
head=&a;
a.next=&b; b.next=&c; c.next=NULL;
p=head;
do
{
printf("%d\n",p->num)
p=p->next;
}while(p!=NULL)
}
結(jié)果:
1
2
3

所有結(jié)點(diǎn)都是在程序中定義的,不是臨時(shí)開(kāi)辟的,也不能用完后釋放,這種鏈表稱(chēng)為“靜態(tài)鏈表”。


建立動(dòng)態(tài)鏈表

動(dòng)態(tài)鏈表是指在程序執(zhí)行過(guò)程中從無(wú)到有地建立起一個(gè)鏈表,即一個(gè)一個(gè)地開(kāi)辟結(jié)點(diǎn)和輸入各結(jié)點(diǎn)數(shù)據(jù),并建立起前后相鏈的關(guān)系。

#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct student)     //設(shè)置LEN的長(zhǎng)度
struct student
{
long num;
float score;
struct student *next;
};
int n;
struct student *creat(void)    //定義函數(shù),此函數(shù)返回一個(gè)指向鏈表頭的指針
{
struct student *head,p1,p2;
n=0;
p1=p2=(struct student *)malloc(LEN);    //開(kāi)辟動(dòng)態(tài)存儲(chǔ)區(qū),把起始地址賦給p1
scanf("%ld,%f",&p1->num,&p1->score);   
head=NULL;
while(p1->num!=0)
{
n=n+1;
if(n==1) head=p1;
else p2->next=p1;
p2=p1;
p1=(struct student *)malloc(LEN);    //開(kāi)辟動(dòng)態(tài)存儲(chǔ)區(qū),把起始地址賦給p1
scanf("%ld,%f",&p1->num,&p1->score);
}
p2-next=NULL;
return(head);
}
int main()
{
 struct student *pt;
pt=creat();    //函數(shù)返回鏈表第一個(gè)結(jié)點(diǎn)的地址
printf("\nnum:%ld\nscore:%5.f\n",pt->num,pt->score);    //輸出第一個(gè)結(jié)點(diǎn)的成員值
return 0;
}
結(jié)果:
1 65
2 50
3 34
0 0
num:1
score:65


9.2 共用體類(lèi)型

共用體結(jié)構(gòu),用同一段內(nèi)存單元存放不同類(lèi)型的變量(存放共用體的成員,但同時(shí)只能放一個(gè),保留最一個(gè)存放的變量)。

定義共用體類(lèi)型變量的一般形式:
union 共用體名 例如 union Data

{成員表列 { int i;

}變量表列 ; char ch;

float f;

}a,b,c;

也可以類(lèi)型聲明和變量定義分開(kāi):例如:

union Data
{int i;
char ch;
float f;
};
union Data a,b,c;

共用體類(lèi)型數(shù)據(jù)的特點(diǎn),同一段內(nèi)存可以幾種不同的類(lèi)型成員,但每一瞬間只能存放其中一個(gè)成員,而不是同時(shí)存放幾個(gè)成員。

union Data
{int i;
char ch;
float f;
};
union Data a;
a.ch='a';
a.f=100.2;
a.i=97;  //內(nèi)存中最終存儲(chǔ)97
printf("%d",a.i);    //輸出97
printf("%c",a.ch);    //輸出字符'a',ASCII碼是97
printf("%f",a.f);    //輸出實(shí)數(shù)0.0000


9.3 枚舉類(lèi)型

聲明枚舉類(lèi)型的一般形式為:enum[枚舉名] {枚舉元素列表};

定義枚舉類(lèi)型變量:例如:(1)先聲明枚舉類(lèi)型enum Weekdat: enum Weekdat {sun,mon,tue,wed,thu,fir,sat};(2)在定義變量:enum Weekdat workday; workday變量的值只能是枚舉元素列表中的枚舉元素(也稱(chēng)枚舉常量)。枚舉元素列表中的枚舉元素按順序系統(tǒng)默認(rèn)它們的值是0,1,2,3....。workday=mon;相當(dāng)于workday=1;


用typedef聲明新類(lèi)型名

簡(jiǎn)單地用一個(gè)新的類(lèi)型名代替原有的類(lèi)型名

例如: typedef int Integer;指定用Integer代表int類(lèi)型。這樣 int i;等價(jià)于 Integer i;

通過(guò)typedef可以命名一個(gè)簡(jiǎn)單的類(lèi)型名代替復(fù)雜的類(lèi)型表示方法,例如

sypedef struct
  {
    long int num;
    char name[20];
    char sex;
  }student1;
聲明了一個(gè)新類(lèi)型名student1,代表上面的結(jié)構(gòu)體類(lèi)型。
定義結(jié)構(gòu)體變量: student1 xisi;

命名一個(gè)新的類(lèi)型名代表數(shù)組類(lèi)型,例如typedef int Num[100];//聲明Num為整型數(shù)組類(lèi)型名

Num a;定義a為整型數(shù)組名,它有100個(gè)元素。

命名一個(gè)新的類(lèi)型名代表指針類(lèi)型,例如typedef char *String;//聲明String 為字符指針類(lèi)型

String p,s[10];//定義p為字符指針變量,s為字符指針數(shù)組。一般typedef聲明新的類(lèi)型名的開(kāi)頭用大寫(xiě)。

命名一個(gè)新的類(lèi)型名代表指向函數(shù)的指針類(lèi)型,typedef int (*Pointer)(); //聲明Pointer為指向函數(shù)的指針類(lèi)型,該函數(shù)的返回整型。Pointer p1,p2; //p1,p2為Pointer類(lèi)型的指針變量。



第10章 對(duì)文件的輸入輸出(主要討論數(shù)據(jù)文件)

10.1 什么是文件

文件有不同的類(lèi)型,在程序設(shè)計(jì)中,主要用到兩種文件:程序文件和數(shù)據(jù)文件。程序文件:包括源程序文件(后綴.c)、目標(biāo)文件(后綴.obj)、可執(zhí)行文件(后綴.exe)等,這些文件的內(nèi)容是程序代碼。數(shù)據(jù)文件,文件的內(nèi)容不是程序,而是程序運(yùn)行時(shí)讀寫(xiě)的數(shù)據(jù),如在程序運(yùn)行過(guò)程中輸出到磁盤(pán)(或其他設(shè)備)的數(shù)據(jù),或在程序運(yùn)行過(guò)程中供讀入的數(shù)據(jù),如:一批學(xué)生的成績(jī)數(shù)據(jù)。

為了簡(jiǎn)化用戶(hù)對(duì)輸入輸出設(shè)備的操作,使用戶(hù)不必去區(qū)分各種輸入輸出設(shè)備之間的區(qū)別,操作系統(tǒng)把各種設(shè)備都統(tǒng)一作為文件處理。(例如鍵盤(pán)是輸入文件、顯示屏和打印機(jī)是輸出文件)。所謂”文件“一般指存儲(chǔ)在外部介質(zhì)上數(shù)據(jù)的集合(一批數(shù)據(jù)是以文件的形式存放在外部介質(zhì)(如磁盤(pán))上的)。

,輸入輸出是數(shù)據(jù)傳送的過(guò)程,數(shù)據(jù)如流水一樣從一處流向另一處,因此常將輸入輸出形象地稱(chēng)為流,即數(shù)據(jù)流。


10.2 文件分類(lèi)

一個(gè)文件要有一個(gè)唯一的文件標(biāo)識(shí):包括(1)文件路徑;(2)文件名主干;(3)文件后綴。如:D: \CC \temp \file1.dat

文件的分類(lèi):根據(jù)數(shù)據(jù)的組織形式,數(shù)據(jù)文件可分為:ASCII文件和二進(jìn)制文件。數(shù)據(jù)在內(nèi)存中以二進(jìn)制的形式存儲(chǔ)的,如果不加轉(zhuǎn)換地輸出到外存,就是二進(jìn)制文件,可以認(rèn)為它就是存儲(chǔ)在內(nèi)存的數(shù)據(jù)的映像,所以也稱(chēng)為映像文件。ASCII文件又稱(chēng)為文本文件(text file),每一個(gè)字節(jié)放一個(gè)字符的ASCII代碼。

在磁盤(pán)上,字符一律以ASCII形式存儲(chǔ),數(shù)值型數(shù)據(jù)既可以用ASCII也可以用二進(jìn)制存儲(chǔ)。


10.3 文件的使用

ANSI C標(biāo)準(zhǔn)采用”文件緩沖系統(tǒng)“處理數(shù)據(jù)文件。所謂文件緩沖系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存區(qū)為程序中每個(gè)正在使用的文件開(kāi)辟一個(gè)文件緩沖區(qū)。文件緩沖區(qū)作用:程序數(shù)據(jù)區(qū)——輸入(或輸出)文件緩沖區(qū)——磁盤(pán)。

文件類(lèi)型指針:FILE *文件名,如FILE *f1。它是指向一個(gè)文件的文件信息區(qū)(存放這文件的有關(guān)信息的地方)。

打開(kāi)文件,所謂的”打開(kāi)“,是指為文件建立相應(yīng)的信息區(qū)(用來(lái)存放有關(guān)文件的信息)和文件緩沖區(qū)(用來(lái)暫時(shí)存放輸入輸出的數(shù)據(jù))。

fopen函數(shù),打開(kāi)文件。函數(shù)調(diào)用方法:fopen(文件名,使用文件方式),例如fopen("a1","r"),fopen(a2,“r”),F(xiàn)ILE *fp=fopen(a3,“w”),a2、a3是存放文件名的數(shù)組名。

文件使用方式 含義 如果指定的文件不存在
”r“(只讀) 為了輸入數(shù)據(jù),打開(kāi)一個(gè)也存在的文本文件 出錯(cuò)
"w"(只寫(xiě)) 為了輸出數(shù)據(jù),打開(kāi)一個(gè)文本文件 建立新文件
"a"(追加) 向文本文件尾添加數(shù)據(jù) 出錯(cuò)
"rb"(只讀) 為了輸入數(shù)據(jù),打開(kāi)一個(gè)二進(jìn)制文件 出錯(cuò)
"wb"(只寫(xiě)) 為了輸出數(shù)據(jù),打開(kāi)一個(gè)二進(jìn)制文件 建立新文件
"ab"(追加) 向二進(jìn)制文件尾添加數(shù)據(jù) 出錯(cuò)
"r+"(讀寫(xiě)) 為了讀和寫(xiě),打開(kāi)一個(gè)文本文件 出錯(cuò)
"w+"(讀寫(xiě)) 為了讀和寫(xiě),建立一個(gè)新的文本文件 建立新文件
"a+"(讀寫(xiě)) 為了讀和寫(xiě),打開(kāi)一個(gè)文本文件 出錯(cuò)
"rb+"(讀寫(xiě)) 為了讀和寫(xiě),打開(kāi)一個(gè)二進(jìn)制文件 出錯(cuò)
"wb+"(讀寫(xiě)) 為了讀和寫(xiě),建立一個(gè)新的二進(jìn)制文件 建立新文件
"ab+"(讀寫(xiě)) 為了讀和寫(xiě),打開(kāi)一個(gè)二進(jìn)制文件 出錯(cuò)

fclose函數(shù),關(guān)閉文件。fclose函數(shù)調(diào)用的一般形式:fclose(文件指針),例如:fclose(fp);

對(duì)文本文件讀寫(xiě)一個(gè)字符的函數(shù)

函數(shù)名 調(diào)用形式 功能 返回值
fgetc fgetc(fp) 從fp指向的文件讀入一個(gè)字符 成功(返回讀取的字符),失敗(返回-1,即文件結(jié)束標(biāo)志EOF)
fputc fputc(ch,fp) 把字符ch寫(xiě)到文件指針變量fp所指向的文件中 成功(返回輸出的字符),失。ǚ祷-1,即文件結(jié)束標(biāo)志EOF)

讀寫(xiě)一個(gè)字符串的函數(shù)

函數(shù)名 調(diào)用形式 功能 返回值
fgets fgets(str,n,fp) 從fp指向的文件讀入一個(gè)長(zhǎng)度為(n-1)的字符串,存放到字符數(shù)組str中。 讀成功(返回地址str),失。ǚ祷豊ULL)
fputs fputs(str,fp) 把str所指向的字符串寫(xiě)到文件指針變量fp所指向的文件中。 輸出成功(返回0),失。ǚ祷胤0值)

用格式化的方式讀取文件:

fprintf(文件指針,格式字符串,輸出列表);例如:fprintf(fp,"%d,%f",i,f);

fsanf(文件指針,格式字符串,輸入列表);scanf(fp,"%d,%f",&i,&f);

用二進(jìn)制方式向文件讀取一組數(shù)據(jù):它們一般調(diào)用形式:讀入:fread(buffer,size,count,fp);輸出:fwrite(buffer,size,count,fp);其中buffer是地址,size:要讀寫(xiě)的字節(jié)數(shù),count:要讀寫(xiě)多少個(gè)數(shù)據(jù)項(xiàng)(每個(gè)數(shù)據(jù)項(xiàng)的長(zhǎng)度為size)。注意,打開(kāi)文件時(shí)要使用二進(jìn)制形式,如:fopen(”file1“,”wb“)。


文件位置標(biāo)記

(1)用rewind函數(shù)使文件位置標(biāo)記指向文件開(kāi)頭。

(2)用fseek函數(shù)改變文件位置標(biāo)記,fseek函數(shù)的調(diào)用形式為:fseek(文件指針,位移量,起始點(diǎn)),起始點(diǎn)可以用0、1、2代替,其中0代表文件開(kāi)始位置,1代表當(dāng)前位置,2代表文件末尾位置。起始點(diǎn)名字如表:

起始點(diǎn) 名字 用數(shù)字代表
文件開(kāi)始位置 SEEK_SET 0
文件當(dāng)前位置 SEEK_CUR 1
文件末尾位置 SEEK_END 2

位移量應(yīng)是long型數(shù)據(jù)(在數(shù)字的末尾加一個(gè)字母L,就表示long型)

例如:fseek(fp,100L,0)將文件位置標(biāo)記向前移到離文件開(kāi)頭100個(gè)字節(jié)處。


文件讀寫(xiě)的出錯(cuò)檢測(cè)

ferror函數(shù),檢查輸入輸出函數(shù)出錯(cuò)的情況,一般調(diào)用形式:ferror(fp);出錯(cuò)時(shí)返回非0值,未出錯(cuò)返回0值。注意,對(duì)同一個(gè)文件每一次調(diào)用輸入輸出函數(shù),都會(huì)產(chǎn)生一個(gè)新的ferror函數(shù)值。

clearerr函數(shù),作用是使文件錯(cuò)誤標(biāo)志和文件結(jié)束標(biāo)志為0。一般調(diào)用形式:clearerr(fp)。

Tags:C語(yǔ)言,編程入門(mén),入門(mén)教程  
責(zé)任編輯:admin
請(qǐng)文明參與討論,禁止漫罵攻擊。 昵稱(chēng):注冊(cè)  登錄
[ 查看全部 ] 網(wǎng)友評(píng)論
關(guān)于我們 - 聯(lián)系我們 - 廣告服務(wù) - 友情鏈接 - 網(wǎng)站地圖 - 版權(quán)聲明 - 在線幫助 - 文章列表
返回頂部
刷新頁(yè)面
下到頁(yè)底
晶體管查詢(xún)