阵 列 与 指 标
l l 何谓数组 ( Array)
1. 1. 有限个相同数据型态之元素组成之集合
2. 2. 一大块连续之内存
3. 3. 一组索引与数据对映
l 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]=1 number[1]=2 number[2]=3 number[3]=4 number[4]=5 number[5]=6 number[6]=7 number[7]=8 number[8]=9 number[9]=10 1+2+3+4+5+6+7+8+9+10=55 |
l 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[i][j] != 0 ) /* 检查有没有课 */ sum++; printf("课程总数: %d/n",sum); /* 印出课程总数 */ } |
l l 阵 列 表 示 法
数组之表示法有两种:
1. 1. 以列为主或行为主之表示法
2. 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. 1. 以列为主:i*c+j
2. 2. 以行为主:j*r+i
l 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 l 阵 列 与 基 本 输 出 / 输 入 函 数 的 搭 配
无 论 是 整 数 , 浮 点 数 或 字 元 阵 列 (字符串 ) 均 可 与 基 本 输 出 / 输 入 函 数 的 搭 配 . 例 如 一 名 叫 array1 的 字 元 阵 列 :
printf("%s/n",array1);
puts(array1);
scanf("%s",array1);
gets(array1);
所 以 USER 可 以 自 行 参 考 相 关 的 章 节 使 用 之 . 在 此 补 充 一 点 , 上 述 所 叙 述 scanf 函 数 是 乎 少 一 个 & (地址操作数 ) ? ? ? 没 错 ! 那 是 因 为阵 列 本 身 的 名 称 即 代 表 其 位 址 之 所 在 , 所 以 不 需 在 阵 列 名 称 前 加 上 & 符 号 来 代 表 位 址 .
l l 指 标 ( Pointer )
何谓 指 标 呢 ? 简 单 的 说 " 它 是 一 个 用 来 指 示 资 料 存 在 于 记 忆 体 中 的 位 址 标 示 器 " , 简 称 指 标 . 由指 标 的 运 用 里 , 使 我 们 瞭 解 到 资 料 与 位 址 间 的 关 系 , 进 而 对 记 忆 体 配 置 有 很 大 的 帮 助 .
l l 指 标 的 基 本 观 念
<1>在 C 语 言 中 , 若 某 变 数 所 含 的 是 一 个 记 忆 体 地址,此 变 数 称 为 指 标 变 数。如 下 图 所 示
<2> 在 C 语 言中 , 指 标 变 数 的 宣 告 方 式 如 下 :
变量数据型态 *变量名称 ;
For example int *ptr ;
如 下 图 所 示
|
ptr为 指 标 变 数 |
|
|
|
|
® 变数ptr ® |
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 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 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)=1 array[1]=2 <--> *(array+1)=2 array[2]=3 <--> *(array+2)=3 array[3]=4 <--> *(array+3)=4 array[4]=5 <--> *(array+4)=5
|
l 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)=P string[1]=O <--> *(string+1)=O string[2]=I <--> *(string+2)=I string[3]=N <--> *(string+3)=N string[4]=T <--> *(string+4)=T string[5]=E <--> *(string+5)=E string[6]=R <--> *(string+6)=R |
l l 指 标 与 阵 列 的 混 合 应 用
指标之运算有两种: (+) 、 (-) 。
|
假设指针ptr所指数据为整数,且其为指为1666 |
指令 |
执行结果 |
执行动作 |
|
ptr++ |
1668 |
指向下一个整数地址 | |
|
ptr-- |
1664 |
指向前一个整数地址 | |
|
ptr+7 |
1676 |
指向第七个整数地址 |
本文详细介绍了数组的概念、声明及应用,并深入解析了一维数组、二维数组和字符数组的特点。同时,文章还探讨了指针的基本概念及其与数组、字符串之间的关系。
13万+

被折叠的 条评论
为什么被折叠?



