第3章 指標與字串 (Pointers and Strings)

Slides:



Advertisements
Similar presentations
資料坐火車 …… 談陣列 (Array) 綠園 2008/12/15. Array 的宣告 整數陣列的宣告  int student[5]; 意義:宣告了 5 個 int 大小的連續空間,名稱 為 student ,沒有預設值,則為系統殘值。 student student[0] student[1]
Advertisements

第一單元 建立java 程式.
电子成绩单项目实现.
陣列與字串 Java陣列特性 一維陣列 多維陣列 字串 字串的相關函數 字串緩衝器類別.
C/C++基礎程式設計班 陣列 (Array)
基本輸入與輸出 王振生.
Chapter 3.0 C語言的結構與指標 資料結構導論 - C語言實作.
資料結構 Data Structure.
第2章 陣列與結構 (Arrays and Structures)
資料結構 第2章 陣列.
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
結構(struct).
第十一章 結構.
C 程式設計— 字元與字串 台大資訊工程學系 資訊系統訓練班.
第5章 基本輸入與輸出 5-1 程式的輸入與輸出 5-2 字元與字串的輸入 5-3 字元與字串的輸出 5-4 格式化資料的輸入
Visual C++ introduction
Do.For.While.正三角.倒正三角.倒九九乘法表
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 指定字串的初值 8-3 指標與字串 8-4 字串處理 8-5 C語言的字串函數.
列舉(enum).
【變數與記憶體位址】 變數(Variable)提供一個有名稱的記憶體儲存空間。一個變數包含資料型態、變數本身的值及它的位址值。
程序设计II 第三讲 字符串处理.
String C語言-字串.
101北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
C語言簡介 日期 : 2018/12/2.
CLASS 5 指標.
Chapter 7 指標.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
Introduction to the C Programming Language
Introduction to the C Programming Language
Java 程式設計 講師:FrankLin.
字符串和字符数组 字符串的输入和输出 字符串的基本操作
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
Chap3 Linked List 鏈結串列.
|12 結構與列舉型態.
程式設計實習課(四) ----C 函數運用----
第一單元 建立java 程式.
Chapter 5 複合資料型態.
陣列(Array).
第7章 陣列與指標 7-1 陣列的基礎 7-2 一維陣列的處理 7-3 二維與多維陣列的處理 7-4 陣列的函數參數
輸入&輸出 函數 P20~P21.
第十章 指標.
第九章 字串.
第一次Labview就上手 參考書籍: LabVIEW for Everyone (Jeffrey Travis/Jim Kring)
程式設計 博碩文化出版發行.
第7章 指標 7-1 指標的基礎 7-2 指標變數的使用 7-3 指標運算 7-4 指標與陣列 7-5 指向函數的指標.
挑戰C++程式語言 ──第8章 進一步談字元與字串
函式庫補充資料.
認識常數與變數 學習C++所提供的各種基本資料型態 瞭解溢位的發生 學習認識資料型態之間的轉換
C qsort.
C程序设计.
挑戰C++程式語言 ──第7章 輸入與輸出.
流程控制:Switch-Case 94學年度第一學期‧資訊教育 東海大學物理系.
第14章 結構與其他資料形式.
陣列與結構.
指標、串列 (Linked List).
10115: Automatic Editing ★★☆☆☆
北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
實習八 函式指標.
1757: Secret Chamber at Mount Rushmore
Programming & Language Telling the computer what to do
C 程式設計— 字元與字串 台大資訊工程學系 資訊系統訓練班.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
字串 第10章 part I 8/30/2019.
String類別 在C語言中提供兩種支援字串的方式 可以使用傳統以null結尾的字元陣列 使用string類別
Array(陣列) Anny
C語言程式設計 老師:謝孟諺 助教:楊斯竣.
Introduction to the C Programming Language
台大資訊工程學系 資料系統訓練班 第119期 吳晉賢
台大資訊工程學系 資訊系統訓練班 第119期 吳晉賢
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
Presentation transcript:

第3章 指標與字串 (Pointers and Strings) 資料結構 第3章 指標與字串 (Pointers and Strings)

第3章 課程大綱 3-1 C語言的指標 3-2 指標與陣列 3-3 指標與結構 3-4 指標與字串 3-5 指標的應用 - 字串處理 2008/3/18

3-1 C語言的指標 3-1-1 指標變數(Pointer Variable)的使用 3-1-2 指向指標的指標變數 2008/3/18

3-1 C語言的指標 C語言的「指標」(Points)屬於一種低階的程式處理功能 可以直接存取記憶體位址 指標變數的變數內容並不是字元或數值等基本資料型態的值,而是其它變數的「位址」(Address)。 換句話說,單獨存在的指標變數並沒有意義,因為它的值是其它變數的位址,程式需先宣告其它變數,才能取得指標變數的值,即指向其它變數的儲存位址。 2008/3/18

3-1-1 指標變數的使用-說明 C語言的「指標變數」(Pointer Variables)是一種變數,其變數值是其它變數的位址(Address),如下圖所示: 間接索引 2008/3/18

3-1-1 指標變數的使用-宣告 指標變數的宣告和基本資料型態變數的宣告稍有不同,其宣告格式,如下所示: 資料型態 *變數名稱; 指標變數宣告和變數宣告只差變數名稱前的「*」星號,簡單的說,這個變數是指向宣告資料型態的指標變數, 例如:指向整數int的指標變數宣告,如下所示: int *ptr; 2008/3/18

3-1-1 指標變數的使用-取得變數位址 將指標變數ptr指向變數j的位址 取得變數位址是使用單運算元的「&」取址運算子,如下所示: ptr = &j; //取得變數 J 的位置 2008/3/18

3-1-1 指標變數的使用-初值 指標變數也可以在宣告時指定初值,不過取得位址的變數一定需要在指標變數前宣告,如下所示: int i; int *ptr1 = &i; 上述程式碼先宣告整數變數i,然後是指標變數ptr1,指標變數的初值是變數i的位址。 因為C語言的指標變數並沒有預設值,為了避免程式錯誤,例如:尚未指向其它變數的位址就使用指標變數,可以在宣告時指定成NULL常數,如下所示: int *ptr = NULL; 2008/3/18

3-1-1 指標變數的使用-取得變數值 在C程式取得指標變數指向的變數值 是使用單運算元的「*」星號運算子,稱為「取值」(Indirection)或「解參考」(Dereferencing)運算子, 例如:ptr是指向整數變數j的指標變數,*ptr就是變數j的值,如下所示: printf("*ptr :位址%p的值=%d\n", ptr, *ptr); 上述printf()函數使用%p格式字元顯示指標變數的值,ptr是變數j的位址,*ptr是變數j的值。 2008/3/18

程式範例Ch3-1-1.c 程式目標 執行結果如下 在C程式中宣告數個變數和指標變數, 然後測試 ”&” 取址運算子和 “*” 取值運算子 i=1 位址=0022FF74 j=2位址=0022FF70 ptr=0022FF70位址=0022FF6C *ptr=位址0022FF70的值=2 ptr1=0022FF74位址=0022FF68 *ptr1=位址0022FF74的值=1 2008/3/18

#include <stdio.h> #include <stdlib.h> /* 主程式 */ /* 程式範例: Ch3-1-1.c */ #include <stdio.h> #include <stdlib.h> /* 主程式 */ int main() { /* 宣告變數 */ int i, j; int *ptr = NULL; int *ptr1 = &i; /* 指標變數的初值 */ i = 1; j = 2; /* 取得指標變數的值 */ ptr = &j; printf("i =%8d 位址=%p\n", i, &i); printf("j =%8d 位址=%p\n", j, &j); printf("ptr =%p 位址=%p\n", ptr, &ptr); printf("*ptr :位址%p的值=%d\n", ptr, *ptr); printf("ptr1=%p 位址=%p\n", ptr1, &ptr1); printf("*ptr1:位址%p的值=%d\n", ptr1, *ptr1); system("PAUSE"); return 0; } 2008/3/18

3-1-2 指向指標的指標變數-說明 指向指標的指標變數是說指標變數是指向其它的指標變數。 首先在程式宣告一個整數 i 和指標變數 ptr,如下所示: int i = 5; int *ptr = &i; 接著再宣告一個指向指標的指標變數ptr1,如下所示: int **ptr1 = &ptr; 指標變數ptr1共有2個星號,第1個星號指出變數是一個指標變數,第2個星號表示它是指向指標變數,即ptr。 接著再宣告指標變數指向指標的指標變數,如下所示: int ***ptr2 = &ptr1; 指標變數ptr2共有3個星號,第1個星號指出變數是指標變數,後2個星號表示它是指向指標的指標變數,即ptr1。 2008/3/18

3-1-2 指向指標的指標變數-圖例 2008/3/18

程式範例Ch3-1-2.c 程式目標 在C程式中宣告指標變數, 指向指標的指標變數和指向指標的指標的指標變數, 然後分別執行取值運算, 以顯示其位址與值!! 執行結果如下 i=5 位址=0022FF74 ptr=0022FF74 位址=0022FF70 ptr1=0022FF70 位址=0022FF6C ptr2=0022FF6C 位址=0022FF68 *ptr=位址0022FF74的值=5 *ptr1=位址0022FF70的值=0022FF74 *ptr2=位址0022FF6C的值=0022FF70 *ptr = 5 **ptr1 = 5 ***ptr2 = 5 2008/3/18

#include <stdio.h> #include <stdlib.h> /* 主程式 */ /* 程式範例: Ch3-1-2.c */ #include <stdio.h> #include <stdlib.h> /* 主程式 */ int main() { /* 宣告變數 */ int i = 5; int *ptr = &i; int **ptr1 = &ptr; int ***ptr2 = &ptr1; /* 取得指標變數的值 */ printf("i =%8d 位址=%p\n", i, &i); printf("ptr =%p 位址=%p\n", ptr, &ptr); printf("ptr1=%p 位址=%p\n", ptr1, &ptr1); printf("ptr2=%p 位址=%p\n", ptr2, &ptr2); printf("*ptr :位址%p的值=%8d\n", ptr, *ptr); printf("*ptr1:位址%p的值=%p\n", ptr1, *ptr1); printf("*ptr2:位址%p的值=%p\n", ptr2, *ptr2); printf("*ptr = %d\n", *ptr); printf("**ptr1 = %d\n", **ptr1); printf("***ptr2= %d\n", ***ptr2); system("PAUSE"); return 0; } 2008/3/18

3-2 指標與陣列 (Pointers and Arrays) 3-2-1 指標與陣列 3-2-2 指標與二維陣列 3-2-3 指標陣列 2008/3/18

3-2-1 指標與陣列-說明 C語言的陣列配置 如果改成指標變數,只需將指標變數指向陣列的第1個元素, 是一塊連續的記憶體空間,然後使用索引值存取陣列元素 如果改成指標變數,只需將指標變數指向陣列的第1個元素, 元素存取就可以使用指標的數運算加和減來完成。 2008/3/18

3-2-1 指標與陣列-指向陣列元素 宣告指標變數指向陣列的第1個元素,如下所示: int *ptr = array; C語言的陣列名稱就是陣列第1個元素的位址,因為陣列名稱本身是一個指標變數,如果使用取址運算子「&」,其程式碼如下所示: ptr = &array[0]; 2008/3/18

3-2-1 指標與陣列-走訪陣列(方法1) 一共有2種方法存取其它陣列元素的值,如下所示: for ( i = 0; i < LEN; i++ ) printf("ptr+%d=%d ", i, *(ptr+i)); 2008/3/18

3-2-1 指標與陣列-走訪陣列(方法2) 第2個方法是使用指標變數的遞增運算ptr++,如下所示: for ( i = 0; i < LEN; i++ ) printf("ptr+%d=%d ", i, *ptr++); 上述for迴圈使用指標走訪陣列元素,指標運算ptr++移到下一個元素,元素值是取值運算*(ptr++), 這個方法會真正移動指標變數的位址,等到執行完迴圈,指標變數ptr是指向陣列的最後1個元素。 2008/3/18

程式範例Ch3-2-1.c 程式目標 在C程式中宣告一維陣列後, 分別使用陣列索引, 指標運算與遞增, 遞減運算顯示陣列所有元素的值!! 執行結果如下 array[0] = 1 array[1] = 23 array[2] = 23 array[3] = 17 array[4] = -40 array[5] =100 ptr+0=1 ptr+1=23 ptr+2=23 ptr+3=17 ptr+4=-40 ptr+5=100 ptr-0=100 ptr-1 = -40 ptr-2=17 ptr-3=23 ptr-4=23 ptr-5 =1 2008/3/18

ptr = &array[0]; /* 第一個元素 */ for ( i = 0; i < LEN; i++ ) /* 程式範例: Ch3-2-1.c */ #include <stdio.h> #include <stdlib.h> #define LEN 6 /* 主程式 */ int main() { /* 宣告變數 */ int i; /* 建立int陣列且指定初值 */ int array[LEN] = { 1, 23, 33, 17, -40, 100 }; int *ptr = array; /* 第一個元素 */ /* 顯示陣列元素的值 */ for ( i = 0; i < LEN; i++ ) printf("array[%d]=%d ",i,array[i]); printf("\n"); ptr = array; /* 第一個元素 */ printf("ptr+%d=%d ", i, *(ptr+i)); ptr = &array[0]; /* 第一個元素 */ for ( i = 0; i < LEN; i++ ) printf("ptr+%d=%d ", i, *ptr++); printf("\n"); ptr = &array[LEN-1]; /* 最後一個元素 */ printf("ptr-%d=%d ", i, *ptr--); system("PAUSE"); return 0; } 2008/3/18

3-2-2 指標與二維陣列-範例 C語言的二維陣列也可以使用指標變數來存取陣列元素,例如:宣告一個二維整數陣列tables[][],如下所示: #define ROWS 4 #define COLS 5 int tables[ROWS][COLS]; 2008/3/18

3-2-2 指標與二維陣列-方法1 視為一維陣列存取,因為二維陣列配置的記憶體空間是將每一列結合起來的連續記憶體位置,如同4列合一的一維陣列,如下所示: int *ptr; ptr = &tables[0][0]; 指標變數ptr指向陣列第1個元素的位址。 接著使用指標運算取得每一個陣列元素,如下所示: for ( i=0; i < ROWS; i++) { //先控制Row在控制COLS for ( j=0; j < COLS; j++) printf("%d*%d=%2d ", (i+1), (j+1), *(ptr+(i*COLS)+j)); printf("\n"); } 2008/3/18

3-2-2 指標與二維陣列-方法2 第二個方法是使用tables[ ][ ]陣列名稱的指標變數,其運算式如下所示: *(*(tables + i) + j) tables是二維陣列的名稱,可以將它視為是一個指向指標的指標變數,在中間括號部分的運算式,如下所示: *(tables+i) 上述指標運算可以當作是第一欄tables[ROWS][0]的指標運算,取值運算取得的是: tables[0][0](tables+0) tables[1][0](tables+1) tables[2][0](tables+2) tables[3][0](tables+3) 2008/3/18

程式範例Ch3-2-2.c 程式目標 在C程式中宣告 2 維陣列儲存部分的九九乘法表, 然後使用指標方式顯示部分的九九乘法表!! 執行結果如下 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 上方是用一維陣列的指標存取, 下方是用二維陣列的指標存取來顯示部分的九九乘法表 2008/3/18

#include <stdio.h> #include <stdlib.h> #define ROWS 4 /* 程式範例: Ch3-2-2.c */ #include <stdio.h> #include <stdlib.h> #define ROWS 4 #define COLS 5 /* 主程式 */ int main() { /* 宣告變數 */ int i, j; /* 建立int的二維陣列 */ int tables[ROWS][COLS]; int *ptr; /* 指定二維陣列的元素值 */ for ( i=0; i < ROWS; i++) for ( j=0; j < COLS; j++) tables[i][j] = (i+1)*(j+1); /* 顯示二維陣列的元素值 */ ptr = &tables[0][0]; for ( i=0; i < ROWS; i++) { for ( j=0; j < COLS; j++) printf("%d*%d=%2d ", (i+1), (j+1), *(ptr+(i*COLS)+j)); printf("\n"); } printf("%d*%d=%2d ", (i+1), (j+1), *(*(tables + i) + j)); system("PAUSE"); return 0; 2008/3/18

/* 程式範例: Ch3-2-2.c-1 */ /* 九九乘法表*/ 2008/3/18 #include <stdio.h> #include <stdlib.h> #define ROWS 9 #define COLS 9 /* 主程式 */ int main() { /* 宣告變數 */ int i, j; /* 建立int的二維陣列 */ int tables[ROWS][COLS]; int *ptr; /* 指定二維陣列的元素值 */ for ( i=0; i < ROWS; i++) for ( j=0; j < COLS; j++) tables[i][j] = (i+1)*(j+1); /* 顯示二維陣列的元素值 */ ptr = &tables[0][0]; for ( i=0; i < ROWS; i++) { printf("%d*%d=%2d ", (i+1), (j+1), *(ptr+(i*COLS)+j)); printf("\n"); } printf("%d*%d=%2d ", (i+1), (j+1), *(*(tables + i) + j)); system("PAUSE"); return 0; 2008/3/18

3-2-3 指標陣列-宣告 「指標陣列」(Arrays of Pointer)是指陣列的每一個元素都是一個指標變數 也就是說,陣列元素的值都是指向其它變數的位址。 指標陣列的宣告方式類似指標變數,如下所示: #define ROWS 4 int *tables[ROWS]; 上述程式碼宣告指標陣列tables[],一共擁有4個元素,每一個元素是一個整數的指標變數,可以指向整數或一個一維陣列, 如果都是指向5個元素的一維陣列,相當於是宣告一個4 X 5的二維陣列。 2008/3/18

3-2-3 指標陣列-差異 指標陣列和二維陣列的差異在 指標陣列並不能指定初值, 二維陣列在宣告後就配置ROWS X COLS個元素,指標陣列只配置ROWS個元素, 指標陣列的最大好處是每一個指標指向的變數可以是不同長度, 例如:不同元素分別指向整數或整數陣列。 2008/3/18

3-2-3 指標陣列-圖例 2008/3/18

3-2-3 指標陣列-存取 使用指標運算存取指標陣列的元素,如下所示: for ( i=0; i < ROWS; i++ ) { printf("*tables[%d]=%2d ", i, *tables[i]); printf("**(tables+%d)=%2d ", i, **(tables + i)); printf("**(ptr+%d)=%2d ", i, **(ptr + i)); } 上述for迴圈可以走訪指標陣列,然後使用*tables[i]、**(tables + i)和**(ptr + i)取得陣列元素的值。 2008/3/18

程式範例Ch3-2-3.c 程式目標 在C程式中宣告一個指標陣列和一維陣列, 將指標陣列的每一個元素指向一維陣列的元素, 然後用指標運算顯示出指標陣列的元素值!! 執行結果如下 **ptr=&tables[0]; *tables[0]=10 **(tables+0)=10 **(ptr+0)=10 位址=0022FF50 *tables[1]=4 **(tables+0)=4 **(ptr+0)=10 位址=0022FF54 *tables[2]=5 **(tables+0)=5 **(ptr+0)=10 位址=0022FF58 *tables[3]=19 **(tables+0)=19 **(ptr+0)=10 位址=0022FF5C 2008/3/18

#include <stdio.h> #include <stdlib.h> #define ROWS 4 /* 程式範例: Ch3-2-3.c */ #include <stdio.h> #include <stdlib.h> #define ROWS 4 /* 主程式 */ int main() { /* 宣告變數 */ int i; int values[ROWS] = { 10, 4, 5, 19 }; /* 建立int的指標陣列 */ int *tables[ROWS]; int **ptr = &tables[0]; /* 指向指標的指標變數 */ /* 指定指標陣列的元素值 */ for ( i=0; i < ROWS; i++) tables[i] = &values[i]; /* 取得陣列元素位址 */ /* 顯示指標陣列的元素值 */ printf("**ptr = &tables[0];\n"); for ( i=0; i < ROWS; i++ ) { printf("*tables[%d]=%2d ", i, *tables[i]); printf("**(tables+%d)=%2d ", i, **(tables + i)); printf("**(ptr+%d)=%2d ", i, **(ptr + i)); printf("位址=%p\n", tables[i]); } system("PAUSE"); return 0; 2008/3/18

3-3 指標與結構-宣告 指標也可以指向結構。 例如:宣告label結構儲存員工的姓名和年齡,如下所示: struct label { char name[20]; int age; }; 上述結構擁有2個成員變數 因為指標需要指向結構變數的位址,所以需要先宣告結構變數,然後才能建立指向結構的指標,如下所示: struct label worker; struct label *ptr; 2008/3/18

3-3 指標與結構-存取 接著將結構指標指向結構,如下所示: 結構指標ptr指向結構變數worker的位址, 換個方式,可以使用指標變數存取結構的成員變數,如下所示: (*ptr).age = 50; 程式碼相當於是worker.age = 50;。 C語言提供另一種語法,結構指標可以直接使用「->」運算子存取結構的成員變數,如下所示: ptr->age = 50; 2008/3/18

程式範例Ch3-3.c 程式目標 在C程式中宣告結構label儲存員工資料, 然後建立結構變數與指標, 分別使用結構變數與指標來存取成員變數!! 執行結果如下 姓名: 陳會安 年齡: 30 員工名牌 ------------ 2008/3/18

strcpy(worker.name, "陳會安"); ptr->age = 30; printf("員工基本資料\n"); /* 主程式 */ int main() { /* 宣告變數 */ struct label worker; struct label *ptr; /* 將結構指標指向結構 */ ptr = &worker; /* 指定結構的成員變數 */ strcpy(worker.name, "陳會安"); ptr->age = 30; printf("員工基本資料\n"); printf("姓名: %s\n", worker.name); printf("年齡: %d\n", worker.age); /* 呼叫函數 */ showlabel(ptr); system("PAUSE"); return 0; } /* 程式範例: Ch3-3.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* 結構label的宣告 */ struct label { char name[20]; int age; }; /* 函數: 顯示結構指標的成員變數 */ void showlabel(struct label *ptr) { printf("--------------------\n"); printf("員工名牌\n"); printf("姓名: %s\n", ptr->name); printf("年齡: %d\n", ptr->age); printf("------------------\n"); } 2008/3/18

3-4 指標與字串 3-4-1 指標與字串 3-4-2 字串的指標陣列 2008/3/18

3-4 指標與字串 在C語言的字串是一種字元陣列,指標運算也一樣適用在字元陣列的字串。 例如:宣告一個字元陣列來儲存字串,其宣告如下所示: char line[80]; 存取字元陣列元素是使用line[0]、line[1]~line[79]來存取,如下所示: line[i] = c; 在字元陣列的結束加上字元'\0'當作結束字元,如下所示: line[i] = '\0'; 2008/3/18

3-4-1 指標與字串 字串指標是一個char資料型態的指標,可以用來指向字元陣列或字串常數。 宣告一個字元陣列的字串,如下所示: #define LEN 16 char str[LEN] = "This is a book."; 上述字元陣列是一個字串且指定初值,接著宣告指標變數指向此字串,如下所示: char *ptr = str; 2008/3/18

程式範例Ch3-4-1.c 程式目標 在C程式中宣告指標變數分別指向字元陣列的字串與字串常數, 然後使用指標運算來複製字串內容!! 執行結果如下 str = This is a book. ptr = This is a book. ptr1 = This is a book. 將字串str複製到str1: str1 = This is a book. 2008/3/18

#include <stdio.h> #include <stdlib.h> #define LEN 16 /* 程式範例: Ch3-4-1.c */ #include <stdio.h> #include <stdlib.h> #define LEN 16 /* 主程式 */ int main() { /* 字元陣列宣告 */ char str[LEN] = "This is a book."; char str1[LEN]; /* 字元指標 */ char *ptr = str; char *ptr1; int i; /* 顯示字串內容 */ ptr1 = "This is a pen."; printf("str = %s\n", str); printf("ptr = %s\n", ptr); printf("ptr1 = %s\n", ptr1); /* 字串複製的迴圈 */ printf("將字串str複製到str1: \n"); i = 0; ptr1 = str1; while ( *ptr != '\0' ) { *(ptr1+i) = *ptr++; i++; } *(ptr1+i) = '\0'; printf("str1 = %s\n", str1); printf("ptr1 = %s\n", ptr1); system("PAUSE"); return 0; 2008/3/18

3-4-2 字串的指標陣列-說明 C語言的指標陣列最常是應用在字串的指標陣列,如下所示: #define ROWS 4 char *name[ROWS] = { "陳會安", "江小魚", "張無忌", "楊過" }; 2008/3/18

3-4-2 字串的指標陣列-字串交換 使用指標陣列來儲存字串, 不只可以節省記憶空間,而且因為是指標,如果指標陣列的元素需要交換字串,只需更改指標指向的字串即可,如下圖所示: 2008/3/18

程式範例Ch3-4-2.c 程式目標 執行結果如下 在C程式中宣告二維字元陣列和字串的指標陣列儲存數個字串, 然後使用巢狀迴圈顯示各字串!! 顯示二維字元陣列的內容 names[0]=[ 陳會安 ] names[1]=[ 江小魚 ] names[2]=[ 張無忌 ] names[3]=[ 楊過 ] 顯示指標陣列的內容 name[0]=[ 陳會安] name[1]=[ 江小魚] name[2]=[ 張無忌] name[3]=[ 楊過] 2008/3/18

printf("--------------------\n"); printf("顯示指標陣列的內容: \n"); /* 顯示指標陣列的元素值 */ printf("--------------------\n"); printf("顯示指標陣列的內容: \n"); for ( i = 0; i < ROWS; i++ ) { printf("name[%d] =[", i); ptr = name[i]; /* 取得每一個指標 */ for ( j = 0; *(ptr+j) != '\0'; j++) printf("%c", *(ptr+j)); printf("]\n"); } system("PAUSE"); return 0; /* 程式範例: Ch3-4-2.c */ #include <stdio.h> #include <stdlib.h> #define ROWS 4 #define COLUMNS 10 /* 主程式 */ int main() { /* 宣告變數 */ int i, j; /* 建立二維的字元陣列且指定初值 */ char names[ROWS][COLUMNS] = { "陳會安", "江小魚", "張無忌", "楊過" }; /* 指標陣列 */ char *name[ROWS] = { "陳會安", "江小魚", "張無忌", "楊過" }; char *ptr; /* 顯示二維陣列的元素值 */ printf("顯示二維字元陣列的內容: \n"); for ( i = 0; i < ROWS; i++ ) { printf("names[%d]=[", i); ptr = names[i]; for ( j = 0; j < COLUMNS; j++) printf("%c", *(ptr+j)); printf("]\n"); } 2008/3/18

3-5 指標的應用 - 字串處理(說明) C語言的字串並不是一種基本資料型態,而是一種字元陣列 所以並沒有支援指定、連結和比較等運算子 取而代之的是在標準函式庫<string.h>提供多種字串處理函數。 接下來, 將討論一些基本字串函數的實作,著重於說明如何設計這些字串函數所需的程式技巧,這些技巧都屬於指標的應用。 2008/3/18

3-5 指標的應用 - 字串處理(標頭檔) 01: /* 程式範例: Ch3-5.h */ 02: char str[81]; /* 儲存字串的字元陣列 */ 03: /* 抽象資料型態的操作函數宣告 */ 04: extern int strLen(char *str); 05: extern char *strCpy(char *dest, char *source); 06: extern char *strCat(char *dest, char *source); 07: extern int strCmp(char *source, char *target); 08: extern char *strPos(char *source, char *target); 2008/3/18

3-5 指標的應用 - 字串處理(1) 函數strLen():取得字串長度 字串是一個字元陣列 計算字串長度的方法就是一維陣列的走訪和指標的遞增運算,如下所示: char *ptr = str; while ( *ptr != '\0' ) ptr++; return ptr - str; 上述程式碼使用while迴圈走訪到字串的最後1個字元,然後使用ptr-str指標減法運算取得字串長度。 2008/3/18

strlen() #include <string.h> size_t strlen(const char *s); //傳進來的常數不可改變內容 計算字串的長度,其單位長度以一個byte為單位,但不包括’\0’這個字元. 2008/3/18

輸入一個字串, 計算出該字串的長度 #include <string.h> #include <stdio.h> #include <stdlib.h> int main() { char fun[80]; int a; printf("請你輸入一字串:\n"); gets(fun); a=strlen(fun); printf("\n此字串長度為: %d",a); system("pause"); return 0; } 2008/3/18

3-5 指標的應用 - 字串處理(2) 函數strCpy():字串複製 字串複製是將字串內容複製到其它的字元陣列,其目的是為了保留原始字串,以避免執行其它字串處理時,更改到原始字串的內容。如下所示: char *ptr = dest; while ( (*ptr++=*source++) != '\0' ); return dest; 上述程式碼使用while迴圈複製字串,因為先執行*ptr++=*source++指定運算,再進行比較,所以連原始字串的結束字元也會複製到新字串。 2008/3/18

strcpy() #include <string.h> char *strcpy(char *dest, const char *src); 將src字串內容複製到dest字串中(包含空字元). 2008/3/18

使用者輸入一個字串,程式會將該字串覆蓋原程式內定的字串 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char target[30]="Hello Everyone",input[30]; printf("請你輸入一字串:"); gets(input); printf("原先的內定字串的內容為: %s\n",target); strcpy(target,input); printf("拷貝過後的字串內容: %s",target); system("pause"); return 0; } 2008/3/18

3-5 指標的應用 - 字串處理(3) 函數strCat():字串連結 字串連結是將兩個字串結合成一個字串,也就是從第1個字串的最後開始複製第2個字串。 字串連結函數是結合字串長度和複製函數,如下所示: while ( *ptr++ != '\0' ); ptr--; 上述程式碼使用while迴圈走訪到字串的最後1個的結束字元 然後就使用迴圈複製字串,如下所示: while ( (*ptr++=*source++) != '\0' ); 2008/3/18

strcat() #include <string.h> char *strcat(char *dest, const char *src); 將src字串內容連結到dest字串的結尾,覆蓋src字串的空字元’\0’,並且保留本身的’\0’. . 2008/3/18

使用strcat()函數,將兩個字串合併為一,並且將之輸出 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char first[20]="Hello "; char last[]="Bill"; printf("合併前 first: %s last : %s\n",first,last); strcat(first,last); printf("合併後 first: %s last : %s",first,last); system("pause"); return 0; } 2008/3/18

3-5 指標的應用 - 字串處理(4) 函數strCmp():字串比較 字串比較是比較兩個字串的內容 如果兩個字串完全相同的話,就傳回0,如果不相同,使用ASCII的字元碼比較不同的哪一個字元。 函數是使用迴圈從頭開始比較兩個字串中的每一個字元,如下所示: for ( ; *source == *target; source++, target++) if ( *source == '\0') return 0; 如果不相等,接著比較最後不相等的兩個字元來決定字串大小,如下所示: if ((*source-*target) < 0 ) return -1; else return 1; 2008/3/18

strcmp() 比較字串 #include <string.h> int strcmp(const char *s1, const char *s2); 比較兩個字串str1跟str2,比較其內容是否相同,若相同,則傳回0; 若不同,則比較兩個字串第一個不同字元的ASCII碼,若str1>str2,則傳回正數,反之,則傳回負數. 2008/3/18

設計一個程式,檢查輸入的字串是否相同 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char input1[30]; char input2[30]; int a; printf("請輸入第一個字串 "); gets(input1); printf("請輸入第二個字串 "); gets(input2); a=strcmp(input1,input2); //比較字串 if(a==0) puts("你輸入的兩個字串是相同的!"); else puts("你輸入的是不相同的字串!"); system("pause"); return 0; } 2008/3/18

3-5 指標的應用 - 字串處理(5) 函數strPos():子字串的搜尋 子字串的搜尋是指在原始字串中找尋某特定字串是否存在 如果存在,這個特定字串就是原始字串的子字串。 函數使用二層的巢狀迴圈來執行字串比較,如下所示: while ( *s != '\0' ) { ptr = s; t = target; while ( *t != '\0' && *ptr == *t ) { ptr++; t++; } if ( *t == '\0' ) return s; s++; 2008/3/18