查看: 3378|回復: 0
打印 上一主題 下一主題

[教學] C的陣列跟指標

[複製鏈接]
跳轉到指定樓層
1#
發表於 2007-9-4 08:57:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
何謂陣列 ( Array)1.
有限個相同資料型態之元素組成之集合
2.
一大塊連續之記憶體
3.
一組索引與資料對映
l
一
維
陣
列
<1> 一 維 陣 列 的 宣 告 方 式 如 下 所 述 :



陣列的資料型態
陣列的名稱 [ 陣列的大小 ]
;
int


array1 [ 20 ] ;


float
array2 [ 25 ] ;


char
array3 [ 50 ] ; <2> 宣 告 陣 列 的 位 置 為 程 式 之 最 上 端 .

<3> 一 維 陣 列 的 排 列 結 構 如 下 圖 所 述 . 我 們 舉 例 一 陣 列 名 叫 A 的 陣 列 , 其 陣 列 大 小 有 n 個 , 即 為 A[n] .


範例:有一陣列宣告如下:int


A[ 20 ] ;

陣列名稱®

A[0]

A[1]

A[2]

.....

A[19]

記憶體®

記憶體位址®

m


(陣列第一元素之位址)

m+2

m+4

m+2*(19)


<4> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 數 值 給 陣 列 . 例 如 :


陣列的資料型態
陣列的名稱 [ 陣列的大小 ]= {
´´,´´,…´´}; 範例: int score[5]={ 2, 5, 7 ,9 ,10 };

陣列名稱®

score[0]

score[1]

score[2]

score[3]

score[4]

記憶體®

2

5

7

9

10


Example: #include < stdio.h >

void main(void)
{

int count,total=0;
int number[10]={ 1,2,3,4,5,6,7,8,9,10 };
for( count=0 ; count < 10 ; ++count ){printf("number[%d]=%d\n",count,number[count]);
total=total + number[count];}printf("1+2+3+4+5+6+7+8+9+10=%d\n",total);
}



執 行 結 果 :

number[0]=1number[1]=2number[2]=3number[3]=4number[4]=5number[5]=6number[6]=7number[7]=8number[8]=9number[9]=101+2+3+4+5+6+7+8+9+10=55
l

二
維
陣
列
<1>
二
維
陣
列
的
宣
告
方
式
如
下
所
述 :

陣列的資料型態
陣列的名稱[ 列陣列的大小 ][ 行陣列大小 ] ;
For example:

int
array1 [ 10 ][ 20 ] ;


float
array2 [ 5 ][ 25 ] ;


char
array3 [ 100 ][ 50 ] ;

<2> 宣
告
陣
列
的
位
置
為
程
式
之
最
上
端 .

<3> 二
維
陣
列
的
排
列
結
構
如
下
圖
所
述 . 我
們
舉
例
一
陣
列
名
叫 A 的
陣
列 , 其
列
陣
列
大
小
有 m 個 , 行
陣
列
大
小
有 n 個 , 即
為 A[m][n] .


行 (column)

列
A[0][0] A[0][1] A[0][2] ...... A[0][n-1]
(row) A[1][0] A[1][1] A[1][2] ...... A[1][n-1]
A[2][0] A[2][1]
A[2][2] ...... A[2][n-1]
.
.
.
.
.
.

.
.
.
.
A[m-1][0] A[m-1][1] A[m-1][2] A[m-1][n-1]
<4> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 數 值 給 陣 列 . 例 如 :
int score1[2][5]={{ 1, 2, 3, 4, 5 },{ 5, 4, 3, 2, 1 }};
或
是
在
程
式
過
程
中
指
定
數
值
給
陣
列 . 例
如 :



void main(void)


{

int score1[2][5];
/* 陣列宣告 */

score1[0][0]=1;
/* 程式本體 */

score1[0][1]=2;

score1[0][2]=3;

score1[0][3]=4;

score1[0][4]=5;


score1[1][0]=5;

score1[1][1]=4;

score1[1][2]=3;

score1[1][3]=2;

score1[1][4]=1;

……

}

【實例探討】某學生之功課表如下,(每個課程名稱皆以代碼表示)
一 二 三 四 五
1 2 2
2 1 4 1 4 1
3 5 5 5
4
5 3 3 3
6
課程名稱 代碼
計算機概論 1
離散數學 2
資料結構 3
資料庫概論 4
上機實習 5
此課表可以以一個二維陣列表示,其宣告方式如下:
int course [6][5];

記憶體位址

記憶體

a (陣列起始位址)

course [0][0]

a + 2

course [0][1]

a + 4

course [0][2]

a + 4

course [5][3]

a + 4

course [5][4]

此課表之抽象表示如下:
(0,0) (0,1) (0,2) (0,3) (0,4)
(1,0) (1,1) (1,2) (1,3) (1,4)
(2,0) (2,1) (2,2) (2,3) (2,4)
(3,0) (3,1) (3,2) (3,3) (3,4)
(4,0) (4,1) (4,2) (4,3) (4,4)
(5,0) (5,1) (5,2) (5,3) (5,4)

/* ================================================== *//*
程式實例: 查詢上課的課目,其中課程以代碼表示.
*/
/*


0 表示沒課
*/
/*


1 表示計算機概論
*/
/*


2 表示離散數學
*/
/*


3 表示資料結構
*/
/*


4 表示資料庫概論
*/
/*

5 表示上機實習;
*/
/* ==================================================*/void main(){
int course[6][5] = { 0, 2, 0, 2, 0,
/* 課程定義
*/

1, 4, 1, 4, 1,

5, 0, 5, 0, 5,

0, 0, 0, 0, 0,

3, 0, 3, 0, 3,

0, 0, 0, 0, 0 };

int week;



/* 星期資料變數
*/

int class;


/* 第幾節課的變數 */

int class_no;
/* 課程代碼變數
*/

printf("請輸入星期(1 到 5). ==> ");

scanf("%d",&week);
/* 讀取星期資料
*/

printf("請輸入第幾節課(1 到 6). ==> ");

scanf("%d",&class);
/* 讀取第幾節課
*/

class_no = course[class-1][week-1];
/* 課程查詢
*/

switch ( class_no )
/* 印出課程名稱
*/

{

case 0: printf("這節沒課\n");

break;

case 1: printf("計算機概論\n");

break;

case 2: printf("離散數學\n");

break;

case 3: printf("資料結構\n");

break;

case 4: printf("資料庫概論\n");

break;


case 5: printf("上機實習\n");

break;

}
}
/* ======================================== *//*
計算出一星期的課程總數
*/
/* ======================================== */ void main(){
int course[6][5] = { 0, 2, 0, 2, 0,
/*課程定義
*/

1, 4, 1, 4, 1,


5, 0, 5, 0, 5,

0, 0, 0, 0, 0,

3, 0, 3, 0, 3,

0, 0, 0, 0, 0 };

int sum;
/* 課程總數 */

int i,j;

sum = 0;

/* 設定課程總數初值 */

for ( i = 0; i < 6; i++ )
/* 二維陣列的走訪
*/

for ( j = 0; j < 5; j++ )

if ( course[j] != 0 )
/* 檢查有沒有課 */

sum++;

printf("課程總數: %d\n",sum);
/* 印出課程總數 */
}

l
陣
列
表
示
法
陣列之表示法有兩種:
1.
以列為主或行為主之表示法
2.
使用指標陣列 (指標單元再介紹)
à
以列為主或以行為主之表示法
行
列 (0,0) (0,1) (0,2) (0,3) (0,4) 列一
(1,0) (1,1) (1,2) (1,3) (1,4) 列二
(2,0) (2,1) (2,2) (2,3) (2,4) 列三
(3,0) (3,1) (3,2) (3,3) (3,4) 列四
(4,0) (4,1) (4,2) (4,3) (4,4) 列五
(5,0) (5,1) (5,2) (5,3) (5,4) 列六
行一 行二 行三 行四 行五

陣列共有6*5=30元素。然而,記憶體實際以宣告一個長度為30之一維陣列儲存之,其宣告方式如下:
int class [30];以列為主所見之陣列表示方式如下:

列一 列二 列六
(0,0) (0,1) (0,2) (0,3) (0,4) (1,0) (1,1) (1,2) (1,3) (1,4) … (5,0) (5,1) (5,2) (5,3) (5,4)
0 1 2 3 4 5 6 7 8 9 25 26 27 28 29


以行為主所見之陣列表示方式如下:

行一 行二 行六
(0,0) (1,0) (2,0) (3,0) (4,0) (5,0) (0,1) (1,1) (2,1) (3,1) (4,1) (5,1) … (0,4) (1,4) (2,4) (3,4) (4,4) (5,4)
0 1 2 3 4 5 6 7 8 9 10 11 24 25 26 27 28 29

【公式】:假設有一二維陣列A[r,c] 之大小為r*c,則此二維陣列A[i,j]以一維陣列表示之索引值為:

1.
以列為主:i*c+j

2.
以行為主:j*r+i



l
字
元
陣
列
<1> 字 元 陣 列 的 宣 告 方 式 如 下 所 述 :


char
陣列的名稱 [ 陣列的大小 ] ;
or
char
陣列的名稱 [ 列陣列的大小 ][ 行陣列大小 ] ;
For example:
char
array1 [ 10 ] ;


char
array2 [ 5 ][ 25 ] ;

<2> 宣 告 陣 列 的 位 置 為 程 式 之 最 上 端 .
<3> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 字 元 給 陣 列 . 例 如 :





例一 :
int string[6]={'A','B','C','D','E','\0'};

或
int string[5]="ABCDE";

例二 :
int string1[2][6]={{'A','B','C','D','E','\0'},

{'F','G','H','I','J','\0'};


或
int string1[2][5]={ "ABCDE","FGHIJ" };

或 是 在 程 式 過 程 中 指 定 數 值 給 陣 列 . 例 如 :




void main(void)



{

int string[6];
/* 陣列宣告 */

.

.

score1[0]='M';
/* 程式本體 */

score1[1]='E';

score1[2]='R';

score1[3]='R';

score1[4]='Y';

score1[5]='\0';

strcpy(string,"MERRY"); /* 將 "MERRY" 字串拷貝至

string 陣列中 */


.

}


<4> 由 於 以 上 敘 述 , 我 們 知 道 如 果 字 元 陣 列 以 字 元 的 方 式 來 存 取 陣 列 , 則 須 加 結 束 字 元 \0 於 陣 列 的 最 末 端 , 表 示 此 字 元 陣 列 的 結 束 . 例 如 <3> 項 例 一 所 述 . 如 果 字 元 陣 列 以 字 串 的 方 式 來 存 取 陣 列 , 則 C 編 譯 器 會 自 動 在 字 串 最 末 端 加 上 結 束 字 元 \0 表 示 此 字 元 陣 列 的 結 束 , 所 以 我 們 不 需 自 行 加 入 . 例 如 <3> 項 例 二 所 述 . ( \0 表 式 零 的 八 進 位 數 )


Example: #include < stdio.h > void main(void){
char string1[5]={'A','B','C','D','E'};
char string2[6]={'A','B','C','D','E','\0'};char string3[6]="ABCDE\0";char string4[5]="ABCDE"; printf("string1 = \"%s\"\n",string1);printf("string2 = \"%s\"\n",string2);printf("string3 = \"%s\"\n",string3);printf("string4 = \"%s\"\n",string4);}
執 行 結 果 : string1="ABCDE?ABCDE" string2 = "ABCDE" string3 = "ABCDE" string4 = "ABCDE"

l
陣
列
與
基
本
輸
出 / 輸
入
函
數
的
搭
配
無 論 是 整 數 , 浮 點 數 或 字 元 陣 列 (字串 ) 均 可 與 基 本 輸 出 / 輸 入 函 數 的 搭 配 . 例 如 一 名 叫 array1 的 字 元 陣 列 :
printf("%s\n",array1);


puts(array1);

scanf("%s",array1);

gets(array1);
所 以 USER 可 以 自 行 參 考 相 關 的 章 節 使 用 之 . 在 此 補 充 一 點 , 上 述 所 敘 述 scanf 函 數 是 乎 少 一 個 & (位址運算元 ) ? ? ? 沒 錯 ! 那 是 因 為陣 列 本 身 的 名 稱 即 代 表 其 位 址 之 所 在 , 所 以 不 需 在 陣 列 名 稱 前 加 上 & 符 號 來 代 表 位 址 .

l
指
標 ( Pointer )
何謂 指 標 呢 ? 簡 單 的 說 " 它 是 一 個 用 來 指 示 資 料 存 在 於 記 憶 體 中 的 位 址 標 示 器 " , 簡 稱 指 標 . 由指 標 的 運 用 裡 , 使 我 們 瞭 解 到 資 料 與 位 址 間 的 關 係 , 進 而 對 記 憶 體 配 置 有 很 大 的 幫 助 .
l
指
標
的
基
本
觀
念
<1>在 C 語 言 中 , 若 某 變 數 所 含 的 是 一 個 記 憶 體 位址,此 變 數 稱 為 指 標 變 數。如 下 圖
所
示
<2> 在 C 語 言中 , 指 標 變 數 的 宣 告 方 式 如 下 :



變數資料型態
*變數名稱 ;
For example

int
*ptr ;
如 下 圖
所
示

ptr為 指 標 變 數

®

變數pt
r
®
1010 H

0800H

0802H

…..

…

1010H

16 ¬*ptr

記憶體


由
以
上
的
宣
告 , 表
示
了
三
件
事:
l
ptr 為
指
標
變
數
, ptr 代
表
一
個
位
址 ,
l
*ptr 代
表
此
位
址
內
的
資
料 .
l
ptr 所
指
向
此
位
址
之
變
數
型
態
為
整
數 ( int ) .

<3> 指
標
變
數
宣
告
的
關
鍵
字
為 " * " , 而
指
標
變
數
的
資
料
型
態
也
分
為
整
數 ( int ) , 浮
點
數 ( float ) , 字
元 ( char ) 三
種 .

<4> "&" 為另一重要符號,"&"為一個特殊運算子,目的為傳回運算元之位址

<5>為什麼scanf()
中之所有引數變數一定要加上"&"符號???……….

Example: #include < stdio.h >
void main(void){int x=10;int *y;y=&x;printf(" x = %d\n", x);printf("&x = %x\n",&x);printf("*y = %d\n",*y);printf(" y = %x\n", y);}
執行結果 :
x = 10

&x = ffda

*y = 10

y = ffda


l
指
標
與
函
數
間
的
關
係
關於 函 數 呼 叫 的 方 式 中 , Call by value 的 引 數 傳 遞 方 式 , 被 呼 叫 函 數 不 能直 接 更 改 呼 叫 函 數 中 的 變 數 , 但 如 果 是 以 指 標 當 作 函 數 的 引 數 ( Call by reference ) , 則上 述 的 狀 況 均 迎 刃 而 解 , 而 且 也 不 受 函 數 返 回 值 ( return ) 只 能 有 一 個 的 影 響 .
Example: #include < stdio.h > change(x,y)
int *x,*y;
{int temp;
temp=*x;
*x=*y;*y=temp;
} void main(void){
int m=3,n=4;printf(" m = %d
n= %d \n\n",m,n);printf(" m = %d
n= %d \n\n",m,n);
change(&m,&n);
printf(" m = %d
n= %d \n",m,n);
}
執行結果 : m = 3
n= 4
m = 4
n= 3

l
指
標
與
陣
列
的
關
係
我們 可 以 將 指 標 與 陣 列 的 關 係 來 做 一 對 比 . 例 如 : 有 一 整 數 陣 列 名 為 array , 其 陣 列 大 小 為 五 個 , 其 內 容 分 別 是 1,2,3,4,5 .

For example:
int array[5]={ 1,2,3,4,5 };

陣列位址 指標相對位址
array[0] 1 *(array+0)
array[1] 2 *(array+1)
array[2] 3 *(array+2)
array[3] 4 *(array+3)
array[4] 5 *(array+4)

Example: #include < stdio.h >
void main(void)
{
int array[5]={ 1,2,3,4,5 };
int count;
for ( count=0 ; count<5 ; ++count )
printf("array[%d]=%d<-->*(array+%d\)=%d\n",count,array[count], count,*(array+count));
}
執行結果 : array[0]=1 <--> *(array+0)=1array[1]=2 <--> *(array+1)=2array[2]=3 <--> *(array+2)=3array[3]=4 <--> *(array+3)=4array[4]=5 <--> *(array+4)=5

l
指
標
與
字
元
陣
列 ( 字
串 ) 間
的
關
係

Example: #include < stdio.h > void main(void)
{
char string[7]="POINTER";
int count;
for (count=0 ; count<7 ; ++count )
printf("string[%d]=%c <-->
*\(string+%d\)=%c\n",
count, string[count],
count,*(string+count)); }
執行結果 :  string[0]=P <--> *(string+0)=Pstring[1]=O <--> *(string+1)=Ostring[2]=I <--> *(string+2)=Istring[3]=N <--> *(string+3)=Nstring[4]=T <--> *(string+4)=Tstring[5]=E <--> *(string+5)=Estring[6]=R <--> *(string+6)=R

l
指
標
與
陣
列
的
混
合
應
用
指標之運算有兩種: (+) 、 (-) 。
假設指標ptr所指資料為整數,且其為指為1666 指令 執行結果 執行動作
ptr++ 1668 指向下一個整數位址
ptr-- 1664 指向前一個整數位址
ptr+7 1676 指向第七個整數位址


您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2026-10-20 14:31 , Processed in 0.042227 second(s), 15 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表