课程主题字串.docx

上传人:b****3 文档编号:10573570 上传时间:2023-05-26 格式:DOCX 页数:27 大小:65.40KB
下载 相关 举报
课程主题字串.docx_第1页
第1页 / 共27页
课程主题字串.docx_第2页
第2页 / 共27页
课程主题字串.docx_第3页
第3页 / 共27页
课程主题字串.docx_第4页
第4页 / 共27页
课程主题字串.docx_第5页
第5页 / 共27页
课程主题字串.docx_第6页
第6页 / 共27页
课程主题字串.docx_第7页
第7页 / 共27页
课程主题字串.docx_第8页
第8页 / 共27页
课程主题字串.docx_第9页
第9页 / 共27页
课程主题字串.docx_第10页
第10页 / 共27页
课程主题字串.docx_第11页
第11页 / 共27页
课程主题字串.docx_第12页
第12页 / 共27页
课程主题字串.docx_第13页
第13页 / 共27页
课程主题字串.docx_第14页
第14页 / 共27页
课程主题字串.docx_第15页
第15页 / 共27页
课程主题字串.docx_第16页
第16页 / 共27页
课程主题字串.docx_第17页
第17页 / 共27页
课程主题字串.docx_第18页
第18页 / 共27页
课程主题字串.docx_第19页
第19页 / 共27页
课程主题字串.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

课程主题字串.docx

《课程主题字串.docx》由会员分享,可在线阅读,更多相关《课程主题字串.docx(27页珍藏版)》请在冰点文库上搜索。

课程主题字串.docx

课程主题字串

C/C++基礎

課程主題:

字串、字串函數

  字串(string)即是由字元(character)所組成的一段文字,在C語言裡,沒有專屬字串的資料型態,因此我們是用字元陣列來模擬字串的。

字串的基本概念

  字串是由字元所組成的一維陣列,為了要知道字串結束的位置,字串的末端必須要加上一個'\0'字元,稱之為空字元(NULLcharacter),ASCII碼值為0。

表示一個字元要在字元前後加上單引號('),同樣的表示一個字串則要在前後加上雙引號("),例如:

"IloveInfor!

"。

字串的宣告

  宣告字串有兩種方式,一種是以陣列方式,另外一種是用指標的形式,例如:

charS1[10]="Hello";//陣列式的宣告,剩餘的空間補'\0'

charS2[]="Hello";//自動設定字元陣列的長度為6

charS3[]={'H','e','l','l','o','\0'};//標準陣列初始化寫法(不可省略'\0')

char*pS=S3;//指標式的宣告

記憶體中的配置如下所示:

※計算長度時要注意:

英文字母等等半形碼佔1byte,而中文字等等全形碼佔2bytes。

【範例】

#include

#defineSIZE6

intmain()

{

inti;

charS1[SIZE]="INFOR";

for(i=0;i

printf("S1[%d]=%c\n",i,S1[i]);

printf("S1=%s\n",S1);//%s是使用於字串的轉換規格符號

system("pause");

return0;

}

字串的輸出輸入

輸出指令

printf()

【語法】

printf("%s",字串名稱);

【說明】

  %s是使用於字串的轉換規格符號。

相較於puts(),printf()不會自動加上換行字元('\n'),需要自行加入。

puts()

【語法】

puts(字串名稱);

【說明】

  puts的使用方式很簡單,只要傳入一個字串當引數就可以了。

puts()會在印完每段字串後自動加上換行字元('\n')。

輸入指令

scanf()

【語法】

scanf("%s",字串名稱);//不用加&

【說明】

  scanf()會從一個非空白字元(如果開頭是空白字元會被略過)一直讀取到空白字元(Space、Tab、Enter)之前。

換行字元不會被去掉。

gets()

【語法】

gets(字串名稱);

【說明】

  gets()函數會讀取換行字元('\n')前的所有字元,並且加上空字元('\0'),然後再將讀取的字串傳給呼叫它的程式。

換行字元讀取時會被去掉。

【討論】

  使用gets()和scanf()函數有一個很大的缺點,就是不能限制輸入資料的大小,若有多餘的字元會溢出至鄰近的記憶體。

這個問題可以使用fgets()函數來解決(往後課程會介紹)。

【範例】

#include

#include

intmain()

{

chartmp[100];

//測試printf(),scanf()

printf("使用scanf()輸入:

");

scanf("%s",tmp);

printf("輸出結果:

%s\n",tmp);

while(getchar()!

='\n')continue;//清空緩衝區

//測試puts(),gets()

puts("使用gets()輸入:

");

gets(tmp);

printf("輸出結果:

%s\n",tmp);

system("pause");

return0;

}

字串函數

  如果我們要作字串的比對、字串的串接、計算字串長度等功能,C語言有提供許多這類處理字串的函數,ANSIC使用了string.h的標頭檔來提供這些函數的原型。

以下列出一些常用的函數:

函數用法

用途(以下函數都要引入string.h才能使用)

strlen(string)

計算string的長度(不含'\0')。

strcat(string1,string2)

將string2的內容接到string1的後面。

strcmp(string1,string2)

將string1和string2作比較,相等傳回0。

strcpy(string1,string2)

將string2的內容複製到string1內。

strstr(string1,string2)

傳回string2在string1中第一次出現的位置(以char*型態)。

strrev(string)

將string字串倒置。

strtok(string1,string2)

將string2的每個字元當作分隔符號,把string1做切割。

遇到結尾會傳回NULL。

※在使用strcat()或strcpy()這些函數時,要特別注意目的字串是否有足夠的空間。

【範例】

#include

#include

#include

intmain()

{

chartmp[100],*token,*sep=",.";//分隔字元

puts("輸入欲切割的字串:

");

gets(tmp);

puts("結果:

");

for(token=strtok(tmp,sep);token!

=NULL;token=strtok(NULL,sep))

puts(token);

puts("切開後的原字串");

puts(tmp);

system("pause");

return0;

}

C/C++基礎

課程主題:

指標的基本概念、函數的傳址呼叫

指標的基本概念

  當我們宣告一個變數時,其實是向系統申請一個記憶體空間來儲存資料,系統會分配一個位址來存放這個變數,因此宣告的程序結束後,每個變數都擁有自己的位址。

  指標(pointer)也是一個變數,就像int變數能儲存整數一樣,指標變數能儲存記憶體內的位址。

指標的宣告

  指標的宣告是在資料型態後面加上星號(*),如下所示:

int*ptr;//宣告ptr為一個指向int的指標

float*ptr2;//宣告ptr2為一個指向float的指標

char*pS,*pS2;//宣告pS,pS2分別為指向char的指標

取值運算子(*)、取址運算子(&)

運算子

功能

*

傳回運算元所指向位址的資料

&

傳回運算元的起始位址

【範例】

#include

#include

intmain()

{

intval=10;

int*ptr=&val;

printf("val的值=%d\n",val);

printf("val的位址=%p\n",&val);

printf("ptr的值=%p\n",ptr);

printf("ptr的位址=%p\n",&ptr);

printf("ptr指向的值=%d\n",*ptr);

//system("pause");

return0;

}

【範例】

#include

#include

intmain()

{

inta=10;

int*b=&a;

printf("a=%d*b=%d\n",a,*b);

*b=20;

printf("a=%d*b=%d\n",a,*b);

system("pause");

return0;

}

函數的傳址呼叫

  在C語言裡,函數呼叫的方式可以分為「傳值呼叫(callbyvalue)」和「傳址呼叫(callbyaddress)」兩種。

函數在傳遞引數的時候,會先將引數複製一份然後再進行運算,因此如果以傳值呼叫的方式,即傳遞的引數為一般變數,原先變數的值是不會改變的(只會改變複製變數的值,不會影響到原來變數);但如果傳遞的是變數的位址,我們可以透過取值運算子(*)直接取到該位址的變數,因此可以改變該變數的值,這就是所謂的傳址呼叫。

【範例】

#include

#include

voidswap(int,int);//傳值呼叫

voidswap2(int*,int*);//傳址呼叫

intmain()

{

inta,b;

printf("輸入a,b兩整數...");

scanf("%d%d",&a,&b);

printf("a=%db=%d\n",a,b);

swap(a,b);

printf("執行swap(a,b)後\n");

printf("a=%db=%d\n",a,b);

swap2(&a,&b);

printf("執行swap2(&a,&b)後\n");

printf("a=%db=%d\n",a,b);

system("pause");

return0;

}

voidswap(inta,intb)

{

inttmp=b;

b=a;

a=tmp;

}

voidswap2(int*a,int*b)

{

inttmp=*b;

*b=*a;

*a=tmp;

}

C/C++基礎

課程主題:

指標的運算、指標與陣列、動態配置記憶體

指標的運算

  指標的運算除了取值、取址或者設定之外,還有加減法和差值這兩種運算。

【範例】

#include

#include

intmain()

{

inta[10],*ptr=&a[1],*ptr2=&a[4];

printf("ptr=%p\n",ptr);

printf("ptr+1=%p\n",ptr+1);//加法

printf("(char*)ptr+1=%p\n",(char*)ptr+1);//加法

printf("ptr-1=%p\n",ptr-1);//減法

printf("ptr2-ptr=%d\n",ptr2-ptr)//差值;

printf("ptr-ptr2=%d\n",ptr-ptr2);//差值

system("pause");

return0;

}

【討論】

  由上面的範例我們可以知道,指標的加減法實際上就是做位址的移動,因此指標是什麼資料型態就顯得格外重要,因為它代表著每單位位移的大小。

例如,int是4bytes,每移動1單位相當於移動4bytes,而char是1byte,移動1單位即移動1byte。

所以,不同型態的指標之間,除非經過強制轉換,否則是不能做運算的。

  另外C語言有提供一種void*型態的指標,它純粹只用來記錄位址,因此不能做加減運算,它的功能在於能與任意型態的指標相容。

【範例】

#include

#include

#defineSIZE5

voidcopy(void*,void*,int);

intmain()

{

inti;

inta[SIZE]={1,2,3,4,5},b[SIZE]={0,0,0,0,0};

printf("原始陣列:

");

for(i=0;i

printf("\n");

copy(a,b,sizeof(int)*SIZE);

printf("後來陣列:

");

for(i=0;i

printf("\n");

system("pause");

return0;

}

voidcopy(void*src,void*des,intlen)

{

inti;

char*src_tmp=(char*)src,des_tmp=(char*)des;

for(i=0;i

des_tmp[i]=src_tmp[i];

}

指標與陣列

  陣列是記憶體中一塊連續的空間,陣列的名稱記錄了整塊空間開頭的位址,所以我們可以透過索引值(偏移量)來存取到我們需要的位置;換句話說,陣列名稱算是一種不能改變位址的常數指標,和指標之間的關係相當密切。

指標與一維陣列

  如果宣告:

inta[5]={1,2,3,4,5};

陣列標記

指標標記

內容

陣列標記

指標標記

內容(假設)

a[0]

*(a+0)

1

&a[0]

a

0x0012FEC4

a[1]

*(a+1)

2

&a[1]

a+1

0x0012FEC8

a[2]

*(a+2)

3

&a[2]

a+2

0x0012FECC

a[3]

*(a+3)

4

&a[3]

a+3

0x0012FED0

a[4]

*(a+4)

5

&a[4]

a+4

0x0012FED4

指標與多維陣列

  如果宣告:

inta[2][3]={{1,2,3},{4,5,6}};

陣列標記

指標標記

內容

陣列標記

指標標記

內容(假設)

a[0][0]

*(*(a+0)+0)

1

&a[0][0]或a[0]+0

*(a+0)+0

0x0012FEC0

a[0][1]

*(*(a+0)+1)

2

&a[0][1]或a[0]+1

*(a+0)+1

0x0012FEC4

a[0][2]

*(*(a+0)+2)

3

&a[0][2]或a[0]+2

*(a+0)+2

0x0012FEC8

a[1][0]

*(*(a+1)+0)

4

&a[1][0]或a[1]+0

*(a+1)+0

0x0012FECC

a[1][1]

*(*(a+1)+1)

5

&a[1][1]或a[1]+1

*(a+1)+1

0x0012FED0

a[1][2]

*(*(a+1)+2)

6

&a[1][2]或a[1]+2

*(a+1)+2

0x0012FED4

示意圖如下:

【說明】

  上述a是一個二維陣列,所以a的每個元素其實是一個大小為3的int陣列,因此a+1會移動3個int的大小即12bytes。

相對的a[0]所指向的物件是一個整數,所以a[0]+1只會移動一個int大小。

#include

#include

intmain()

{

inta[2][3]={1,2,3,4,5,6};

printf("a=%p\ta+1=%p\n",a,a+1);

printf("a[0]=%p\ta[0]+1=%p\n",a[0],a[0]+1);

printf("*a=%p\t*a+1=%p\n",*a,*a+1);

printf("a[0][0]=%d\n",a[0][0]);

printf("*a[0]=%d\n",*a[0]);

printf("**a[0]=%d\n",**a);

printf("a[1][2]=%d\n",a[1][2]);

printf("*(*(a+1)+2)=%d\n",*(*(a+1)+2));

//補充說明

printf("(*a)[1]=%d\n",(*a)[1]);

printf("*a[1]=%d\n",*a[1]);

system("pause");

return0;

}

動態配置記憶體

  之前變數的宣告,都是使用「靜態宣告」的方式,也就是在編譯階段即完成宣告;現在我們要介紹的是「動態宣告」,能夠在程式執行中才配置記憶體空間,使記憶體的使用更加具有彈性。

以下是兩種配置方式的比較:

動態配置

靜態配置

記憶體配置

執行階段

編譯階段

記憶體釋放

程式結束釋放,否則造成記憶缺口

程式結束自動歸還系統

效能

較慢

較快

指標遺失位址

記憶缺口

無此問題

  配置動態空間所使用的函數常用的是malloc()和free(),前者是配置所需的空間,後者是釋放配置的空間。

兩個函數都宣告在stdlib.h裡,需要引入才可使用。

【語法】

資料型態*指標名稱=(資料型態*)malloc(sizeof(資料型態)*資料長度);

free(指標名稱);

【範例】

#include

#include

intmain()

{

inti,n,*num,sum=0;

printf("輸入多少數字:

");

scanf("%d",&n);

num=(int*)malloc(sizeof(int)*n);

for(i=0;i

printf("輸入第%d個數字:

",i+1);

scanf("%d",&num[i]);

sum+=num[i];

}

printf("總和為:

%d\n",sum);

system("pause");

return0;

}

C/C++基礎

課程主題:

檔案輸出輸入

  對於檔案的處理,C提供了強大的功能,可以讓我們在程式中開啟檔案,利用特殊的I/O函數執行讀入或寫入的動作。

※stdio.h全名為StandardInput/OutputHeader,內容就是有關I/O的函數、常數、結構等等的宣告。

以下所介紹的都宣告在stdio.h的檔案裡,所以不再特別註明。

開檔

  使用任何檔案之前都要經過開檔的動作,我們使用fopen()函數來執行這項動作。

【語法】

FILE*指標名稱=fopen(檔案路徑或名稱,檔案開啟模式);

【說明】

  fopen()執行成功後會傳回一個FILE型態的指標(失敗回傳NULL),因此我們要宣告一個FILE*變數來接收其值。

FILE是一個包含檔案相關資訊的資料結構(struct),以提供I/O函數對某個檔案做處理。

此外,在stdio.h裡宣告了三種FILE*供我們使用,如下表:

標準檔案

檔案指標

慣例

標準輸入

stdin

鍵盤

標準輸出

stdout

螢幕

標準錯誤

stderr

螢幕

  關於檔案開啟的模式整理至下表:

模式

意義

"r"

開啟用來讀取的檔案,檔案不存在則傳回NULL

"w"

開啟用來寫入的檔案,自行建立新檔,若檔案存在舊檔會被刪除。

"a"

開啟用來寫入的檔案,寫入的資料加在檔尾,檔案不存在則建立新檔

"r+"

開啟用來更新(也就是可寫也可讀)的檔案,檔案不存在則傳回NULL

"w+"

開啟用來更新的檔案,若檔案存在舊檔會被刪除,檔案不存在則建立新檔

"a+"

開啟用來更新的檔案,寫入的資料加在檔尾,檔案不存在則建立新檔

上述的模式是以文字(text)的方式作存取,如果要以二元(binary)方式存取的話只要在原本模式後加上"b"就行了。

例如:

"rb"、"r+b"、"rb+"……等等。

【範例】

#include

#include

intmain()

{

FILE*fp;

charch;

if((fp=fopen("tmp.txt","r"))==NULL){//如果開啟檔案失敗就結束程式

printf("Can'tfindthefile.\n");

system("pause");

exit

(1);

}

while((ch=getc(fp))!

=EOF)//從檔案裡讀取一個字元

putchar(ch);//印至螢幕上

system("pause");

return0;

}

檔案處理函數

輸出指令

fprintf()

【語法】

fprintf(FILE*,"輸出內容",變數名稱);

【說明】

  與printf()的使用方法相近,只是額外多第一個參數,以識別要輸出至什麼檔案。

fputs()

【語法】

fputs(字串名稱,FILE*);

【說明】

  將第一個參數的字串輸出至FILE*指向的檔案,與puts()不同的是,不會自動加上換行字元('\n')。

輸入指令

fscanf()

【語法】

fscanf(FILE*,"輸入內容",變數位址);

【說明】

  同樣與scanf()使用方法相近,但多一個FILE*參數識別檔案。

讀到檔案結尾或讀取錯誤時,fscanf()會回傳EOF。

fgets()

【語法】

fgets(字串名稱,最大長度,FILE*);

【說明】

  fgets()可以限制輸入資料的長度,因此使用上比gets()來的更加安全。

另外,fgets()會讀入換行字元,而讀到檔案結尾或錯誤時,會回傳NULL。

關檔

  使用完檔案後要養成關檔的好習慣,因為每個系統能同時開啟的檔案有限,隨手關閉不再讀寫的檔案可以節省系統資源,所以我們使用fclose()來關閉檔案。

【語法】

fclose(FILE*);

【說明】

  fclose()執行成功會傳回0,否則會傳回EOF。

【範例】

#include

#include

intmain()

{

FILE*in,*out;

charbuf[100],name[20],name2[20];

fprintf(stdout,"請輸入要複製的檔案:

");

fscanf(stdin,"%s",name);

if((in=fopen(name,"r"))==NULL)exit

(1);//無法開檔結束程式

fprintf(stdout,"複製檔的名稱:

");

fscanf(stdin,"%s",name2);

if((out=fopen(name2,"w"))==NULL)exit

(1);//無法建檔結束程式

while(fgets(buf,100,in)!

=NULL)

fputs(buf,out);

fclose(in);

fclose(out);

system("pause");

return0;

}

C/C++基礎

課程主題:

列舉(enum)、結構(struct)

列舉

  列舉型態(enumeratedtype)常運用在具有相同類型特點的常數識別字,將它們集合在一起,給予一個可以辨識的名字,取代沒有意義的數值,既可以統一名稱管哩,也方便我們記憶,加強了程式的可讀性。

【語法】

enum列舉名稱{成員1,成員2,成員3,......}變數名稱;

【說明】

  enum是一種衍生的資料型態,所以我們可以使用自訂的enum來宣告變數。

enum中成員的值可以自訂,如果沒有特別指定,則會自動往後遞增編號(完全沒給會從0開始編號)。

enum成員其實就是整數常數,所以可以把它用來當作switch敘述的標籤使用。

【範例】

#include

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2