第8章常用构造类型2.docx
- 文档编号:312817
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:41
- 大小:33.99KB
第8章常用构造类型2.docx
《第8章常用构造类型2.docx》由会员分享,可在线阅读,更多相关《第8章常用构造类型2.docx(41页珍藏版)》请在冰点文库上搜索。
第8章常用构造类型2
第8章常用数据表达
本章重点:
●常用的数据类型
●宏的定义与应用
●数组的定义和使用
●指针的定义和使用
●结构体的定义
●枚举与定义类型
●指针和数组
●返回值为指针的函数
●指向函数的指针
本章难点
●数组的含义与数组名的理解
●结构体类型与结构体变量的区别
●结构体变量对结构体成员的引用
●指针在数组中的应用
●指针数组与数组指针
本章学习建议:
除了前面章节涉及的基本数据类型:
int、float、double、char外,C语言还提供了构造类型的数据。
本章让读者初步认识数组类型、结构体类型、数组指针和指针数组等概念,掌握一维数组和结构体的定义及应用,掌握指针在一维数组中的应用,了解指针数组与数组指针的概念。
(4课时)
8.1数组
数组是一种用户自定义的构造类型,是有序数据的集合。
在C语言中的程序设计过程中,数组的应用是非常普遍的,许多问题不用数组几乎难以解决。
数组有以下主要特点:
(1)每个数组中的元素类型必须一致。
(2)用不同的下标来区分数组的元素。
(3)数组在内存中占有连续的存储单元,数组名表示数组在内存中的首地址。
(4)数组和指针有着极密切的联系,可以通过指针移动来对数组元素进行操作。
8.1.1一维数组
1.一维数组的定义
类型说明符数组名[整型常量表达式];
类型说明符表示数据存放的类型,整型常量表达式为数组下标,表示数组元素的个数。
例如:
inta[5];
它表示定义5个元素的整型数组,数据名为a,a也是这5个元素存储区的首地址,因而a的地址值不能改变。
例8.1数组及数组元素的表示方法
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-1.c
#include
intmain()
{
inti,a[10]={1,2,3,4,5,6};/*定义一个整型数组,数组名为a,并给数组初始化*/
for(i=0;i<10;i++)
printf("a[%d]=%-4d",i,a[i]);/*a[i]为数组的第i个元素*/
printf("\n");
return0;
}
步骤3:
点击编译图标
,编译程序8-1.c
步骤4:
点击执行图标
,执行程序8-1.c,此程序执行后在屏幕上输出
a[0]=1a[1]=2a[2]=3a[3]=4a[4]=5a[5]=6a[6]=0a[7]=0a[8]=0a[9]=0
参照例8.1,请注意下列问题。
注意:
(1)数组名的命名方法与变量名相同,遵循标识符命名规则。
(2)常量表达式表示数组元素的个数,即数组的长度,数组的下标从0开始,下标的最大值为:
常量表达式-1。
例如,在inta[5];中数组a的5个元素分别表示为:
a[0]、a[1]、a[2]、a[3]、a[4]。
(3)常量表达式中可以包括常量和符号常量。
(4)C语言不允许对数组作动态定义。
例如:
intn;
scanf("%d",&n);
inta[n];
以上程序段是错误的,它对数组大小作了动态定义。
2.一维数组的引用、初始化与赋值
C语言规定不能一次引用整个数组,引用时只能对逐个元素进行引用。
如何给一维数组赋值呢?
可以有三种方法:
(1)数组的初始化;
(2)程序中赋值;(3)键盘中读入。
(1)数组的初始化。
数组的初始化,只有静态或外部数据可赋一个最初的值。
对数组初始化可以用以下方法实现:
①在定义数组时对数组元素可赋以初值。
如:
staticinta[10]={0,1,2,3,4,5,6,7,8,9};
经过上面的定义和初始化后,它相当于:
a[0]=0,a[1]=1,a[2]=2,a[3]=3,a[4]=4,a[5]=5,a[6]=6,a[7]=7,a[8]=8,a[9]=9。
②初始化时可以只对一部分元素赋初值。
例如:
staticinta[10]={0,1,2,3,4};
定义的数组有10个元素,但只对其中前5个元素赋了初值,后5个元素的初值为0。
③如果想使一个数组的元素值全部为0,可以用下面的方法:
staticinta[10]={0};
即使对static型的数组不赋初值,系统也会对所定义的数组的所有元素自动赋以0值。
例题8.1验证了以上论述。
④在对全部数组元素赋初值时,可以不指定数组长度。
例如:
staticinta[5]={1,0,3,5,7};与staticinta[]={1,0,3,5,7};等效。
注意:
下列定义语句是不等效的:
staticinta[10]={1,2,3,4};与staticinta[]={1,2,3,4};前者表示前4个元素的值分别为1、2、3、4,后6个元素数值为0;后者表示的数组只有4个元素。
以上论述了如何给数组初始化,也可以在程序运行时给数组元素赋值,以下用实例来说明这个问题。
(2)程序中给数组的元素赋值。
例8.2问题的提出:
程序中给数组的元素赋值,并输出数组元素的值。
分析问题:
数组s在定义时赋值;数组a在程序中赋值。
s[2]的3赋给a[0],s[4]的5赋给a[1],s[7]的8赋给a[2],程序运行的结果为:
a[0]=3a[1]=5a[2]=8。
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-2.c
步骤2:
在8-2.c文件中输入以下完整的源程序。
#include
intmain()
{
ints[10]={1,2,3,4,5,6,7,8,9,10};
inti=2,a[3];
a[0]=s[i];
a[1]=s[2+i];
a[2]=s[2*i+3];
printf("a[0]=%da[1]=%da[2]=%d\n",a[0],a[1],a[2]);
return0;
}
步骤3:
点击编译图标
,编译程序8-2.c
步骤4:
点击执行图标
,执行程序8-2.c,此程序执行后在屏幕上输出
a[0]=3a[1]=5a[2]=8
(3)程序运行时从键盘输入。
例8.3问题的提出:
程序运行时从键盘输入,给数组的元素赋值,最后输出数组元素的值。
分析问题:
初始化数组a[4],程序等待键盘输入4个数,把键盘输入的数赋值给数组a中的4个元素,输出数组a[4]的4个元素的值。
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-3.c
步骤2:
在8-3.c文件中输入以下完整的源程序。
#include
intmain()
{
inti,a[10];
printf("请输入10个整型数,以空格隔开\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("输入的数组为:
");
for(i=0;i<10;i++)
printf("a[%d]=%-4d",i,a[i]);
printf("\n");
return0;
}
步骤3:
点击编译图标
,编译程序8-2.c
步骤4:
点击执行图标
,执行程序8-2.c,此程序执行后在屏幕上输出
请输入10个整型数,以空格隔开
8791246203
输入的数组为:
a[0]=8a[1]=7a[2]=9a[3]=1a[4]=2a[5]=4a[6]=6a[7]=2a[8]=0a[9]=3
✧上机练习1
模仿例8.3,定义有10个元素的int型数组,数组元素从键盘输入,求数组中所有元素的各个位数之和。
8.1.2字符数组
C语言本身并没有设置一种类型来定义字符串变量,字符串的存储完全依赖于字符数组,但字符数组又不等于字符串变量。
虽然C语言中没有字符串数据类型,但却允许使用字符串常量。
在C语言中,字符串是借助于字符型一维数组来存放的,以字符‘\0’作为字符串结束标志,它的ASCII代码值为0,‘\0’占用存储空间、不输出,但不计入串的实际长度。
可以用字符数组存放字符串,如chars[10]={'H','e','l','l','o','!
','\0'};或:
chars[10]="Hello!
";
但是以下给数组的赋值是不合法的:
chars[10];
s="Hello!
";
因为表示字符串“Hello!
”的是存储空间的首地址,而数组定义后数组首地址也是常量,两个常量之间不能相互赋值。
如有以下定义:
charstr1[10]="computer",str2[20];
赋值方式str2=str1;也是错误的。
当然数组元素间赋值可逐个进行,最后人为加入字符串结束标志‘\0’。
例如:
for(j=0;str1[j]!
='\0';j++)
str2[j]=str1[j];
str2[j]='\0';/*人为加入字符串结束标志'\0'*/
可以在字符数组内存放字符串。
如果一个字符数组用来作为字符串使用,那么在定义该字符数组时,数组的大小就应该比它将要实际存放的最长字符串多一个元素,从而在末尾存放‘\0’留有空间。
当用赋初值方式来定义字符数组大小时,这时定义应写成:
charstr1[]={'s','t','r','i','n','g','!
','\0'};
在此定义了有7个字符的字符串,数组str1包含了8个元素的字符数组。
可以直接用字符串常量给一维字符数组赋初值。
例如:
charstrl[10]={"string!
"};
在这里由于“string!
”是字符串常量,系统己自动在最后加入‘\0’,所以不必人为加入。
或写成:
charstr[]="string";
若是定义成:
charstr[7]="string!
";是错误的,因7个字节的空间不够用,‘\0’将占用下一个不属于str的存储单元。
例8.4问题的提出:
利用字符数组,在终端中输出字符串“ILoveLinux!
”。
分析问题:
初始化数组string[],在初始化时直接用字符串常量,给字符数组string[]赋初值“ILoveLinux!
”,用printf直接输出字符串。
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-4.c
步骤2:
在8-4.c文件中输入以下完整的源程序。
#include
intmain()
{
charstring[]="ILoveLinux!
";
printf("%s\n",string);
return0;
}
步骤3:
点击编译图标
,编译程序8-4.c
步骤4:
点击执行图标
,执行程序8-4.c,此程序执行后在屏幕上输出
ILoveLinux!
思考:
1.如果把语句printf("%s\n",string);修改为:
printf("%s\n",string+2);思考输出的结果并验证。
2.修改上例的程序,程序运行时从键盘输入“ILoveLinux!
”。
✧上机练习2
1.从键盘输入一字符串,存放在一字符数组中,然后求这一字符数组中大写字母的个数。
2.从键盘输入一字符串,存放在一字符数组中,然后求这一字符数组中元音字母的个数。
8.1.3二维数组
在C语言中,可以把二维数组看作是一种特殊的一维数组,二维数组中元素的排列顺序是:
先按行存放,再按列存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素。
1.二维数组的定义
类型说明符数组名[常量表达式1][常量表达式2];
常量表达式1表示二维数组的行数,常量表达式2表示二维数组的列数。
例,floata[3][4];
它表示定义了数组名为a的3行4列的实型数组。
2.二维数组的表示、初始化与赋值
当定义了一个二维数组后,在程序中就可以引用二维数组的元素及地址。
在引用二维数组时,必须是单个元素,不能是整个数组名。
下标可以是一个表达式。
如果下标是一个表达式,注意表达式的值不能超出数组定义的上、下限。
二维数组的赋值也可以分为3种情况:
(1)二维数组的初始化;
(2)在程序中赋值;(3)从键盘读入。
在程序中对二维数组的初始化应说明为静态的或外部的。
可对二维数组初始化的情况有:
(1)分行给二维数组赋初值。
statica[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
以上赋值把第一个花括号内的数据赋给第一行元素,第二个花括号内的数据赋给第二行元素…,即按行赋值。
或者:
staticinta[3][3]={{1,2,3},
{4,5,6},
{7,8,9}};
(2)可以将所有的数据写在一个花括号内,按数组排列的顺序对各元素赋值。
例:
staticinta[3][3]={1,2,3,4,5,6,7,8,9};
(3)可以对数组的部分元素赋初值。
如:
staticinta[3][4]={{l},{5},{9}};
以上赋值的结果是:
数组第一列的元素分别赋了初值1,5,9,其余元素的值都是0。
例如,有定义:
inta[3][3]={{1},{4},{7}};
实质上与:
inta[3][3]={1,0,0,4,0,0,7,0,0};等效。
inta[3][3]={{1,2,3}};
实质上与:
inta[3][3]={1,2,3,0,0,0,0,0,0};等效。
(4)如果对二维数组的全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省略。
例如:
inta[3][3]={1,2,3,4,5,6,7,8,9};
与a[][3]={1,2,3,4,5,6,7,8,9};等价。
又如:
staticinta[][3]={{0,0,3},{0},{0,10}};可表示为:
staticinta[][3]={0,0,3,0,0,0,0,10,0};
有关在程序设计中给二维数组元素赋值及从键盘读入的方法与一维数组基本相同。
设有整型二维数组a[3][4]如下:
0123
4567
891011
它的定义为:
inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}
例8.5二维数组输入、输出的例子。
#include
intmain()
{
inti,j,a[4][4];
printf("请输入16个整型数,以空格隔开\n");
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);
printf("输入的数组为:
\n");
for(i=0;i<4;i++){
for(j=0;j<4;j++)
printf("a[%d][%d]=%-4d",i,j,a[i][j]);
printf("\n");
}
return0;
}
步骤3:
点击编译图标
,编译程序8-5.c
步骤4:
点击执行图标
,执行程序8-5.c,此程序执行后在屏幕上输出
请输入16个整型数,以空格隔开
259-732451234910-2-58
输入的数组为:
a[0][0]=2a[0][1]=5a[0][2]=9a[0][3]=-7
a[1][0]=3a[1][1]=2a[1][2]=4a[1][3]=5
a[2][0]=12a[2][1]=34a[2][2]=9a[2][3]=1
a[3][0]=0a[3][1]=-2a[3][2]=-5a[3][3]=8
8.2结构体
以前各章所讨论的数据是单一的数据类型,而在实际应用中所涉及到变量的属性是各种基本数据类型的组合,因而在C语言程序设计中引入了结构体类型的概念。
结构体类型是C语言的一种构造数据类型,它用于描述具有多个数据成员且每个数据成员具有不同数据类型的数据对象。
例如描写一个学生的基本情况,涉及到学号、姓名、性别、两门课的成绩,分别用intnum;charname[8];charsex;floatscore[2]表示,要描写这样一个由不同数据类型构成的对象,需要定义一个结构体类型。
1.结构体类型定义
结构体类型的定义格式为:
struct结构体类型名
{类型数据类型成员名1;
类型数据类型成员名2;
类型数据类型成员名3;
………………
类型数据类型成员名n;
};
例如要描写上述学生的基本情况,需定义的结构体类型为:
structstudent
{
intnum;
charname[8];
charsex;
floatscore[2];
};
注意:
(1)此定义仅仅是结构体类型的定义,它说明了结构体类型的构成情况,C语言并没有为之分配存储空间。
(2)结构体中的每个数据成员称为分量或域,它们并不是变量,在实际应用中还需定义结构变量。
2.结构体变量的定义
定义了结构体类型以后,可以进行结构体变量的定义,其形式为:
struct结构体类型名结构体变量表;
结构体的变量也可以是数组或指针。
定义结构体变量时,C语言会为每个变量分配存储空间。
结构体变量的定义的方法可以与结构体类型同时定义或分开定义,分开定义是指先定义结构体类型,再定义结构体变量。
定义结构体时,实际上声明了一种复杂的数据类型,并未生成任何变量。
声明该变量之前,不存在任何此种类型的变量。
为了声明student类型的变量stu,可写成如下形式:
structstudentstu;
这样就定义了structstudent类型的结构体变量stu。
student描述结构体类型,称为结构体类型。
stu是结构体类型的实例或对象,称为结构体类型变量或结构体变量。
定义了结构体变量(stu)之后,C编译程序自动为结构体变量的所有成员分配足够的内存,如图8.4所示。
num
name
sex
score[0]
score[1]
4Byte
8Byte
1B
8Byte
8Byte
低地址
高地址
图8.4在Linux环境下结构体变量stu占用内存的情况
定义结构体的同时可定义一个或多个结构体变量。
例如:
structstudent
{
intnum;
charname[8];
charsex;
floatscore[2];
}stu1,stu2,stu3;
定义结构体类型student,同时声明该类型变量stu1,stu2,stu3。
每个结构体变量都包含各自的结构体成员的副本。
例如,stu1中的sex成员和stu2中的sex成员是彼此独立的,改变stu1中的sex,不会影响stu2中的sex。
3.结构体变量对结构体成员的引用
通过圆点(.)操作符可访问结构体中的成员。
访问一个结构体成员的一般形式为:
结构体变量名.成员名;
它表示结构体变量对具体成员的引用,以下代码把2001赋给结构体变量stu1的成员num:
stu1.num=2001;
在屏幕上显示stu的成员num所含的学号值,应写为:
printf("%d",stu.num);
同理,从键盘读入的语句是:
scanf("%d”,&stu.num);
4.结构体变量的赋值
(1)结构体变量可在声明时直接进行初始化。
初始化数据应放在大括号中,并根据成员变量的声明次序排列,同时数据之间的类型应一致。
例如:
structstudentstu1={2001,"张华",’M’,86.00,92.2};
或:
structstudent
{
intnum;
charname[8];
charsex;
floatscore[2];
}stu1={2001,"张华",’M’,86.00,92.2};
例8.6问题的提出:
利用结构体变量存储,并在声明时直接进行初始化,最后在终端中输出张华同学的个人信息。
分析问题:
初始化结构体变量stu1,在初始化时直接给各成员变量赋初值,在主程序中用printf直接输出结构体各成员变量的值。
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-6.c
步骤2:
在8-6.c文件中输入以下完整的源程序。
#include
structstudent
{
intnum;
charname[8];
charsex;
floatscore[2];
}stu1={2001,"张华",'M',86.00,92.2};
intmain()
{
printf("%d\t%s\t%c\t%f\t%f\n",stu1.num,stu1.name,stu1.sex,stu1.score[0],stu1.score[1]);
return0;
}
步骤3:
点击编译图标
,编译程序8-6.c
步骤4:
点击执行图标
,执行程序8-6.c,此程序执行后在屏幕上输出
2001张华M86.00000092.199997
(2)对结构体变量的数据成员成员进行逐个赋值。
例8.7问题的提出:
利用结构体变量存储,并在程序运行时在程序中逐个给成员变量赋值,最后在终端中输出张华同学的个人信息。
分析问题:
定义结构体变量stu1,先不赋值,在主程序中逐个给成员变量赋值,最后用printf直接输出结构体各成员变量的值。
步骤1:
在VisualC++环境下新建文件可用[开始]→[程序]→[MicrosoftVisualC++6.0]→[MicrosoftVisualC++6.0]→[文件]→[新建]→[文件]→[C++SourseFile],输入文件名8-7.c
步骤2:
在8-7.c文件中输入以下完整的源程序。
#include
#include
structstudent
{
intnum;
charname[8];
charsex;
floatscore[2];
}stu1;
intmain(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 常用 构造 类型