1清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础乔 林计算机程序设计基础
Email,qiaolin@cic.tsinghua.edu.cn
Tel,62792961
2清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础第四章 复合数据结构基础
学习目标
– 掌握数组定义与基本使用方法,熟悉字符型数组概念
– 掌握指针基本概念,能熟练使用指针操作基本数据对象,
掌握指针基本运算,了解指针与数组的关系
– 掌握结构体类型的声明、结构体变量的定义与基本用法,
能在程序中熟练使用结构体
– 掌握联合体类型的声明、联合体变量的定义与基本用法,
能在程序中熟练使用联合体
– 掌握枚举类型的概念、定义与使用方法
– 了解自定义类型的定义与使用方法
3清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.1 数组及其应用
一维数组
多维数组
字符数组的应用
4清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组的定义与格式
一维数组的定义:相同类型的一系列数据
– 数据类型 数组名 [元素个数 ];
– 例,int a[8];
关于数组定义的几点说明
– 数组声明中的方括号不能使用小括号代替
– 数组元素个数必须为整型常量或编译期可计算的常量表达式,不能为变量
– 数组元素下标从 0开始编号,数组元素个数必须大于 1
– 系统不检查数组下标,注意数组下标是否超出定义范围!
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
5清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组的初始化
初始化格式:相同类型的一系列数据
– 数据类型 数组名 [元素个数 ] = {值 1,值 2,<,值 n};
– 例,int a[8] = {10,20,30};
关于数组初始化的几点说明
– 花括号中数据序列表示数组初始值,以逗号分隔
– 数组元素的初始化从第 0个元素开始;若初始值数目少于数组元素个数,则后继元素未初始化;若中间部分元素无需初始化,则应使用逗号分隔(系统默认为 0)
– 数组定义与初始化场合,可省略方括号中的元素个数说明,系统自动将其设为初始化值的个数
10 20 30
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
6清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例一
输入一个含有 12个浮点数的一维数组,分别计算数组中所有正数与所有负数的和
#include <stdio.h>
int main()
{
float data[12];
float result1 = 0.0,result2 = 0.0;
int i;
printf(?Please input 12 floats:\n?);
for(i = 0; i < 12; i++) scanf(?%f?,&data[i]);
for(i = 0; i < 12; i++){
if(data[i] > 0.0) result1 += data[i]; else result2 += data[i];
}
printf(?Positives,%f\nNegatives,%f\n?,result1,result2);
return 0;
}
实际为数组元素遍历问题:使用循环,从头至尾搜索整个数组数组经常与循环联系在一起,这是因为数组下标的变化与循环控制变量是一致的
7清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例二
使用冒泡法对 5个整数按从大到小的顺序排列利用冒泡法进行排序,5个数分别位于不同层。要使大数在顶层小数在底层,小数应下降,大数应上升。最大数上升到顶层最多需要“冒泡” 4次,其中每一次称为一趟。而在每一趟中,最小数不断下降,因为每次只交换相邻两个层面的数据,所以每一趟内的执行次数不大于 4次,并会随着趟数的增加不断减少。
1
7
12
16
20
7
1
12
16
20
7
12
1
16
20
7
12
16
1
20
7
12
16
20
1
12
16
20
7
1
16
20
12
7
1
20
16
12
7
1
一趟 二趟 三趟 四趟
8清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例二
使用冒泡法对 5个整数按从大到小的顺序排列
#include <stdio.h>
int main()
{
int i,j,temp;
static int a[5] = {1,7,12,16,20};
for(i = 0; i < 4; i++)
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;
}
}
for(j = 0; j < 5; j++) printf(?a[%d] = %d\n?,j,a[j]);
return 0;
}
9清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组的定义与格式
多维数组的定义:相同类型的一系列数据
– 数据类型 数组名 [常量表达式 1][常量表达式 2+<;
– 例,int a[2][8];
关于多维数组定义的几点说明
– 数据顺序存放,先存第一行,再存第二行
– 只能引用元素,不能引用整体数组,如不能整体赋值
– 系统不检查数组下标,注意数组下标是否超出定义范围!
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] a[1][5] a[1][6] a[1][7]
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[0][5] a[0][6] a[0][7]
10清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组的初始化
按数据元素的存放顺序依次初始化每个元素
– 例,int a[2][8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
按其维度分别初始化:相当于降维处理
– 例,int a[2][8] = {{0,1,2,3,4,5,6,7},{8,9,10,11,12,13,14,15}};
8 9 10 11 12 13 14 15
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] a[1][5] a[1][6] a[1][7]
0 1 2 3 4 5 6 7
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[0][5] a[0][6] a[0][7]
11清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组示例
用户输入一个 4× 4的整数矩阵,编写程序求其两对角线上元素的和
#include <stdio.h>
int main()
{
int matrix[4][4],i,j,result1 = 0,result2 = 0;
for(i = 0; i < 4; i++){
printf(?Line %d,?,i);
for(j = 0; j < 4; j++){
scanf(?%d?,&matrix[i][j]);
if(i == j) result1 += matrix[i][j]; if( i + j == 3 ) result2 += matrix[i][j];
}
}
printf(?Results,%d,%d\n?,result1,result2);
return 0;
}
12清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础字符型数组的应用
字符型数组:元素类型为字符的数组
– 常用于存放字符串
– 二维字符数组:元素类型为字符串的一维数组
初始化
– 使用数组形式,char s*6+ =,‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’};
– 使用字符串形式,char s*6+ =?Hello?;
字符型数组的输入输出
– putchar(),getchar(),printf(),scanf()
13清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础字符型数组示例
编写程序,将两个字符串中的字符拼接起来
#include <stdio.h>
int main()
{
char str0[41],str1[21]; // 定义字符型数组,存放两个字符串
int j,k; // 定义两个循环因子
printf(?Please input the first string:\n?);
scanf(?%s?,str0);
printf(?Please input the second string:\n?);
scanf(?%s?,str1);
for(j = 0; str0[j+ != ‘\0‘; j++) ; // 搜索到 str0的结尾处
for(k = 0; str1[k+ != ‘\0‘; k++,j++) // 将 str1中字符拷贝到 str0后面
str0[j] = str1[k];
str0[j+ = ‘\0‘; // 添加字符串结尾标志
printf(?%s?,str0);
return 0;
}
14清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.2 指针及其应用
指针的基本概念与定义
指针的初始化
指针运算
使用指针操作基本数据对象
使用指针操作数组
15清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的基本概念与定义
指针是一种数据类型
– 格式,目标数据对象的数据类型 *指针变量名 ;
– 例,int *p; float *q; char *s;
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s
多个指针变量声明指针
– 每个变量名前都需使用指针符号
– 例,int *p,*q;
16清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针数据对象与目标数据对象
指针数据对象
– 指针变量:指针数据类型定义的变量(数据对象)
– 指针变量的值:内存地址值,一般为其他数据对象地址
目标数据对象:指针所指向的数据对象
– 和指针数据对象不是一回事,一般位于不同的地址
– 一般匿名,在使用时指定
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s
0x1000 0x1004 100 200
17清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的初始化
未初始化的指针非常危险
– 既可能指向未知地址,也可能指向未初始化的目标对象
指针的初始化方法
– 目标数据对象的数据类型 *指针变量名 = 初始值 ;
– 例,int n = 100; int *p = &n;
– 例,int a[8]; int *q = a; // a为数组名,表示数组首地址
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s n a[0]
0x1000 0x1004 100 200
18清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础关于指针初始化的说明
指针的初始化是指针数据对象的初始化,而不是目标数据对象的初始化
目标数据对象的数据类型必须与指针定义一致
可以使用其他同类型指针变量进行初始化
初始值为某个数据对象的地址,该数据对象必须已定义
普通整型数据一般不能作为初始值,否则会造成程序灾难
可以将指针初始化为空指针,即设为 0,使其不指向任何对象
19清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的算术运算
指针递增递减运算
– 向下(递增)或向上(递减)移动 一个数据单位
– 例,int a[8]; int *p = a; p++; // 使 p指向 a[1]
指针加减某个整数运算
– 向下(加)或向上(减)移动 n个数据单位
– 例,int a[8]; int *p = a; p = p + 2; // 使 p指向 a[2]
指针相减运算
– 确定两个指针间的 数据个数,不是字节数
– 例,int a[8]; int *p1 = a,*p2 = &a[7]; // p2 – p1? 7
20清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的关系运算与赋值运算
指针的关系运算
– 只能判断指针是否为空指针
– 例,int a[8]; int *p = a; if( p != 0 ) *p = 100;
指针的赋值运算
– 将变量地址赋给指针,int n; int *p; p = &n;
– 同类型指针赋值,int *p,*q; p = q;
– 将数组赋给指针,int a[8]; int *p; p = a;
– 其他常用赋值运算,int *p,*q; p = q + 2; p += 2;
21清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针操作示例一
使用指针将输入的两个整数交换顺序
#include <stdio.h>
int main()
{
int m,n,*pm,*pn,temp; // 定义整型变量和指针变量
pm = &m; pn = &n; // 指针 pm指向变量 m,指针 pn指向变量 n
scanf(?%d%d?,&m,&n); // 利用指针输入整型数据 m和 n
// 利用指针进行数据交换,设中间变量 temp
temp = *pm; *pm = *pn; *pn = temp;
printf(?%d,%d\n?,m,n); // 输出 m和 n的结果
printf(?%d,%d\n?,*pm,*pn); // 利用指针输出结果
return 0;
} temp = pm; pm = pn; pn = temp;
问题:使用下边的语句替换行不行?
22清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针操作示例二
使用指针输入输出数组元素
#include <stdio.h>
int main()
{
float data[5],*pf = data;
int k;
printf(?Input data:\n?);
for(k = 0; k < 5; k++) scanf(?%f?,pf + k); // 通过指针进行数组元素的输入
for(k = 0; k < 5; k++){ printf(?%f,?,*pf ); pf++; } // 通过指针输出数组元素
pf = data; // 指针重新指向数组的首地址
printf(?\n?);
for(k = 0; k < 5; k++) printf(?%f,?,*(pf + k)); // 依次输出数组各元素
printf(?\n?);
return 0;
}
pf + k? &data[k]
*(pf + k)? data[k]
23清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.3 结构体及其应用
结构体类型的声明
结构体变量的声明
结构体成员的引用
结构体变量的初始化
24清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体类型的声明
结构体类型的性质:不同数据类型组成的集合体
声明格式 struct 结构体名{
数据类型声明符 1 成员名 1;
数据类型声明符 2 成员名 2;
┆
数据类型声明符 n 成员名 n;
};
struct DATE
{
int year;
int month;
int day;
int yearday;
};
说 明
– 结构体类型声明为数据结构的存储模型,并不分配内存
– 结构体成员不能为本结构体类型,但可以为与本结构体完全无关的其他结构体类型
25清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体变量的定义与初始化
结构体类型的变量定义
– 按照结构体类型分配实际的存储空间
– 声明格式,struct 结构体名 变量名 ;
– 例,struct DATE date;
结构体类型变量的初始化
– 按声明顺序逐成员进行
– 例,struct DATE date = { 2004,8,3 };
– 说明:初始化数据必须与结构体类型声明的类型与顺序完全一致,各个成员初始值之间用逗号分隔
26清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体成员的引用
成员选择操作符,.”
– 格式,结构体变量名,成员名
– 例,struct DATE date; date.year = 2004;
成员选择操作符,–>”
– 格式,结构体变量名 –>成员名
– 例,struct DATE *p = &date; p–>year = 2004;
– 说明,p–>year? (*p).year
y e a r
m o n t h
day
y e a r d a y
date
27清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体成员的引用示例
将某年某月某日转换成该年的第几天
#include <stdio.h>
struct DATE{ int year; int month; int day; int yearday; };
int main()
{
int leap = 0,i;
struct DATE date;
static int month[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
printf(?\nEnter year month and day,\n?);
scanf(?%d,%d,%d?,&date.year,&date.month,&date.day);
if(date.year%4==0 && (date.year%100!=0||date.year%400==0)) leap = 1;
date.yearday = date.day + leap;
for(i = 1; i < date.month; i++) date.yearday += month[i];
printf(?yearday = %d\n?,date.yearday);
return 0;
}
28清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.4 联合体及其应用
联合体类型的声明
联合体变量的声明
联合体成员的引用
联合体变量定义时应注意的问题
29清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体类型的声明
联合体类型的性质
– 不同数据类型组成的集合体
– 除了各个成员共享同一片存储空间,其他性质与结构体完全相同
声明格式
union 联合体名
{
数据类型声明符 1 成员名 1;
数据类型声明符 2 成员名 2;
┆
数据类型声明符 n 成员名 n;
};
union DATA
{
int n;
char* p;
char c;
};
30清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体成员的引用示例
编程建立教师与学生登记表,其中包括 ID识别号、
姓名、身份标志、职称(教师)或年级(学生),
如若身份标志为‘ S’则填年级信息,若身份标志为
‘ T’则填职称信息
#include <stdio.h>
#include <string.h>
struct PERSON{
int id;
char name[10];
char levelflag;
union{
int grade;
char jobtitle[10];
} level;
};
struct PERSON person;
嵌套的联合体变量 level作为结构体类型 PERSON的成员
31清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体成员的引用示例
int main()
{
printf(?\nPersonal Info(ID,name,level-flag,grade or job-title),\n?);
scanf(?%d%s%s?,&person.id,person.name,&person.levelflag);
if(person.levelflag,‘S’)
scanf(?%d?,&person.level.grade);
else if(person.levelflag,‘T’)
scanf(?%s?,&person.level.jobtitle);
else
printf(?Input Error!\n?);
printf(?ID name job grade/position\n?);
if(person.levelflag,‘S’)
printf(?%–15d%–10s%–15d\n?,person.id,person.name,person.level.grade);
else if(person.levelflag,‘T’)
printf(?%–15d%–10s%–15s\n?,person.id,person.name,person.level.jobtitle);
return 0;
}
32清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.5 枚举类型及其应用
枚举类型的声明
– enum 枚举名 { 元素名 1,元素名 2,<,元素名 n };
– 例,enum MONTH{ JAN,FEB,MAR,APR,
MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC };
枚举类型变量的定义
– 例,enum MONTH month;
枚举类型的应用
– 意义:取代魔数,使源代码更易理解
33清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础关于枚举类型的说明
枚举类型声明中的元素为枚举文字,不是变量
枚举文字的值缺省时从 0开始,依次递增
显式定义枚举文字的值也是允许的
– 例,enum WEEKDAY{ SUN=7,MON=1,TUE,WED,
THU,FRI,SAT };
枚举变量可用于比较或判断操作
– 例,if( month == DEC ) <
整数要先进行类型转换才可以赋给枚举变量
34清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.6 自定义类型
自定义类型的格式
– typedef 原类型标识 新类型名 ;
– 例一,typedef int DWORD;
– 例二,enum BOOL_TAG{ FALSE,TRUE }; typedef
enum BOOL_TAG BOOL;
自定义类型的性质
– 新类型与原类型相同,并未产生新类型,重新命名的自定义类型使程序更易理解
– 自定义类型不是简单的类型替换,typedef CHAR*
PCHAR; PCHAR p,q; 定义了两个指针变量 p,q,不是单个指针变量 p与单个字符变量 q
35清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础作 业
第 106页:第二题(编程题)
– 第 1,6,7小题
计算机程序设计基础乔 林计算机程序设计基础
Email,qiaolin@cic.tsinghua.edu.cn
Tel,62792961
2清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础第四章 复合数据结构基础
学习目标
– 掌握数组定义与基本使用方法,熟悉字符型数组概念
– 掌握指针基本概念,能熟练使用指针操作基本数据对象,
掌握指针基本运算,了解指针与数组的关系
– 掌握结构体类型的声明、结构体变量的定义与基本用法,
能在程序中熟练使用结构体
– 掌握联合体类型的声明、联合体变量的定义与基本用法,
能在程序中熟练使用联合体
– 掌握枚举类型的概念、定义与使用方法
– 了解自定义类型的定义与使用方法
3清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.1 数组及其应用
一维数组
多维数组
字符数组的应用
4清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组的定义与格式
一维数组的定义:相同类型的一系列数据
– 数据类型 数组名 [元素个数 ];
– 例,int a[8];
关于数组定义的几点说明
– 数组声明中的方括号不能使用小括号代替
– 数组元素个数必须为整型常量或编译期可计算的常量表达式,不能为变量
– 数组元素下标从 0开始编号,数组元素个数必须大于 1
– 系统不检查数组下标,注意数组下标是否超出定义范围!
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
5清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组的初始化
初始化格式:相同类型的一系列数据
– 数据类型 数组名 [元素个数 ] = {值 1,值 2,<,值 n};
– 例,int a[8] = {10,20,30};
关于数组初始化的几点说明
– 花括号中数据序列表示数组初始值,以逗号分隔
– 数组元素的初始化从第 0个元素开始;若初始值数目少于数组元素个数,则后继元素未初始化;若中间部分元素无需初始化,则应使用逗号分隔(系统默认为 0)
– 数组定义与初始化场合,可省略方括号中的元素个数说明,系统自动将其设为初始化值的个数
10 20 30
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]
6清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例一
输入一个含有 12个浮点数的一维数组,分别计算数组中所有正数与所有负数的和
#include <stdio.h>
int main()
{
float data[12];
float result1 = 0.0,result2 = 0.0;
int i;
printf(?Please input 12 floats:\n?);
for(i = 0; i < 12; i++) scanf(?%f?,&data[i]);
for(i = 0; i < 12; i++){
if(data[i] > 0.0) result1 += data[i]; else result2 += data[i];
}
printf(?Positives,%f\nNegatives,%f\n?,result1,result2);
return 0;
}
实际为数组元素遍历问题:使用循环,从头至尾搜索整个数组数组经常与循环联系在一起,这是因为数组下标的变化与循环控制变量是一致的
7清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例二
使用冒泡法对 5个整数按从大到小的顺序排列利用冒泡法进行排序,5个数分别位于不同层。要使大数在顶层小数在底层,小数应下降,大数应上升。最大数上升到顶层最多需要“冒泡” 4次,其中每一次称为一趟。而在每一趟中,最小数不断下降,因为每次只交换相邻两个层面的数据,所以每一趟内的执行次数不大于 4次,并会随着趟数的增加不断减少。
1
7
12
16
20
7
1
12
16
20
7
12
1
16
20
7
12
16
1
20
7
12
16
20
1
12
16
20
7
1
16
20
12
7
1
20
16
12
7
1
一趟 二趟 三趟 四趟
8清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础一维数组示例二
使用冒泡法对 5个整数按从大到小的顺序排列
#include <stdio.h>
int main()
{
int i,j,temp;
static int a[5] = {1,7,12,16,20};
for(i = 0; i < 4; i++)
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;
}
}
for(j = 0; j < 5; j++) printf(?a[%d] = %d\n?,j,a[j]);
return 0;
}
9清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组的定义与格式
多维数组的定义:相同类型的一系列数据
– 数据类型 数组名 [常量表达式 1][常量表达式 2+<;
– 例,int a[2][8];
关于多维数组定义的几点说明
– 数据顺序存放,先存第一行,再存第二行
– 只能引用元素,不能引用整体数组,如不能整体赋值
– 系统不检查数组下标,注意数组下标是否超出定义范围!
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] a[1][5] a[1][6] a[1][7]
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[0][5] a[0][6] a[0][7]
10清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组的初始化
按数据元素的存放顺序依次初始化每个元素
– 例,int a[2][8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
按其维度分别初始化:相当于降维处理
– 例,int a[2][8] = {{0,1,2,3,4,5,6,7},{8,9,10,11,12,13,14,15}};
8 9 10 11 12 13 14 15
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] a[1][5] a[1][6] a[1][7]
0 1 2 3 4 5 6 7
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[0][5] a[0][6] a[0][7]
11清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础多维数组示例
用户输入一个 4× 4的整数矩阵,编写程序求其两对角线上元素的和
#include <stdio.h>
int main()
{
int matrix[4][4],i,j,result1 = 0,result2 = 0;
for(i = 0; i < 4; i++){
printf(?Line %d,?,i);
for(j = 0; j < 4; j++){
scanf(?%d?,&matrix[i][j]);
if(i == j) result1 += matrix[i][j]; if( i + j == 3 ) result2 += matrix[i][j];
}
}
printf(?Results,%d,%d\n?,result1,result2);
return 0;
}
12清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础字符型数组的应用
字符型数组:元素类型为字符的数组
– 常用于存放字符串
– 二维字符数组:元素类型为字符串的一维数组
初始化
– 使用数组形式,char s*6+ =,‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’};
– 使用字符串形式,char s*6+ =?Hello?;
字符型数组的输入输出
– putchar(),getchar(),printf(),scanf()
13清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础字符型数组示例
编写程序,将两个字符串中的字符拼接起来
#include <stdio.h>
int main()
{
char str0[41],str1[21]; // 定义字符型数组,存放两个字符串
int j,k; // 定义两个循环因子
printf(?Please input the first string:\n?);
scanf(?%s?,str0);
printf(?Please input the second string:\n?);
scanf(?%s?,str1);
for(j = 0; str0[j+ != ‘\0‘; j++) ; // 搜索到 str0的结尾处
for(k = 0; str1[k+ != ‘\0‘; k++,j++) // 将 str1中字符拷贝到 str0后面
str0[j] = str1[k];
str0[j+ = ‘\0‘; // 添加字符串结尾标志
printf(?%s?,str0);
return 0;
}
14清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.2 指针及其应用
指针的基本概念与定义
指针的初始化
指针运算
使用指针操作基本数据对象
使用指针操作数组
15清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的基本概念与定义
指针是一种数据类型
– 格式,目标数据对象的数据类型 *指针变量名 ;
– 例,int *p; float *q; char *s;
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s
多个指针变量声明指针
– 每个变量名前都需使用指针符号
– 例,int *p,*q;
16清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针数据对象与目标数据对象
指针数据对象
– 指针变量:指针数据类型定义的变量(数据对象)
– 指针变量的值:内存地址值,一般为其他数据对象地址
目标数据对象:指针所指向的数据对象
– 和指针数据对象不是一回事,一般位于不同的地址
– 一般匿名,在使用时指定
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s
0x1000 0x1004 100 200
17清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的初始化
未初始化的指针非常危险
– 既可能指向未知地址,也可能指向未初始化的目标对象
指针的初始化方法
– 目标数据对象的数据类型 *指针变量名 = 初始值 ;
– 例,int n = 100; int *p = &n;
– 例,int a[8]; int *q = a; // a为数组名,表示数组首地址
0x00A0 0x00A4 < 0x1000 0x1004 0x1008 0x100C内存地址数据值
p q数据对象
0x00A8
s n a[0]
0x1000 0x1004 100 200
18清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础关于指针初始化的说明
指针的初始化是指针数据对象的初始化,而不是目标数据对象的初始化
目标数据对象的数据类型必须与指针定义一致
可以使用其他同类型指针变量进行初始化
初始值为某个数据对象的地址,该数据对象必须已定义
普通整型数据一般不能作为初始值,否则会造成程序灾难
可以将指针初始化为空指针,即设为 0,使其不指向任何对象
19清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的算术运算
指针递增递减运算
– 向下(递增)或向上(递减)移动 一个数据单位
– 例,int a[8]; int *p = a; p++; // 使 p指向 a[1]
指针加减某个整数运算
– 向下(加)或向上(减)移动 n个数据单位
– 例,int a[8]; int *p = a; p = p + 2; // 使 p指向 a[2]
指针相减运算
– 确定两个指针间的 数据个数,不是字节数
– 例,int a[8]; int *p1 = a,*p2 = &a[7]; // p2 – p1? 7
20清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针的关系运算与赋值运算
指针的关系运算
– 只能判断指针是否为空指针
– 例,int a[8]; int *p = a; if( p != 0 ) *p = 100;
指针的赋值运算
– 将变量地址赋给指针,int n; int *p; p = &n;
– 同类型指针赋值,int *p,*q; p = q;
– 将数组赋给指针,int a[8]; int *p; p = a;
– 其他常用赋值运算,int *p,*q; p = q + 2; p += 2;
21清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针操作示例一
使用指针将输入的两个整数交换顺序
#include <stdio.h>
int main()
{
int m,n,*pm,*pn,temp; // 定义整型变量和指针变量
pm = &m; pn = &n; // 指针 pm指向变量 m,指针 pn指向变量 n
scanf(?%d%d?,&m,&n); // 利用指针输入整型数据 m和 n
// 利用指针进行数据交换,设中间变量 temp
temp = *pm; *pm = *pn; *pn = temp;
printf(?%d,%d\n?,m,n); // 输出 m和 n的结果
printf(?%d,%d\n?,*pm,*pn); // 利用指针输出结果
return 0;
} temp = pm; pm = pn; pn = temp;
问题:使用下边的语句替换行不行?
22清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础指针操作示例二
使用指针输入输出数组元素
#include <stdio.h>
int main()
{
float data[5],*pf = data;
int k;
printf(?Input data:\n?);
for(k = 0; k < 5; k++) scanf(?%f?,pf + k); // 通过指针进行数组元素的输入
for(k = 0; k < 5; k++){ printf(?%f,?,*pf ); pf++; } // 通过指针输出数组元素
pf = data; // 指针重新指向数组的首地址
printf(?\n?);
for(k = 0; k < 5; k++) printf(?%f,?,*(pf + k)); // 依次输出数组各元素
printf(?\n?);
return 0;
}
pf + k? &data[k]
*(pf + k)? data[k]
23清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.3 结构体及其应用
结构体类型的声明
结构体变量的声明
结构体成员的引用
结构体变量的初始化
24清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体类型的声明
结构体类型的性质:不同数据类型组成的集合体
声明格式 struct 结构体名{
数据类型声明符 1 成员名 1;
数据类型声明符 2 成员名 2;
┆
数据类型声明符 n 成员名 n;
};
struct DATE
{
int year;
int month;
int day;
int yearday;
};
说 明
– 结构体类型声明为数据结构的存储模型,并不分配内存
– 结构体成员不能为本结构体类型,但可以为与本结构体完全无关的其他结构体类型
25清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体变量的定义与初始化
结构体类型的变量定义
– 按照结构体类型分配实际的存储空间
– 声明格式,struct 结构体名 变量名 ;
– 例,struct DATE date;
结构体类型变量的初始化
– 按声明顺序逐成员进行
– 例,struct DATE date = { 2004,8,3 };
– 说明:初始化数据必须与结构体类型声明的类型与顺序完全一致,各个成员初始值之间用逗号分隔
26清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体成员的引用
成员选择操作符,.”
– 格式,结构体变量名,成员名
– 例,struct DATE date; date.year = 2004;
成员选择操作符,–>”
– 格式,结构体变量名 –>成员名
– 例,struct DATE *p = &date; p–>year = 2004;
– 说明,p–>year? (*p).year
y e a r
m o n t h
day
y e a r d a y
date
27清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础结构体成员的引用示例
将某年某月某日转换成该年的第几天
#include <stdio.h>
struct DATE{ int year; int month; int day; int yearday; };
int main()
{
int leap = 0,i;
struct DATE date;
static int month[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
printf(?\nEnter year month and day,\n?);
scanf(?%d,%d,%d?,&date.year,&date.month,&date.day);
if(date.year%4==0 && (date.year%100!=0||date.year%400==0)) leap = 1;
date.yearday = date.day + leap;
for(i = 1; i < date.month; i++) date.yearday += month[i];
printf(?yearday = %d\n?,date.yearday);
return 0;
}
28清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.4 联合体及其应用
联合体类型的声明
联合体变量的声明
联合体成员的引用
联合体变量定义时应注意的问题
29清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体类型的声明
联合体类型的性质
– 不同数据类型组成的集合体
– 除了各个成员共享同一片存储空间,其他性质与结构体完全相同
声明格式
union 联合体名
{
数据类型声明符 1 成员名 1;
数据类型声明符 2 成员名 2;
┆
数据类型声明符 n 成员名 n;
};
union DATA
{
int n;
char* p;
char c;
};
30清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体成员的引用示例
编程建立教师与学生登记表,其中包括 ID识别号、
姓名、身份标志、职称(教师)或年级(学生),
如若身份标志为‘ S’则填年级信息,若身份标志为
‘ T’则填职称信息
#include <stdio.h>
#include <string.h>
struct PERSON{
int id;
char name[10];
char levelflag;
union{
int grade;
char jobtitle[10];
} level;
};
struct PERSON person;
嵌套的联合体变量 level作为结构体类型 PERSON的成员
31清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础联合体成员的引用示例
int main()
{
printf(?\nPersonal Info(ID,name,level-flag,grade or job-title),\n?);
scanf(?%d%s%s?,&person.id,person.name,&person.levelflag);
if(person.levelflag,‘S’)
scanf(?%d?,&person.level.grade);
else if(person.levelflag,‘T’)
scanf(?%s?,&person.level.jobtitle);
else
printf(?Input Error!\n?);
printf(?ID name job grade/position\n?);
if(person.levelflag,‘S’)
printf(?%–15d%–10s%–15d\n?,person.id,person.name,person.level.grade);
else if(person.levelflag,‘T’)
printf(?%–15d%–10s%–15s\n?,person.id,person.name,person.level.jobtitle);
return 0;
}
32清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.5 枚举类型及其应用
枚举类型的声明
– enum 枚举名 { 元素名 1,元素名 2,<,元素名 n };
– 例,enum MONTH{ JAN,FEB,MAR,APR,
MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC };
枚举类型变量的定义
– 例,enum MONTH month;
枚举类型的应用
– 意义:取代魔数,使源代码更易理解
33清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础关于枚举类型的说明
枚举类型声明中的元素为枚举文字,不是变量
枚举文字的值缺省时从 0开始,依次递增
显式定义枚举文字的值也是允许的
– 例,enum WEEKDAY{ SUN=7,MON=1,TUE,WED,
THU,FRI,SAT };
枚举变量可用于比较或判断操作
– 例,if( month == DEC ) <
整数要先进行类型转换才可以赋给枚举变量
34清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础
4.6 自定义类型
自定义类型的格式
– typedef 原类型标识 新类型名 ;
– 例一,typedef int DWORD;
– 例二,enum BOOL_TAG{ FALSE,TRUE }; typedef
enum BOOL_TAG BOOL;
自定义类型的性质
– 新类型与原类型相同,并未产生新类型,重新命名的自定义类型使程序更易理解
– 自定义类型不是简单的类型替换,typedef CHAR*
PCHAR; PCHAR p,q; 定义了两个指针变量 p,q,不是单个指针变量 p与单个字符变量 q
35清华大学计算中心 http://learn.tsinghua.edu.cn
计算机程序设计基础作 业
第 106页:第二题(编程题)
– 第 1,6,7小题