计算机本科C语言第八章讲稿
合集下载
C语言课件第8章
C语言程序设计
南昌大学计算中心
第8章 地址和指针
8.1 变量的地址和指针 内存地址:计算机的内存是以字节为单位的一片连续 的存储空间,每一个字节都有一个编号,这个编号就 称为内存地址。 变量的地址:变量所用内存单元的编号(起始地址)。 int a;
float b;
a=3;b=5;
南昌大学计算中心
变量的访问方式: 1、直接存取:程序中对变量进行存取操作,实际上也 就是对某个地址的存储单元进行操作。这种直接按变 量的地址存取变量值的方式称为“直接存取”方式。 2、间接存取:在C语言中还定义了一种特殊的变量, 这种变量用来存放内存地址的,通过这种变量(假如叫 p)间接得到另一变量(假如叫a)的地址,然后再存取变 量a的值的方式称为“间接存取”方式。通常称变量p 指向了变量a,变量a是变量p所指向的对象。 指针:存放某变量地址的变量。 a 1001
printf(“%d %d\n”, *p,(*q)++);
}
等同于*q++
2 2 3 2
南昌大学计算中心
由上述知识总结出以下具有等价关系的对子: 如有:int a=5,*p=&a;
则:&*p *&a (*P)++ *p++
等价于 等价于 等价于 等价于
&a a a++ *(p++)
南昌大学计算中心
南昌大学计算中心
2、通过指针变量获得地址值 可以用赋了值的指针变量给另一个指针变量赋值。 如: int x=1; int *p=&x; int *q=p;
把指针p中存放的地址值赋给指针q
或写成:int x=1; int *p,*q;
南昌大学计算中心
第8章 地址和指针
8.1 变量的地址和指针 内存地址:计算机的内存是以字节为单位的一片连续 的存储空间,每一个字节都有一个编号,这个编号就 称为内存地址。 变量的地址:变量所用内存单元的编号(起始地址)。 int a;
float b;
a=3;b=5;
南昌大学计算中心
变量的访问方式: 1、直接存取:程序中对变量进行存取操作,实际上也 就是对某个地址的存储单元进行操作。这种直接按变 量的地址存取变量值的方式称为“直接存取”方式。 2、间接存取:在C语言中还定义了一种特殊的变量, 这种变量用来存放内存地址的,通过这种变量(假如叫 p)间接得到另一变量(假如叫a)的地址,然后再存取变 量a的值的方式称为“间接存取”方式。通常称变量p 指向了变量a,变量a是变量p所指向的对象。 指针:存放某变量地址的变量。 a 1001
printf(“%d %d\n”, *p,(*q)++);
}
等同于*q++
2 2 3 2
南昌大学计算中心
由上述知识总结出以下具有等价关系的对子: 如有:int a=5,*p=&a;
则:&*p *&a (*P)++ *p++
等价于 等价于 等价于 等价于
&a a a++ *(p++)
南昌大学计算中心
南昌大学计算中心
2、通过指针变量获得地址值 可以用赋了值的指针变量给另一个指针变量赋值。 如: int x=1; int *p=&x; int *q=p;
把指针p中存放的地址值赋给指针q
或写成:int x=1; int *p,*q;
C程序设计教程第8章
图8-4 例题8.4的执行结果
8.2.3 按位“取反”运算符(~)
按位取反运算符“~”为单目(元)运算符。作用是 将一个二进制数按位取反,即将0变1,1变0。
例如,将char类型的数据22,进行取反,结果为233。
~ 00010110 (22) 11101001 (233)
【例8.5】把输入的数据进行取反操作。
x= 00010110 x<<3 10110000
(22) (176)
8.2.5 “左移”运算符(<<)
【例8.7】把输入的数据进行左移操作。 程序的第一次运行过程及结果如下:
图8-7 例题8.7的第一次执行结果
8.2.5 “左移”运算符(<<)
第二次运行过程及结果如下:
图8-8 例题8.7的第二次执行结果
unsigned int
unsigned int
char d;
float e;
}bitdata;
b:2; c:3;
8.3.1 位段的定义
上述结构体中,第一个成员是整型变量,占2个字节; 后面两个位段b和c占1个字节;再后面是一个字符型和一 个浮点型变量,各占1个字节和4个字节。 在位段的使用过程中需要注意的是,定义位段只能用 int和unsigned int,不能用其它类型。
但是不能取一个位段的地址,例如下面的用法是不合 法的:
&bitdata.c 因为地址是以字节为单位的,无法指向位。 位段在控制中非常有用,可以使用户方便、灵活的对
字节中的位进行操作。并且位段的使用使几个数据放 在同一个字节中,节省了存储空间。
8.4 位运算应用举例
【例8.10】设计一个程序,取出一个整数的第3~5位。 第一种实现方法:
8.2.3 按位“取反”运算符(~)
按位取反运算符“~”为单目(元)运算符。作用是 将一个二进制数按位取反,即将0变1,1变0。
例如,将char类型的数据22,进行取反,结果为233。
~ 00010110 (22) 11101001 (233)
【例8.5】把输入的数据进行取反操作。
x= 00010110 x<<3 10110000
(22) (176)
8.2.5 “左移”运算符(<<)
【例8.7】把输入的数据进行左移操作。 程序的第一次运行过程及结果如下:
图8-7 例题8.7的第一次执行结果
8.2.5 “左移”运算符(<<)
第二次运行过程及结果如下:
图8-8 例题8.7的第二次执行结果
unsigned int
unsigned int
char d;
float e;
}bitdata;
b:2; c:3;
8.3.1 位段的定义
上述结构体中,第一个成员是整型变量,占2个字节; 后面两个位段b和c占1个字节;再后面是一个字符型和一 个浮点型变量,各占1个字节和4个字节。 在位段的使用过程中需要注意的是,定义位段只能用 int和unsigned int,不能用其它类型。
但是不能取一个位段的地址,例如下面的用法是不合 法的:
&bitdata.c 因为地址是以字节为单位的,无法指向位。 位段在控制中非常有用,可以使用户方便、灵活的对
字节中的位进行操作。并且位段的使用使几个数据放 在同一个字节中,节省了存储空间。
8.4 位运算应用举例
【例8.10】设计一个程序,取出一个整数的第3~5位。 第一种实现方法:
C语言第8章的课件
p1
i1
p1
&i1
10
&i1
p2
i2
p2
&i2
20
&i2
运行
i1 20 i2 10
21
注意
*p1表达式表示指针变量p1指向的对象。在访问指针变量 指向对象前,指针变量必需已指向明确。
如:float *pa,a; *pa=3.14; /*错误,因为pa尚未指向任何变量*/ pa=&a; *pa=3.14;/*给pa指向变量赋值*/
运行
18
几个指针应用的例子
main()
{ int *p1,*p2,i1,i2;
scanf("%d,%d",&i1,&i2);
p1=&i1;
p2=&i2;
printf("%d,%d\n",*p1,*p2);
p2=p1;
printf("%d,%d\n",*p1,*p2);
}
p1
i1
p1
&i1
10
&i1
指针实际上是对存储单元地址的一种形 象化描述。指针即地址。
4
程序中的变量表示命名了的存储区域。不 同类型变量其存储区域字节单元数不一样。
变量名表示该存储区域的别名。变量值是 该存储区域中存储的数据。变量地址是该存储 区域的首地址。
变量地址可通过对变量名进行取地址运算 得到。如:&a得到变量a的地址。
C语言中指针变量也有类型。指针变量 的类型是指指针变量指向对象的类型,即指 针变量存储的指针所表示的对象的类型。
指针变量定义格式:
类型标识符 * 指针变量名; 12
C语言教程课件Ch08函数
REPORT
CATALOG
DATE
ANALYSIS
SUMMARY
C语言教程课件 - 第 8章 函数
目录
CONTENTS
• 函数概述 • 函数参数 • 函数返回值 • 函数与程序结构 • 函数应用示例
REPORT
CATALOG
DATE
ANALYSIS
AR Y
01
函数概述
函数定义
函数定义是创建函数的过程,它 告诉编译器如何执行特定的任务
函数声明也称为函数原型,它出现在 调用函数之前,以确保正确匹配函数 。
函数调用
函数调用是执行函数的过程。 在C语言中,函数调用通过函数名和参数列表实现。
例如,`result = add(3, 4);`调用了`add`函数,并将结果存储在变量`result`中。
REPORT
CATALOG
DATE
ANALYSIS
默认参数:在函数定义中,为某个参数指定一个默认值。 如果在调用函数时没有提供该参数的值,则使用该默认值 。
在此添加您的文本16字
示例
在此添加您的文本16字
函数定义:`int add(int a, int b, int c=10)`
在此添加您的文本16字
调用方式
在此添加您的文本16字
add(3, 5)(此时c的值为10)
SUMMAR Y
02
函数参数
位置参数
位置参数
在函数定义中,按照从左到右 的顺序排列的参数。调用函数 时,需要按照同样的顺序提供
相应的值。
函数定义
int add(int a, int b)
调用方式
add(3, 5)
解释
传递给函数的参数是3和5,它 们分别对应于位置参数a和b。
CATALOG
DATE
ANALYSIS
SUMMARY
C语言教程课件 - 第 8章 函数
目录
CONTENTS
• 函数概述 • 函数参数 • 函数返回值 • 函数与程序结构 • 函数应用示例
REPORT
CATALOG
DATE
ANALYSIS
AR Y
01
函数概述
函数定义
函数定义是创建函数的过程,它 告诉编译器如何执行特定的任务
函数声明也称为函数原型,它出现在 调用函数之前,以确保正确匹配函数 。
函数调用
函数调用是执行函数的过程。 在C语言中,函数调用通过函数名和参数列表实现。
例如,`result = add(3, 4);`调用了`add`函数,并将结果存储在变量`result`中。
REPORT
CATALOG
DATE
ANALYSIS
默认参数:在函数定义中,为某个参数指定一个默认值。 如果在调用函数时没有提供该参数的值,则使用该默认值 。
在此添加您的文本16字
示例
在此添加您的文本16字
函数定义:`int add(int a, int b, int c=10)`
在此添加您的文本16字
调用方式
在此添加您的文本16字
add(3, 5)(此时c的值为10)
SUMMAR Y
02
函数参数
位置参数
位置参数
在函数定义中,按照从左到右 的顺序排列的参数。调用函数 时,需要按照同样的顺序提供
相应的值。
函数定义
int add(int a, int b)
调用方式
add(3, 5)
解释
传递给函数的参数是3和5,它 们分别对应于位置参数a和b。
c语言课件第8章
8.1.2带参宏定义 带参宏定义的一般形式: #define 标识符(形参表) 字符串 其中,形参表是由一个或多个形参组成。 带参宏调用的一般形式:
宏名(实参表);
例:编写一个程序,求3个数中的最大数,要求用带参数 的宏实现。
#include <stdio.h> #define MAX1(a,b) ((a)>(b)?(a):(b)) #define MAX2(a,b,c) (MAX1(a,b)>(c)?MAX1(a,b):(c))
功能:首先计算“常数表达式”的值,如果为真 (非零),就编译“程序段1”,否则编译“程序 段2”。如果没有#else部分,则当“常数表达式” 的值为0时,直接跳过#endif。
例:阅读程序。 #include <stdio.h> main() { #if NULL
printf("NULL is non-zero value!\n"); #else printf("NULL is zero value!\n"); #endif } 运行结果:NULL is zero value!
错
8.2 文件包含
文件包含也是一种预处理语句,它的作用是使一 个源程序文件将另一个源程序文件的全部包含进 来。一般形式为: #include <文件名>或 #include “文件名”
“文件包含”示意图
file1.c
包含
#include”file2.c”
file2.c
A
B
(a)
(b)
file1.c
main() {int a=23;
printf("MAX=%d\n",MAX2(13+5,4,a)); }
C语言课件第八章
例 有参函数 int max(int x,int y) { int z;
z=x>y?x:y; return(z); }
传统风格:
函数类型 函数名(形参表) 形参类型说明
{ 说明部分 语句部分
}
例 有参函数(传统风格) int max(x,y) int x,y; { int z;
z=x>y?x:y; return(z); }
{ int temp; temp=x; x=y; y=temp;
或
return;
}
功能:使程序控制从被调用函数返回到调用函数中, 同时把返回值带给调用函数
说明:
函数中可有多个return语句
若无return语句,遇}时,自动返回调用函数,返回的是一
个不确定的值
若函数类型与return语句中表达式值的类型不一致,按前
float fac(int k) { float t=1; int i;
件中所调用的函数进行了声明,则在各函数中不必再说明。 ▪ 若函数返值是char或int型,系统自动按int型处理
void main() { float add(float a,float b);
float a,b,c; scanf("%f,%f",&a,&b); c=add(a,b); printf("sum is %f",c); } float add(float x, float y) { float z; z=x+y; return(z); }
例 空函数 dummy( ) {}
函数体为空
▪ 8.2.2 有参函数定义 的一般格式
函数返回值类 型
缺省int型 无返回值void
C语言讲义第8章
①实参的个数和形参的个数是否一致;
②实参表达式的类型和形参类型是否相符,如果不符 则需要进行必要的类型转换;
③函数返回值类型和主调函数环境是否相符,如果不 符也需要进行必要的类型转换。
11/15/2019
22
函数声明的形式
函数的声明是函数特征的描述。它将函数的特征告 知编译器。函数声明的一般形式为:
被调函数执行完毕后,恢复主调函数的现场,并处理返回
值。计算机的控制权重新由主调函数接管。主调函数执行
中断点的后继语句,如图8-1所示。
11/15/2019
20
图8-1 函数的调用过程
11/15/2019
函数调用时,主调 函数把实参表达式 的值传递给被调函 数的形参变量。C语 言的参数传递机制 是值的单向传递。 函数调用时的处理 过程如下:
定义函数头部时,参数列表中出现的参数称为形式参数。简 称为形参。
11/15/2019
5
2. 函数体
函数体是函数功能的具体实现过程,是一个普通的 复合结构。一般包括变量的定义和声明部分、语句序 列部分。其一般形式为:
{ 变量定义和声明 语句序列
}
注意:C语言要求变量定义和说明必须放在语句之前
11/15/2019
函数执行到复合结构的末尾,依然会正常结束。虽然没 有return语句,但该函数仍然有返回值。函数的返回值将是一 个随机值,即不确定的值,而不是result的值。
无返回值的函数。当函数的返回值类型定义为“void”时,则 明确表明函数没有返回值。
11/15/2019
12
【例8.3】 定义一个函数,输出6个“*”号。
11/15/2019
24
总结
函数的定义形式 函数类型 函数的参数 函数中形式参数和实际参数的数据传递 函数的返回值
②实参表达式的类型和形参类型是否相符,如果不符 则需要进行必要的类型转换;
③函数返回值类型和主调函数环境是否相符,如果不 符也需要进行必要的类型转换。
11/15/2019
22
函数声明的形式
函数的声明是函数特征的描述。它将函数的特征告 知编译器。函数声明的一般形式为:
被调函数执行完毕后,恢复主调函数的现场,并处理返回
值。计算机的控制权重新由主调函数接管。主调函数执行
中断点的后继语句,如图8-1所示。
11/15/2019
20
图8-1 函数的调用过程
11/15/2019
函数调用时,主调 函数把实参表达式 的值传递给被调函 数的形参变量。C语 言的参数传递机制 是值的单向传递。 函数调用时的处理 过程如下:
定义函数头部时,参数列表中出现的参数称为形式参数。简 称为形参。
11/15/2019
5
2. 函数体
函数体是函数功能的具体实现过程,是一个普通的 复合结构。一般包括变量的定义和声明部分、语句序 列部分。其一般形式为:
{ 变量定义和声明 语句序列
}
注意:C语言要求变量定义和说明必须放在语句之前
11/15/2019
函数执行到复合结构的末尾,依然会正常结束。虽然没 有return语句,但该函数仍然有返回值。函数的返回值将是一 个随机值,即不确定的值,而不是result的值。
无返回值的函数。当函数的返回值类型定义为“void”时,则 明确表明函数没有返回值。
11/15/2019
12
【例8.3】 定义一个函数,输出6个“*”号。
11/15/2019
24
总结
函数的定义形式 函数类型 函数的参数 函数中形式参数和实际参数的数据传递 函数的返回值
C语言第八章PPT课件
printf("*(p+%d)=%-4d",i,*(p+i));
printf("\n");
}
第19页/共38页
19
8.3 通过指针引用数组
• 8.3.2 通过指针引用数组元素
• 指针运算的几个注意事项
• 指针指向的地址,必须是程序已经申请的可用地址
• 指向变量的指针,不能进行加减运算
• 若指针指向数组,则可以进行加、减运算。运算的范围不能超出 数组所在的地址区间
8.1 什么是指针
• 学习指针的几点建议 • 弄明白存放在内存中的数据是如何访问的 • 这是学习指针的基础 • 清晰的记住指针和变量的几个关系: • 指针的内容,指针指向的内容等等 • 明白指针作为函数参数、返回值的作用 • 将地址传递到函数,使得几个函数变量共同操作一个数据地址,实现 数据交换
1
第1页/共38页
8
第8页/共38页
8.2 指针变量
• 8.2.4 指针变量作为函数参数 • 复习:函数参数的传值与传址方式 • 传值:传递后形参不影响实参 • 传址:传递后实参、形参指向同一地址 • 利用传址的特点,改变形参指针指向数据的内容,即可改变对应实参 指针指向的内容 • 利用传址方式,可以让函数在保持独立性的同时,实现对主程序中的 数据进行批量修改的功能。
8.3 通过指针引用数组
• 8.3.2 通过指针引用数组元素 • 指针的运算:仅有加减法运算 • 指针的算术运算,并非单纯的地址运算,而是同时涉及指针的地址、 类型的一种运算 • 指针变量+1,是指指针指向的地址位置为下一个数据位。 • 指针变量+1,要根据指针类型的长度来确定实际地址的增减量 • 即有 • (p+n)的地址=p的地址+sizeof(p的类型)*n
c语言课件第8章
文本文件
*.OBJ
目标文件
二进制文件
*.EXE
可执行文件
二进制文件
文件的存储特性
文件是一个有序的数据序列。C语言把文件作 为一个字符(字节)序列处理,对文件的存取是 以字符(字节)为单位进行的。
2020/9/25
8.1 文件的概述
4
8.1.1 文件和文件指针
1. 什么是文件
设备文件
在C语言中,“文件”的概念被进一步扩大, 把每台与主机相连的输入输出设备都看作是一个 文件。即把实际的物理设备抽象为逻辑文件,它 们被称为设备文件。
向文件写数据时,也是先将 变量中数据送到缓冲区,待缓冲 区装满后,再一起存到磁盘文件 中。
8
程序区
数据区
输入 输出 文件
缓冲区
内存
磁盘文件 输出
输入 外存
图8.2 系统对缓冲文件的处理
2020/9/25
8.1 文件的概述
9
8.1.1 文件和文件指针
3. 缓冲文件和文件指针
文件类型指针
在缓冲文件系统中,对每个正在使用的文件 typ都存ed自e放f 动文ssuthnros件分urictgtn的配ed{有一关个信FlfIelL息vaEegls类,;; 型如//**的文fFii结件llle/构号setmap体、ttuy变s文lfe量件lvaegl状,sof态用b*u、于/ffer */
对外部设备的输入输出就是对设备文件的 读写。
2020/9/25
8.1 文件的概述
5
8.1.1 文件和文件指针
2. 文件的种类
按文件存储数据的形式
➢ ASCII文件(或称文本文件) ASCII码文件中每个字节存放一个ASCII代码,代表
C语言课件第08讲
例 指针运算符的使用
#include <stdio.h> void main( ) {
int a=50, *p;
程序运行结果: *p=50, p=fff4 a=100, &a=fff4
p=&a;
printf("*p=%d, p=%x\n", *p, p);
*p=100;
printf("a=%d, &a=%x\n", a, &a);
p1++; p2--; }
程序运行结果:
a[0]=19 a[1]=17 a[2]=15
• • •
a[9]=1
for(t=0; t<10; t++) printf("a[%d]=%d\n", t, a[t]);
} 指针变量的比较运算经常用于数组,判定两个指针变量所指
向的数组元素的位置先后。
2019/6/16
} void main()
地址值传递
{ int a=10, b=20;
printf("1) a=%d, b=%d\n", a, b);
程序运行结果: 1) a=10, b=20 2) a=20, b=10
Page 17
8.2.4 指针变量的运算
Program Design in C Language
4. 两个指针变量相减:当两个指针变量指向同一数组中的不同
数组元素时,指针变量相减的差值即为两个指针变量相隔的元
素个数。
程序运行结果:
例 相减指针变量逆序数组元素
#include <stdio.h> void main( ) { int a[10]={1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
C语言教程第8章
C程序
源程序文件1 预处理命令 源程序文件2 全局变量声明 函数首部 …… 函数1 源程序文件n …… 函数体 执行语句 函数n
特点:
局部变量声明
1)各模块相对独立、功能单一、结构清晰、接口简单 2)控制了程序设计的复杂性 3)缩短开发周期 4)避免程序开发的重复劳动 5)易于维护和功能扩充
开发方法:
函数声明:
一般形式:函数类型 函数名(形参类型 [形参名],….. ); 或: 函数类型 函数名(); 例如:
作用:告诉编译系统函数类型、参数个数及类型,以便检验。 注意:函数定义与函数声明不同
函数声明的位置:程序的声明部分(函数内或函数外)
下列情况下,可不作函数说明:
(1)若函数返值是char或int型,系统自动按int型处理
在C程序中,一个函数的定义可以放在任意位置,既可放在主函数 main之前,也可放在main之后。 例如:可把我们前面求得的max函数放在main函数之前。 也可以把它放在main函数之后,修改后的程序如下所示。
例8.1求两个整数的最大值。 float max(float a,float b) { if(a>b) return a; else return b; }
例8.1求两个整数的最大值。
main() { float max(float a,float b); float x,y,z; printf("input two numbers:\n"); scanf("%f%f",&x,&y); z=max(x,y); printf("maxmum=%f\n",z); } float max(float a,float b) { if(a>b) return a; else return b; }
源程序文件1 预处理命令 源程序文件2 全局变量声明 函数首部 …… 函数1 源程序文件n …… 函数体 执行语句 函数n
特点:
局部变量声明
1)各模块相对独立、功能单一、结构清晰、接口简单 2)控制了程序设计的复杂性 3)缩短开发周期 4)避免程序开发的重复劳动 5)易于维护和功能扩充
开发方法:
函数声明:
一般形式:函数类型 函数名(形参类型 [形参名],….. ); 或: 函数类型 函数名(); 例如:
作用:告诉编译系统函数类型、参数个数及类型,以便检验。 注意:函数定义与函数声明不同
函数声明的位置:程序的声明部分(函数内或函数外)
下列情况下,可不作函数说明:
(1)若函数返值是char或int型,系统自动按int型处理
在C程序中,一个函数的定义可以放在任意位置,既可放在主函数 main之前,也可放在main之后。 例如:可把我们前面求得的max函数放在main函数之前。 也可以把它放在main函数之后,修改后的程序如下所示。
例8.1求两个整数的最大值。 float max(float a,float b) { if(a>b) return a; else return b; }
例8.1求两个整数的最大值。
main() { float max(float a,float b); float x,y,z; printf("input two numbers:\n"); scanf("%f%f",&x,&y); z=max(x,y); printf("maxmum=%f\n",z); } float max(float a,float b) { if(a>b) return a; else return b; }
《C语言程序设计》电子课件 第8章课件
Your site here
重
8.2结构体类型及其变量的定义
庆
电
子
工 程
1.定义结构体变量的三种方法
职 业
①先定义结构体类型,再定
学
义结构体变量
院
num
name
sex age score
struct stu
计
20070101 李文华
男
18
92.5
{
算
机
int num;
学 院
char name[20];
计
main()
算 机
{ pstu=&boy1;
学
printf("Number=%d\nName=%s\n",boy1.num,);
院
printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);
printf("Number=%d\nName=%s\n",(*pstu).num,(*pstu).name);
}
Your site here
重 庆
8.3结构体数组
电
子 工
1.结构体数组的定义
程
职 业
struct stu
学
{
院
定义了一个结构体数组 boy,共有5个元素,
int num;
boy[0]~boy[4],每
char *name;
计
个数组元素都具有
char sex;
算 机
struct stu的结构形式。 float score;
学 院
{104,"Cheng ling",'F',87},
C语言程序设计课件第八章-PPT文档资料
8.2 结构
8.2.1.2结构变量定义 结构变量定义有4种方法: (2) 声明类型同时,定义结构变量 struct 结构名 {成员说明序列} 结构变量表; 例:struct point { double x, y, z; } p1,p2,*p3; 说明结构类型point, 并定义三个变量。
8.2 结构
第八章 结构及其它
本章的主要内容包括: C语言的类型定义 结构 联合 位运算和位段
回首页
8.1 类型定义
写程序时自己定义的数据类型称作“用户定义类型”。 形式: typedef 类型名 标识符; typedef的作用仅仅是用新类型名来代表已存在的类型名,并未产 生新的数据类型。原有的类型名依然有效。 新的类型名可以和C语言中原有的各种基本类名一样,方便地用于 定义变量、定义函数的返回值、定义其它构造类型的元素或成 员。 例8.1:typedef int INTEGER; 给int类型一个新的名字INTEGER,此后,可以用INTEGER来定义整 型变量。如:INTEGER i,j,a[10]; 例8.2:typedef char * CHARP; 新类型名CHARP是字符指针类型,表示的旧类型是char *。 CHARP p; 等价于: char *p; 例8.3:typedef double VECT[4]; 定 义 一 种 具 有 4 个 元 素 的 双 精 度 数 组 类 型 VECT ; 程 序 中 VECT v1,v2;定义两个4个元素的双精度数组。
8.2 结构
结构可以将若干个不同类型的数据组合成一个复合数据对象。组 成结构的数据项称结构的成分或成员。 结构类型成员的数量必须固定,但该结构中各个成员的类型可以 不同。
8.2.1 结构类型说明、结构变量定义
C语言程序设计课件第8章
main() {struct num a[3]={{"zhangsan",0},{"lisi",0},{"wangwu",0}}; int i,j; char inputname[20]; printf("please input the list of candidate:\n"); for(i=0;i<40;i++) {scanf("%s",inputname); for(j=0;j<3;j++) if(strcmp(inputname,a[j].name)==0) a[j].number++;} printf("\n"); for(i=0;i<3;i++) printf("%10s:%2d\n",a[i].name,a[i].number); }
例如:
struct student
{
int number;
char name[10];
int age;
float score;
}
... ... ...
struct student *p;
... ... ...
/* 定义结构体类型 */ /* 定义指向结构体类型变量的指针变量
第8章 结构体与共用体
⑵ 指向结构体类型变量的指针变量引用 利用指向结构体类型的指针变量引用结构体变量成员的一
printf("\n NAME No. SCORE1 SCORE2 SCORE3 AVE\n"); printf("---------------------------------------------------\n"); for(i=0;i<n;i++)
例如:
struct student
{
int number;
char name[10];
int age;
float score;
}
... ... ...
struct student *p;
... ... ...
/* 定义结构体类型 */ /* 定义指向结构体类型变量的指针变量
第8章 结构体与共用体
⑵ 指向结构体类型变量的指针变量引用 利用指向结构体类型的指针变量引用结构体变量成员的一
printf("\n NAME No. SCORE1 SCORE2 SCORE3 AVE\n"); printf("---------------------------------------------------\n"); for(i=0;i<n;i++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
add( )
sub2( )
sub3( )
add2( )
add3( ) add2( )
二、函数的类型
函数的类型: 函数的类型: 1 从用户使用的角度来说 1) 库函数 标准函数 库函数(标准函数 标准函数p381附录 附录5) 附录 2) 用户自定义函数 2 从函数的形式来看 1)无参函数 无参函数 void a1( ) { printf(“******************\n”);}
(4) 程序进行编译时,并不为形式参数分配存储单元, 程序进行编译时,并不为形式参数分配存储单元, 只有它所在的函数被调用时, 只有它所在的函数被调用时,给形参分配存储单 并将实参的值传递给形参; 元,并将实参的值传递给形参;函数调用结束其所 /*例5 c5.c*/ /*例 占空间被释放 main() #include <stdio.h> { int min(int x,int y) int a,b,k; { scanf(“%d%d %d%d”,&a,&b); scanf( %d%d ,&a,&b); int n; k=min(a,b a,b); k=min(a,b); if (x<y) n=x; printf(“min %d\ ,k); printf( min is %d\n”,k); else n=y; } return n; }
… 计算机教学部
… …
add2()
add3()
教学部1室 教学部 室
教学部2室 教学部 室
5 主函数可以调用其它函数,其它函数之间也可以 主函数可以调用其它函数, 相互调用,但其它函数不能调用主函数, 相互调用,但其它函数不能调用主函数,主函数 是由系统调用的。 是由系统调用的。
main( )
sub( )
/*主调函数与被调用函数之间不存在数据传递,只用来执行特定的操作*/ 主调函数与被调用函数之间不存在数据传递,只用来执行特定的操作 主调函数与被调用函数之间不存在数据传递
2)有参函数 有参函数 int ab(x,y) int x,y; { int n; n=(x<y)?x:y; return n;} int ab(int x,int y) { int n; n=(x<y)?x:y; return n;}
3) 实际参数(实参) 实际参数(实参) 在调用函数时, 在调用函数时,函数名后圆括弧中的表达式称为实 际参数。 实参可以是有确定值的变量、 际参数。(实参可以是有确定值的变量、常量或表达 式且与形参类型应一致) /*例 式且与形参类型应一致) /*例5 c5.c*/ #include <stdio.h> int min(int x,int y) { int n; if (x<y) n=x; else n=y; return n; } main() { int a,b,k; scanf(“%d%d %d%d”,&a,&b); scanf( %d%d ,&a,&b); a,b); k=min(a,b k=min(a,b); printf(“min %d\ ,k); printf( min is %d\n”,k); }
c3.c*/
/*程序较大时,要将一些相关语句组织成函数,以简化主函数的设计*/ 程序较大时,要将一些相关语句组织成函数,以简化主函数的设计 程序较大时
3 函数 是具有特定功能的模块,它是构成C程序的基本 是具有特定功能的模块,它是构成 程序的基本 单位, 程序的运行由主函数开始 程序的运行由主函数开始, 单位,C程序的运行由主函数开始,主函数通过 调用一系列函数来实现各种功能。 调用一系列函数来实现各种功能。 例4 c4.c #include <stdio.h> main( ) main( ) { int a=-1;float k; abs( ) printf( ) sqrt( ) k=4.0; a=abs(a); /*求绝对值 求绝对值*/ 求绝对值 k=sqrt(k); /*求平方根 求平方根*/ 求平方根
void dum( ) { } 说明:在编写程序的开始阶段, 说明:在编写程序的开始阶段,在将来准备扩充 功能的地方写上一个空函数,先占一个位置 先占一个位置, 功能的地方写上一个空函数 先占一个位置, 以后用一个编好的函数来代替它。 以名应符合C语言对标识符的规定, 1)函数名应符合C语言对标识符的规定,函数名后的一 函数名应符合 对园括号是函数的象征. 对园括号是函数的象征. int max(int x,int y) { int n; n=(x>y)?x:y; return n; }
打印n 打印n 个*的函数 void spc( int n) { int i; for( i=0; i<n;i++) printf(“*”); return ; }
注意:在一个函数中,允许有一个或多个 注意:在一个函数中,允许有一个或多个return语 语 只要执行其中一个return语句时流程即返回主 句。只要执行其中一个 语句时流程即返回主 调函数 x2 − x +1 (x < 0) 例 :设 y = 设
#include <stdio.h> /*例7 c7.c*/ /*例 int min(int x,int y) { int n; if (x<y) n=x; else n=y; return n; } main() { int a,b,k=0; scanf(“%d%d %d%d”,&a,&b); scanf( %d%d ,&a,&b); /*实参为表达式 实参为表达式*/ 实参为表达式 a+5,b+k); k=min(a+5,b+k k=min(a+5,b+k); printf(“min %d\ ,k); printf( min is %d\n”,k); }
(3)在函数体内形参可以被引用,可以输入、输 在函数体内形参可以被引用,可以输入、 被赋予新值或参加运算。 出、被赋予新值或参加运算。 int ab1(int x,int y) { int sum; printf(“x is %d\n”,x); /*形参可输出 形参可输出*/ 形参可输出 scanf(“%d”,&y); /*形参可输入 形参可输入*/ 形参可输入 sum=x+y; /*可参与运算 可参与运算*/ 可参与运算 printf(“x+y=\n”,sum ); x*=2; /*可赋于新值 可赋于新值*/ 可赋于新值 y*=2; printf(“2x+2y=%d”,x+y); }
/*例2 c2.c*/ 例 #include <stdio.h> main( ) { int a,b,min,max; printf(“please input to a and b:\n”); scanf(“%d%d”,&a,&b); if (a>=b) max=a; else max=b; printf(“max is %d\n”,max); if (a<=b) min=a; else min=b; printf(“min is %d\n”,min); }
例8
四、 函数的返回
c8.c
#include <stdio.h> float pow1(int n) 函数执行的最后一个操作 {int k; 是返回。返回的意义是: 是返回。返回的意义是: float sum=1; for (k=1;k<=n;k++) 1)使流程返回到主调函数 使流程返回到主调函数, 1)使流程返回到主调函数, sum*=k; 宣告函数的一次执行结束。 宣告函数的一次执行结束。 return sum; } 在调用期间分配的形参单 main() 元撤销。 元撤销。 { 2)送函数值到调用表达式中 送函数值到调用表达式中。 2)送函数值到调用表达式中。 float s;/*s用来求 的阶乘 用来求15的阶乘 用来求 的阶乘*/ s=pow1(15); 但这一点并非必要。 但这一点并非必要。 printf(“15!=%f\n”,s); }
/*实参为变量 实参为变量*/ 实参为变量
#include <stdio.h> /*例6 c6.c*/ /*例 int min(int x,int y) { int n; if (x<y) n=x; else n=y; return n; } main() { printf(“min %d\ ,min(7,8)); ,min(7,8 printf( min is %d\n”,min(7,8)); /*实参为常量*/ 实参为常量* } /*实参为常量
例9
c9.c
#include <stdio.h> void pt( ) { char dm[17]={“I am a student”}; puts(dm); } /*函数体右侧花括弧起到返回的作用 函数体右侧花括弧起到返回的作用*/ 函数体右侧花括弧起到返回的作用 main() { pt( ); printf(“\n”); }
第八章
函数
本章重点 1 函数的定义方法 2 函数的调用形式 3 实参与形参之间的传递方式 函数的嵌套调用与递归调用 4 函数的嵌套调用与递归调用 变量的存储类别、作用域和生存期 5 变量的存储类别、作用域和生存期
一、概述 1 一个简单的 程序只要有一个主函数就可完成特定功能 一个简单的C程序只要有一个主函数就可完成特定功能 例1:c1.c : #include <stdio.h> main() { int a[3][3],t,k; for(t=0;t<=2;t++) for (k=0;k<=2;k++) a[t][k]=t*k; for(t=0;t<=2;t++) for (k=0;k<=2;k++) printf(“%4d”,a[t][k]); }