• 1. 主要内容 Contents第一讲 C语言程序设计入门 第二讲 数据类型、运算符和表达式 第三讲 顺序结构 第四讲 选择结构 第五讲 循环结构 第六讲 函数 第七讲 数组与字符串 第八讲 指针 第九讲 结构 第十讲 文件处理 第十一讲 预处理器Program Design in C Language双语课堂Introduction Data types, operators and expressions Sequence structure Selection structure Repetition structure Functions Arrays and strings Pointers Structures File processing The preprocessor学习程序设计的目的是进行程序设计的基本训练,掌握程序设计的基本方法。 We will learn the C programming language and structured programming techniques.
  • 2. 参考书目 ReferencesThe C Programming Language Brian W. Kernighan Dennis M. Ritchie C How to Program Harvey M. Deitel Paul J. Deitel C 语言程序设计 杨健霑 刘英 康卓 Data Structure & Program Design in C Robert Kruse Clovis L. Tondo Bruce P. LeungPROGRAM DESIGN IN C LANGUAGE双语课堂目 录
  • 3. 第一讲 C语言程序设计入门 IntroductionProgram Design in C Language双语课堂目 录1.2 C语言的发展C Language's Evolution1.3 结构化程序设计Structured Programming1.4 C程序的基本结构Basic Structure of A C Program1.5 C语言程序的开发C Program Development1.1 计算机基础回顾Review of Computer Basic
  • 4. 计算机系统 Computer System计算机(Computer) 能进行计算(computations)和逻辑判断(logical decisions) 在一组指令(instructions)——程序(programs)的控制下处理数据(process data) 硬件(Hardware) Various devices comprising a computer Keyboard, screen, mouse, disks, memory, CD-ROM, and processing units 软件(Software) Programs that run on a computerREVIEW OF COMPUTER BASIC双语课堂目 录第一讲 C语言程序设计入门
  • 5. 计算机的组织 Computer Organization计算机包括六大部件: Input unit(输入单元) Obtains information from input devices (keyboard, mouse) Output unit(输出单元) Outputs information (to screen, to printer, to control other devices) Memory unit(内存) Rapid access, low capacity, stores input information Central processing unit (CPU)(中央处理单元) Arithmetic and logic unit (ALU)(算术逻辑单元) Performs arithmetic calculations and logic decisions Control unit(控制器) Supervises and coordinates the other sections of the computer Secondary storage unit(辅助存储器) Cheap, long-term, high-capacity storage Stores inactive programsREVIEW OF COMPUTER BASIC双语课堂目 录第一讲 C语言程序设计入门
  • 6. 计算机语言 Computer Language三种编程语言(programming language): 机器语言(Machine language) 机器指令(machine instruction) 汇编语言(Assembly language) 类似英文的缩写来表示基本操作(elementary operation) 通过汇编程序(assembler)翻译成机器语言 高级语言(High-level language) 代码(code)类似日常英语 使用数学符号(mathematical notations) 通过编译程序(compiler)翻译成机器语言REVIEW OF COMPUTER BASIC双语课堂目 录第一讲 C语言程序设计入门0110001100000110 0110010111001100 0000110000011011LOAD X ADD Y STORE ZZ = X + YMachine LanguageAssembly LanguageHigh-level Language
  • 7. C语言的发展 C Language’s EvolutionTraditional C Evolved by Ritchie from two previous programming languages, BCPL and B Used to develop UNIX Used to write modern operating systems Hardware independent (portable)(可移植) By late 1970's C had evolved to "Traditional C" 标准化(Standardization) 许多互不兼容(incompatible)的C的变种(variations),差异很小 成立委员会建立 “unambiguous, machine-independent” (明确的,独立于机器的)定义 正式的标准诞生于1989年(C89), 在1999作了重大更新(C99)C LANGUAGE’S EVOLUTION AND FEATURES双语课堂目 录第一讲 C语言程序设计入门
  • 8. 程序概念 Program Concept程序的概念 程序是计算机解决问题所需的一系列指令的集合。 A program is a set of self-contained instructions that tells a computer how to solve a problem or carry out a task. 程序=数据结构+算法+程序设计方法+语言工具和编程环境 数据结构(Data structure)是数据的类型和数据的组织形式。 算法(Algorithm)是为解决某个特定的问题而采用的确定且有限的步骤。 程序设计方法(Programming method) 语言工具和编程环境(Language tools and programming environment)STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门
  • 9. 例1-1 简单程序设计 A Simple Program Design问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 定义数据结构 Define data structure 设计算法 Design algorithm 确定程序设计方法 Select a programming method 确定语言和开发环境 Select a computer language and programming environment 实现 ImplementationSTRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门
  • 10. 例1-1 简单程序设计 A Simple Program Design (1/5)问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 1:定义数据结构 根据问题确定哪些是已知数据,哪些是通过计算得到的数据。对输入、输出和存储的数据进行描述,指定数据的类型和数据的组织形式。 定义以下变量(variables):STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门a、b、c (保存输入的系数) p、disc、q (保存中间结果) x1、x2 (保存最后的结果)
  • 11. 例1-1 简单程序设计 A Simple Program Design (2/5)问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 2:设计算法 根据数学知识,知道此时方程有两个根 那么,可以确定解方程的方法和步骤:STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门输入a,b,c; 计算-b/2a,把结果存入p,即p=-b/2a; 计算b2-4ac,把结果存入disc,即disc=b2-4ac; 计算 ,把结果存入q,即q= ; 计算p+q和p-q,把结果存入x1和x2,即x1=p+q,x2=p-q; 输出x1和x2。
  • 12. 例1-1 简单程序设计 A Simple Program Design (3/5)问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 3:确定程序设计方法 结构化程序设计(Structured programming) 严格的方法(disciplined approach) 清晰(clear),便于测试(test)、调试(debug)和修改(modify) 面向对象程序设计(Object-oriented programming) 可重用(reusable) 更易理解(understandable),更好的组织(organized),更利于维护(maintain) 支持模块性(modularity) 这里,采用结构化程序设计方法。STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门
  • 13. 例1-1 简单程序设计 A Simple Program Design (4/5)问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 4:确定语言和开发环境 采用C语言 在Borland C 3.1开发环境下进行程序设计STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门
  • 14. 例1-1 简单程序设计 A Simple Program Design (5/5)问题 求方程ax2+bx+c=0的根(设b2-4ac≥0) 程序设计步骤 5:实现 编写C语言程序STRUCTURED PROGRAMMING双语课堂目 录第一讲 C语言程序设计入门#include void main() { float a, b, c, p, disc, q, x1, x2; scanf(“%f%f%f”, &a, &b, &c); p=-b/(2*a); disc=b*b-4*a*c; q=sqrt(disc)/(2*a); x1=p+q; x2=p-q; printf(“x1=%f, x2=%f”, x1, x2); } /*CW01-01.C*/例: x2=4 即 a=1 b=0 c=-4
  • 15. C程序的基本结构 Basic Structure of A C ProgramExample 1-3: Hello World 在屏幕上打印一行文字。 Program BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门Comments(注释) Preprocessor directive(预处理命令) Function(函数) Statement(语句) Return 0;(返回语句)/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }Hello World!
  • 16. C程序的基本结构 Basic Structure of A C Program (Cont.1/5)BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }注释(Comment) /* 文本 */ 不被执行 用来对程序进行描述
  • 17. C程序的基本结构 Basic Structure of A C Program (Cont.2/5)BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }预处理命令(Preprocessor directive) 告诉计算机包含某一文件的内容 定义了标准输入/输出操作
  • 18. C程序的基本结构 Basic Structure of A C Program (Cont.3/5)BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }函数(Function) C程序包含一个或多个函数,其中必须有一个 main 函数 圆括号(Parenthesis)指示一个函数 int 表示 main 函数返回(return)一个整数值(integer value) { } (braces)包含函数体(body) }(right brace)表示 main 函数结束
  • 19. C程序的基本结构 Basic Structure of A C Program (Cont.4/5)BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }语句(Statement) 一行称为一条语句 必须以 ; ( semicolon )结尾 命令计算机完成一个操作(action)
  • 20. C程序的基本结构 Basic Structure of A C Program (Cont.5/5)BASIC STRUCTURE OF A C PROGRAM双语课堂目 录第一讲 C语言程序设计入门/* Example 1-3 (CW01-03.C) Print a line of text. This is my first c program.*/ #include int main() { printf("Hello World!"); return 0; }Return 0; 退出函数的一种方法
  • 21. C程序的开发阶段 Phases of C Program DevelopmentC PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerCPULoaderProg.objProg.exeRAMLibrariesSource file(源文件)Object file(目标文件)Library file(库文件)Executable file(可执行文件)
  • 22. C程序的开发阶段 Phases of C Program Development (1/4)C PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerCPULoaderProg.objProg.exeRAMLibrariesEdit(编辑) Program is created in the editor and stored on disk.
  • 23. C程序的开发阶段 Phases of C Program Development (2/4)C PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerCPULoaderProg.objProg.exeRAMLibrariesCompile(编译) Preprocessor program processes the code. Compiler creates object code and stores it on disk.
  • 24. C程序的开发阶段 Phases of C Program Development (2/4)C PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerCPULoaderProg.objProg.exeRAMLibrariesLink(链接) Linker links the object code with the libraries.
  • 25. C程序的开发阶段 Phases of C Program Development (4/4)C PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerCPULoaderProg.objProg.exeRAMLibrariesExecute(运行) Loader puts program in memory. CPU takes each instruction and executes it, possibly storing new data values as the program executes.
  • 26. C程序的开发工具 C Program Development ToolsC PROGRAM DEVELOPEMNT双语课堂目 录第一讲 C语言程序设计入门EditPreprocessCompileLinkLoadExecuteEditorProg.cCompilerLinkerProg.objProg.exeLibrariesIntegrated Development Environment (IDE)(集成开发环境) Turbo C/C++ Borland C/C++ Visual C/C++IDE
  • 27. 第二讲 数据类型、运算符和表达式 Data Types,Operators and ExpressionsPROGRAM DESIGN IN C LANGUAGE双语课堂目 录2.2 变量Variables2.3 数据类型Data Types2.4 常量Constants2.5 整型数据Integers2.1 字符集 标识符 关键字Character Set, Identifiers and Keywords2.7 字符型数据Characters2.8 字符串常量String Constants2.9 算术运算符Arithmetic Operators2.10 类型转换Type Conversion2.6 浮点型数据Floating-point Data2.11 赋值运算符Assignment Operators2.12 逗号运算符Comma Operator
  • 28. 字符集 Character SetC 语言源程序文件是来自一个字符集的字符序列。 A C source file is a sequence of characters selected from a character set. C 语言的字符集(character set) 52个大小写字母(Letters) A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 10个数字(Digits) 0 1 2 3 4 5 6 7 8 9 空格(SPACE) 制表符(Tab) 图形符号(Graphic characters) ! # % ^ & * ( _ ) - + = ~ [ ] ' | \ ; : " {} , . < > / ?CHARACTER SET, IDENTIFIERS AND KEYWORDS双语课堂目 录第二讲 数据类型、运算符和表达式
  • 29. 标识符 Identifiers标识符(Identifiers) 是一个字符序列,包括大小写字母(capital and small letters),数字(digits)和下划线(the underscore character)。 用来标识变量名、符号常量名、数组名、函数名、结构名、类型名等。 命名规则 首字符必须是字母或下划线; 一般内部标识符的前31个字符有效,而外部标识符的前6个字符有效; 不能与关键字相同。CHARACTER SET, IDENTIFIERS AND KEYWORDS双语课堂目 录第二讲 数据类型、运算符和表达式i j k n1 n2 sum display_matrix _time1 2x !here money$ void main integer date-timeOKInvalid
  • 30. 关键字 KeywordsKeywords The following identifiers are reserved for use as keywords, and may not be used as ordinary identifiers:CHARACTER SET, IDENTIFIERS AND KEYWORDS双语课堂目 录第二讲 数据类型、运算符和表达式auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
  • 31. 变量 Variables变量(Variables) 变量是在程序执行过程中其值会发生变化的量。 Variables are program elements that change their values during the course of program execution. 声明(Declaration) [,[,...]] 变量在使用之前必须被声明。VARIABLES双语课堂目 录第二讲 数据类型、运算符和表达式int x , y ; int sum=0 ; float volt ; char degree ;变量名(name)是一个标识符变量类型(type)变量可以在声明时被初始化(initialized)
  • 32. 变量与内存 Variables and Memory变量与内存(Variables and Memory) 每一个变量有名字(name),类型(type),大小(size)和值(value) 变量名对应于它在内存中的位置(location) 当一个新的值被放进(placed into)变量时,它将替换(replace)掉以前的值 从内存中读取变量的值不会改变它 A visual representationVARIABLES双语课堂目 录第二讲 数据类型、运算符和表达式int x = 23;23FF022BytesRAMx = 90;90printf(“%d”, x);
  • 33. 变量初始化 Variables InitializationInitialization A variable may be initialized in its declaration. If the variable in question is not automatic, the initialization is done once only, conceptually before the program starts executing, and the initializer must be a constant expression. Automatic variables for which there is no explicit initializer have undefined values.VARIABLES双语课堂目 录第二讲 数据类型、运算符和表达式char esc = ‘\\’; int i = 0, limit = MAXLINE+1; float eps = 1.0e-5;Initializer
  • 34. 数据类型 Data TypesC 语言的数据类型 基本类型 整型(integer):int, short, long 字符型(character):char 浮点型(floating-point):float, double 枚举类型(enumeration):enum 构造型 结构体(structure):struct 共用体(union):union 数组(array) 指针类型(pointer) 空类型(void):voidDATA TYPES双语课堂目 录第二讲 数据类型、运算符和表达式
  • 35. 基本类型 Basic Types基本数据类型(Basic data types): 字符型(char) a single byte, capable of holding one character 基本整型(int) an integer, typically reflecting the natural size of integers on the host machine 单精度浮点型(float) single-precision floating point 双精度浮点型(double) double-precision floating point 此外,有几个修饰符(qualifiers)可以加到基本数据类型上 short long signed unsignedDATA TYPES双语课堂目 录第二讲 数据类型、运算符和表达式
  • 36. 常量 Constants常量(Constants) 常量是在程序执行过程中其值不变化的量。 Constants are program elements that do not change their values during the course of program execution. C语言有以下几种类型的常量: 整型常量(integer constants) 浮点型常量(floating-point constants) 字符型常量(character constants) 字符串型常量(string constants)CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式
  • 37. 符号常量 Symbolic Constants符号常量 符号常量是用一个标识符表示的常量。 定义规则 #define Symbolic constants are handled by the C preprocessor and are defined using the #define construct. It is a good programming practice to use symbolic constants where possible. This enables certain changes be made with a minimal amount of efforts.CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式#define MAXSIZE 20 #define WELCOME "Welcome to you!" #define PI 3.14
  • 38. 例2-1 符号常量的应用 Symbolic Constants ApplicationProblem Calculate area of a circle. ProgramCONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-1 CW02-01.C Calculate area of a circle.*/ #include #define PI 3.14 void main() { float r, area; scanf("%f",&r); area = PI*r*r; printf("area=%f",area); }1 3.140000arear
  • 39. 整数的类型和大小 Integer Types and Sizes在微机中,不同类型的整型数据在内存中占的字节数如下表:Integer VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式类型名称类型说明符字节数数值范围基本整型[signed] int2-32768~32767短整型[signed] short [int]2-32768~32767长整型[signed] long [int]4-2147483648~ 2147483647无符号基本整型unsigned [int]20~65535无符号短整型unsigned short [int]20~65535无符号长整型unsigned long [int]40~4294967295
  • 40. 回顾:整数的存储 Review: Integer Storage (1/3)正整数在内存中以二进制原码形式存放。 有符号正整数 10INTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式符号位0 0 0 0 0 0 0 00 0 0 0 1 0 1 00000000000001010RAM
  • 41. 回顾:整数的存储 Review: Integer Storage (2/3)负整数在内存中以二进制补码的形式存放。 有符号负整数 -10INTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式符号位1 1 1 1 1 1 1 11 1 1 1 0 1 1 01111111111110110RAM10的原码0 0 0 0 0 0 0 00 0 0 0 1 0 1 01 1 1 1 1 1 1 11 1 1 1 0 1 0 11 1 1 1 1 1 1 11 1 1 1 0 1 1 0按位取反加一后得到 -10的补码
  • 42. 回顾:整数的存储 Review: Integer Storage (3/3)无符号整数的所有二进制位都存放数值。 无符号整数 65535uINTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式1 1 1 1 1 1 1 11 1 1 1 1 1 1 11111111111111111RAM
  • 43. 整型常量 Integer Constants有三种形式: 十进制(decimal)整数 12 65 65535 八进制(octal)整数:带前缀 0(zero) 014 0101 0177777 十六进制(hexadecimal)整数:带前缀 0x 或 0X 0xc 0x41 0xffff 可以加上后缀 u 或 U 表示无符号整数(unsigned),或者 l 或 L 表示长整数(long)。 0xb5LuINTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式
  • 44. 例2-2:整型变量和常量 Integer Variables and ConstantsExample 2-2: Integer Variables and ConstantsINTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-2 CW02-02.C Integer Variables and constants.*/ #include void main() { int a, b; unsigned c, d; a=32767; b=-32768; c=32768; d=65535; printf("a=%d,b=%d\n", a, b); printf("c=%u,d=%u", c, d); }a=32767,b=-32768 c=32768,d=65535
  • 45. 例2-2:整型变量和常量 Integer Variables and Constants (Cont.)Modified Example 2-2INTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-2 CW02-02M.C Integer Flowout.*/ #include void main() { int a, b; unsigned c, d; a=32767; b=a+1; c=32768; d=65535; printf("a=%d,b=%d\n", a, b); printf("c=%u,d=%u", c, d); }a=32767,b=-32768 c=32768,d=65535???
  • 46. 溢出 OverflowAnalyzes Example 2-2 结论:a+1 的结果(32768) 超出了基本整型变量 b 所能容纳(表示)的数值范围(-32768~32767),这种情况称为“溢出”。INTEGER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0a(32767)1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0a+1(32768)b(-32768)
  • 47. 浮点数的类型和大小 Floating-point Types and Sizes在微机中,不同类型的浮点型数据在内存中占的字节数如下表:FLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式类型名称类型说明符字节数有效数字数值范围单精度float46~710-37~1038双精度double815~1610-307~10308长双精度long double1018~1910-4931~104932
  • 48. 回顾:浮点数的存储 Review: Floating-point Data Storage浮点型数据在内存中按指数形式存放。 举例 3.14159FLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式0 (0.314159)10 0 (1)10 数符 小数部分 阶符 阶码 + 0.314159 × 10+1由此可见,小数部分的宽度决定了有效数字(精度),阶码部分的宽度决定了数值范围。
  • 49. 浮点型常量 Floating-point Constants有两种形式: 十进制小数 12.3 .65 0. 指数形式:< 小数 > < e | E > < 整数 > 1.2e-2 .1E5 7E0 可以加上后缀 f 或 F 表示float类型,或者 l 或 L 表示long double类型,否则该常量是double类型。 2.3f 1.2L .1E5fFLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式
  • 50. 例2-3:浮点型变量和常量 Floating-point Variables and ConstantsExample 2-3: Floating-point Variables and ConstantsFLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-3 CW02-03.C Floating-point variables and constants.*/ #include void main() { float f; double d; f=33333.33333; d=33333.3333333333; printf("f=%f\nd=%f", f, d); }f=33333.332031 d=33333.333333实数的有效数字是有限的,在有效位之外的数字被舍去。由此可能会产生一些误差。
  • 51. 例2-4:浮点型数据的舍入误差 Floating-point Rounding ErrorExample 2-4: Floating-point Rounding ErrorFLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-4 CW02-04.C Floating-point rounding error.*/ #include void main() { float a, b; a=123456.789e5; b=a+20; printf("a=%f\nb=%f", a, b); }a=12345678848.000000 b=12345678848.000000???
  • 52. 舍入误差分析 Analyze Floating-point Rounding ErrorAnalyze Example 2-4FLOATING-POINT VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式a=123456.789e5; b=a+20;a+20的理论值应该是:12345678920 但是,一个实型变量能够保证的有效数字是7位,后面的数字将被舍去,是没有意义的。 因此,最后得到 b=12345678848.000000由此可知,应当避免一个很大的数和一个很小的数直接相加或相减,否则就会“丢失”较小的数。1.0/3*3=?
  • 53. 字符型常量 Character Constants字符型常量 用单引号(single quote)括起来的一个字符。 'x' '9' '+' 转义字符(escape character) 指代一些特殊的字符。CHARACTER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式\a alter(bell) character \\ backslash \b backspace \? question mark \f formfeed \' single quote \n newline \" double quote \r carriage return \ooo octal number \t horizontal tab \xhh hexadecimal number \v vertical tab
  • 54. 例2-5:转义字符 Escape CharacterExample 2-5: Escape CharacterCHARACTER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-5 CW02-05.C Escape character.*/ #include void main() { printf(" ab c\t de\rf\tg\n"); printf("h\ti\b\bj k"); }f gde h j kf ab c gde h jik输出到显示屏打印机输出
  • 55. 字符数据的存储 Character Storage在内存中,是把一个字符的ASCII码以二进制形式存放的,占一个字节。 Example:CHARACTER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式char c1, c2; c1=‘a’; c2=‘b’;0 1 1 0 0 0 0 1字符 a 的ASCII码(值)为97c10 1 1 0 0 0 1 0字符 b 的ASCII码(值)为98c2与整型数据的存储形式类似,因此两者之间的转换非常方便,可以把字符数据当作整型数据来用。
  • 56. 例2-6:字符变量 Character VariablesExample 2-6:Character VariablesCHARACTER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-6 CW02-06.C Assign integers to character variables.*/ #include void main() { char c1, c2; c1=97; c2=98; printf("c1=%c,c2=%c\n", c1, c2); printf("c1=%d,c2=%d", c1, c2); }c1=a,c2=b c1=97,c2=98
  • 57. 例2-7:字符变量 Character VariablesExample 2-7:Character VariablesCHARACTER VARIABLES AND CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-7 CW02-06.C Convert lowercase character to uppercase.*/ #include void main() { char c1, c2; c1=97; c2=c1-32; printf("c1=%c,c2=%c\n", c1, c2); }c1=a,c2=A
  • 58. 字符串常量 String Constants字符串常量 用双引号(double quote)括起来的字符序列。 "this is a string" "x" "12345" The double quotes are not part of the string, but only to delimit it. A string constant is actually represented internally as an array of characters terminated by the null character '' (\0).STRING CONSTANTS双语课堂目 录第二讲 数据类型、运算符和表达式‘x’x在内存中占一个字节“x”x在内存中占两个字节\0
  • 59. 算术运算符 Arithmetic Operators算术运算符(Arithmetic operators) 算术计算(Arithmetic calculations) 整数相除截去(truncates)余数(remainder) 7 / 5 1 取模运算(%)返回相除后的余数,不能用于 float 或 double 型数据 7 % 5 2ARITHMETIC OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式C operationArithmetic operatorAlgebraic expressionC expressionAddition+f + 7f + 7Subtraction-p – cp – cMultiplication*bmb * mDivision/x / yx / yModulus%r mod sr % s
  • 60. 算术运算符的优先级 Arithmetic Operator Precedence运算符优先级(Operator precedence) 某些运算符先于其他运算符被执行 (例如,先乘除后加减) 必要时可以用()改变计算顺序 Example: Find the average of three variables a, b and c Do not use: a + b + c / 3 Use: (a + b + c ) / 3 优先级和结合性(precedence and associativity)ARITHMETIC OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式Operator(s)Operation(s)PrecedenceAssociativity()parenthesis1left to right*, /, %Multiplication, division, modulus3left to right+ or -Addition or subtraction4left to right
  • 61. 算术表达式 Arithmetic Expressions算术表达式(Arithmetic expression) 算术表达式,是由算术运算符和括号将运算对象(也称为操作数)连接起来的式子 运算对象包括常量、变量、函数等 Examples:ARITHMETIC OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式7/5 x+y+z (f1*2)/f2+0.5 sqrt(a)+sqrt(b)数学函数
  • 62. 例2-8:算术运算 ArithmeticExample 2-8: Arithmetic calculationARITHMETIC OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-8 CW02-08.C Arithmetic calculation.*/ #include void main() { float f1; float f2; f1=1/3; f2=1.0/3.0; printf("f1=%f\nf2=%f", f1, f2); }f1=0.000000 f2=0.333333
  • 63. 类型转换 Type Conversion在算术表达式中允许不同类型的数据参与运算 Example: 10+‘a’+1.5-8765.1234*’b’ 在进行运算时,不同类型的数据要先转换成同一类型,然后进行运算 转换方式有两种: 自动转换:数据类型自动由低级向高级转换 强制转换:将表达式的运算结果强制转换成指定的数据类型TYPE CONVERSION双语课堂目 录第二讲 数据类型、运算符和表达式
  • 64. 自动类型转换 Automatic Type Conversion这种类型转换由编译系统自动完成。 转换规则:TYPE CONVERSION双语课堂目 录第二讲 数据类型、运算符和表达式floatdoublelongunsignedintChar short低高说明: 1、横向的箭头表示必定的转换。 2、纵向的箭头表示当运算对象类型不同时转换的方向。
  • 65. 强制类型转换 Type Conversion类型转换运算符: ( ) 将一个表达式转换成所需类型 表达式: ( type-specification ) [(] expression [)] Examples: (double)a (int)(x+y) ≠(int)x+y (float)(5/3) =1.0 强制转换属单目运算,运算优先级为2 强制转换得到的是中间变量类型,原变量类型不变TYPE CONVERSION双语课堂目 录第二讲 数据类型、运算符和表达式
  • 66. 例2-13:类型转换 Type Conversion下面表达式的类型是什么? 10+‘a’+1.5-87.1*’b’ Example 2-13: Type conversionTYPE CONVERSION双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-13 CW02-13.C Type conversion.*/ #include void main() { float f; int i; f=3.6; i=(int)f; printf("f=%f\ni=%d",f,i); }i=3 f=3.600000f 的类型并未因此而改变!
  • 67. 赋值运算 Assignment赋值运算符(Assignment operators) 简单赋值运算符(Simple assignment operator):= 复合赋值运算符(Compound assignment operators): +=,-=,*=,/=,%= 赋值表达式(Assignment Expression) 作用:将表达式的值赋给变量 赋值表达式的值就是被赋值的变量的值ASSIGNMENT OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式
  • 68. 简单赋值运算符 Simple Assignment OperatorSimple assignment operator: = Associativity:right to left Examples:ASSIGNMENT OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式c=a+b a=b=c=d=10 x=(a=5)+(b=8)a=(a+b) a=(b=(c=(d=10))) a=5, b=8, x=a+b
  • 69. 复合赋值运算符 Compound Assignment OperatorsCompound assignment operator: +=, -=, *=, /=, %= Associativity:right to left 简化了赋值表达式 表达式格式(form) = 由下面的表达式简化而来 = Examples:ASSIGNMENT OPERATORS AND EXPRESSIONS双语课堂目 录第二讲 数据类型、运算符和表达式a+=5 x*=y+7 x+=x-=x*=xa=a+5 x=x*(y+7) x=x+(x=x-(x=x*x))≡
  • 70. 自增、自减运算符 Increment and Decrement Operators自增运算符(Increment operator):++ c++ 可以用来代替 c+=1 自减运算符(Decrement operator):-- c-- 可以用来代替 c-=1 使用形式一:Preincrement ++c or --c Variable is changed before the expression it is in is evaluated 使用形式二:Postincrement c++ or c-- Expression executes before the variable is changedINCREMENT AND DECREMENT双语课堂目 录第二讲 数据类型、运算符和表达式
  • 71. 例2-9:自增、自减运算 Increment and Decrement OperationExample 2-9: Increment and decrement operationINCREMENT AND DECREMENT双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-9 CW02-09.C Increment and decrement operation.*/ #include void main() { int i=6, a, b; printf("%d\n", ++i); printf("%d\n", i++); a=--i; printf("%d\n", a); b=i--; printf("%d\n", b); printf("%d\n", -i++); printf("i=%d\n", i); }7 7 7 7 -6i = ?
  • 72. 例2-10:自增、自减运算 Increment and Decrement OperationExample 2-10: Increment and decrement operationINCREMENT AND DECREMENT双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-10 CW02-10.C Increment and decrement operation.*/ #include void main() { int i=5, j=5, p, q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); printf("p=%d,i=%d\n", p, i); printf("q=%d,j=%d\n", q, j); }p=15,i=8 q=24,j=8
  • 73. 例2-11:自增、自减运算 Increment and Decrement OperationExample 2-11: Increment and decrement operationINCREMENT AND DECREMENT双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-11 CW02-11.C Increment and decrement operation.*/ #include void main() { int i, j, k; i=1; j=1; k=i+++j; printf("k=%d,i=%d,j=%d\n",k,i,j); }k=2 i=2 j=1k=(i++)+j;
  • 74. 例2-12:自增、自减运算 Increment and Decrement OperationExample 2-12: Increment and decrement operationINCREMENT AND DECREMENT双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-12 CW02-12.C Increment and decrement operation.*/ #include void main() { int i=3; printf("%d,%d\n",i,i++); }4,3Order of evaluation
  • 75. 逗号运算符 Comma Operator逗号运算符(Comma operator):, 表达式格式(Expression form): , , …, 求解过程:先求表达式1的值,再求表达式2的值,···,直至求出表达式n的值。 整个表达式的值为表达式n的值。COMMA OPERATOR双语课堂目 录第二讲 数据类型、运算符和表达式
  • 76. 例2-15:逗号运算符 Comma OperatorExample 2-15: Comma operatorCOMMA OPERATOR双语课堂目 录第二讲 数据类型、运算符和表达式/* Example 2-15 CW02-15.C Comma operator.*/ #include void main() { int a=2, b=4, c=6; int x, y; y=((x=a+b),(b+c)); printf("x=%d\ny=%d", x, y); }x=6 y=10
  • 77. 第三讲 顺序结构 Sequence StructurePROGRAM DESIGN IN C LANGUAGE双语课堂目 录3.2 控制结构Control Structures3.3 结构化程序Structured Program3.4 顺序结构Sequence Structure3.5 常用语句Common Statements3.1 算法Algorithm3.7 流Streams3.8 字符输出Character Output3.9 字符输入Character Input3.10 格式输出Formatted output3.6 输入输出Input/Output3.11 格式输入Formatted Input3.12 程序设计举例Example
  • 78. 简 介 Introduction在编写程序解决实际问题之前 全面的理解问题 仔细规划解决问题的方法(approach) 在编写程序时 了解有哪些可用的“构造块”(building blocks) 使用良好的编程规则(programming principles)iNTRODUCTION双语课堂目 录第三讲 顺序结构强调程序的清晰性与实用性
  • 79. 算法 Algorithm任何计算问题的解决方案包括 按照特定顺序去执行一系列动作(actions) 算法(Algorithm) 为解决某个特定的问题而采用的确定且有限的步骤。 Procedure in terms of Actions to be executed The order in which these actions are to be executed 例如 “早晨上学准备算法”:起床-穿衣-洗漱-吃早餐-上学 程序控制(Program Control) 计算机程序中指定语句执行的顺序ALGORITHM双语课堂目 录第三讲 顺序结构算法是程序的灵魂。 Algorithm is the spirit of a program.
  • 80. 算法的表示 Representation of Algorithm算法的表示方法 自然语言 Natural language 伪代码 Pseudocode 流程图 Flowchart 计算机语言 Computer languageALGORITHM双语课堂目 录第三讲 顺序结构
  • 81. 算法的自然语言表示 Algorithm (1/4) :Natural Language问题 计算1+2+3+…+100 自然语言表示 定义数据结构: 变量 i 代表每一个数 变量 sum 表示和ALGORITHM双语课堂目 录步骤1:i=1,sum=0; 步骤2:使sum(和)加上i,累加后的值仍放在sum中。用公式表示就是:sum = sum+i; 步骤3:使i的值增一,即i=i+1; 步骤4:如果i不大于100,重复执行步骤2和步骤3;否则算法结束,变量sum中的值就是要得到的结果。第三讲 顺序结构
  • 82. 算法的伪代码表示 Algorithm (2/4) :Pseudocode问题 计算1+2+3+…+100 伪代码(pseudocode)表示ALGORITHM双语课堂目 录i=1 sum=0 while i<=100 do sum=sum+i i=i+1 end while print sum第三讲 顺序结构人为的、非正式的语言 与日常用语类似 不被执行 帮助程序员在写程序之前“设想出”程序 很容易被转换成C程序 一般只包括可执行语句
  • 83. 算法的流程图表示 Algorithm (3/4) :Flowchart问题 计算1+2+3+…+100 流程图(flowchart)表示ALGORITHM双语课堂目 录starti=1 sum=0i<=100sum=sum+i i=i+1Out: sumendYN第三讲 顺序结构程序的开始和结束动作(action)流程线(flowline)判断(decision)输入/输出(input/output)连接(connection)
  • 84. 算法的计算机语言表示 Algorithm (4/4) :Computer Language问题 计算1+2+3+…+100 C语言表示ALGORITHM双语课堂目 录main() { int i, sum; i=1; sum=0; while (i<=100) { sum=sum+i; i=i+1; } printf("1+2+3+...+100=%d",sum); }第三讲 顺序结构
  • 85. 控制结构 Control Structure顺序执行(Sequential execution) 程序中的语句按照它们的书写顺序一句接一句地执行 控制转移(Transfer of control) 把待执行的下一个语句指定为不是书写顺序中的下一个语句 goto语句带来很多问题 程序结构不清晰、可读性差、不利于维护 结构化技术(1970s):所有的程序只用3种结构就可以写出来 顺序结构(Sequence structures) Built into C Programs executed sequentially by default 选择结构(Selection structures) C has three types: if, if-else, and switch 循环结构(Repetition structures) C has three types: while, do/while and forCONTROL STRUCTURES双语课堂目 录第三讲 顺序结构
  • 86. 结构化程序 Structured Program单入/单出(Single-entry/single-exit)控制结构 3种控制结构都是单入/单出的 把控制结构的出口处与下一个控制结构的入口处连接起来 使程序开发非常容易 结构化程序由3种结构通过以下方式组合而成: 堆叠(stacking) 嵌套(nesting)STRUCTURED PROGRAM双语课堂目 录第三讲 顺序结构sum=sum+ii=i+1sequence structurestackingnesting
  • 87. 顺序结构 Sequence StructureSequence Structure Programs executed sequentially by default Control flow: Statements executed one after the other in the order writtenSEQUENCE STRUCTURE双语课堂目 录statement 1statement 2Sequence Structure第三讲 顺序结构
  • 88. 常用语句 Common StatementsC语言程序常用的语句: 表达式语句 expression; 函数调用语句 function-name(parameter-list); 空语句 ; 复合语句(compound statement)COMMON STATEMENTS双语课堂目 录第三讲 顺序结构{} { int x, y; x=y=10; printf(“x=%d,y=%d\n”, x, y); }
  • 89. 输入/输出 Input/Output输入输出是以计算机主机为主体而言的。 输出:从计算机向外部输出设备输出数据。 输入:从外部通过输入设备向计算机输入数据。 C语言中数据的输入、输出是由函数来实现的。 字符输入函数:getchar 字符输出函数:putchar 格式输入函数:scanf 格式输出函数:printf 它们的原型(prototype)都在 stdio.h 中INPUT/OUTPUT 双语课堂目 录第三讲 顺序结构主 机键盘 磁盘 光盘 扫描仪 ……显示器 打印机 磁盘……
  • 90. 流 Streams流(stream) 按直线排列的字符序列 每个序列包括0个或多个字符,并用换行符结尾 ANSI C支持至少254个字符的序列 所有的输入/输出都是用流来进行的 开始执行程序时,3个流自动连接到程序上 标准输入(standard input):keyboard 标准输出(standard output):screen 标准错误(standard error):screen 操作系统允许这些流重定向(redirected)到其它设备STREAMS双语课堂目 录第三讲 顺序结构type myprog.c > prnS@!ci’[]
  • 91. 字符输入/输出 Character Input/Outputputchar getchar 使用说明 程序中必须包含 stdio.h 头文件(head file)CHARACTER INPUT/OUTPUT 双语课堂目 录第三讲 顺序结构#include
  • 92. 字符输出 Character Outputputchar putchar(character); 向标准输出流输出一个字符character 使用说明 character可以是以下数据: 字符型变量 整型变量 字符型常量 转义字符PUTCHAR 双语课堂目 录第三讲 顺序结构S@!ci’[]output streamkRAM
  • 93. 例3-1:字符输出 Character OutputExample 3-1:putcharPUTCHAR 双语课堂目 录第三讲 顺序结构#include main() { char a; int b; a=‘B’; b=79; putchar(a); putchar(‘\n’); putchar(b); putchar(‘\n’); putchar(‘Y’); } /*CW03-01.C*/B O Y
  • 94. 字符输入 Character Inputgetchar variable=getchar(); 从标准输入流读取一个字符 使用说明 只读取一个字符 该字符可赋给字符变量、整型变量或作为表达式的一部分GETTCHAR 双语课堂目 录第三讲 顺序结构S@!ci’[]Input streamRAM
  • 95. 例3-2:字符输入 Character InputExample 3-2:getcharGETCHAR 双语课堂目 录第三讲 顺序结构#include main() { char c; c=getchar(); putchar(c); } /*CW03-02.C*/a aabc a98 9123
  • 96. 格式输入/输出 Formatted Input/Outputprintf scanf 使用说明 程序中可以不明确指定包含 stdio.h 头文件FORMATTED INPUT/OUTPUT 双语课堂目 录第三讲 顺序结构#include 可以省略此命令
  • 97. 格式输出 Formatted Outputprintf printf(format-control-string,output-list); 按格式控制字符串规定的格式,向指定的输出设备输出输出表列中的输出项。 使用说明 格式控制字符串(format-control-string) 由双引号括起来的字符串,用于指定输出格式 输出表列(output-list) 需要输出的数据列表,彼此间用逗号分隔 可以是任意合法的表达式Formatted outPUT 双语课堂目 录第三讲 顺序结构23.5 s 78output stream120 fRAM
  • 98. 格式控制字符串 Format Control String printf(“n=%5d,f=%5.2f\n”, n, f)Formatted outPUT 双语课堂目 录第三讲 顺序结构普通字符 原样输出 格式说明符(转换规则) % [修饰符] 格式字符 指定数据的输出格式
  • 99. printf的格式字符 Format CharacterFormatted outPUT 双语课堂目 录第三讲 顺序结构格式字符功 能d, i以十进制有符号形式输出整数(正数不输出符号)o以八进制无符号形式输出整数(不输出前缀)x, X以十六进制无符号形式输出整数(不输出前缀)u以十进制无符号形式输出整数f以小数形式输出单、双精度实数e, E以指数形式输出单、双精度实数g, G选用%f和%e格式中输出宽度较短的一种,不输出无意义的零c以字符形式输出,输出一个字符s输出字符串
  • 100. printf的修饰符 Qualifier CharacterFormatted outPUT 双语课堂目 录第三讲 顺序结构修饰符意 义l用于长整型和双精度实型数据,可加在格式字符 d、o、x、u、f 前面。m(正整数)数据最小宽度。n(正整数)对于实数,表示输出n位小数; 对于字符串,表示截取的字符个数。-输出的数字或字符在域内向左靠,右边填空格。#当整数以八进制或十六进制形式输出时,输出前缀。 可加在格式字符o、x前面。
  • 101. printf的格式说明符小结 Format Specification String SummaryFormatted outPUT 双语课堂目 录第三讲 顺序结构格式字符形 式d, i%d,%md,%-md,%ld,%mld,%-mld,%i,……o%o,%mo,%-mo,%lo,%mlo,%-mlo,%#o,……x, X%x,%mx,%-mx,%lx,%mlx,%-mlx,%#x,……u%u,%mu,%-mu,%lu,%mlu,%-mluf%f,%mf,%m.nf,%lf,……e, E%e,%me,%m.ne,……g, G%gc%cs%s,%ms,%m.ns,……
  • 102. 例3-3:格式输出 Formatted OutputExample 3-3:printfFormatted outPUT 双语课堂目 录第三讲 顺序结构main() { int a=97,b=-1; float f=123.4; printf(“%d,%c\n”,a,a); printf(“%d,%o,%x,%u\n”,b,b,b,b); printf(“%f,%e,%gEND”,f,f,f); } /*CW03-03.C*/97,a -1,177777,ffff,65535 123.400002,1.234000e+02,123.4END1 1 1 1 1 1 1 11 1 1 1 1 1 1 1
  • 103. 例3-4:格式输出 Formatted OutputExample 3-4:printfFormatted outPUT 双语课堂目 录第三讲 顺序结构main() { int a=1,b=2,c=3; printf(“%d,%d,%d,%d\n”,a,b,c); printf(“%d,%d,%d\n”,a,b,c,a+b+c); } /*CW03-04.C*/1,2,3,898 1,2,3格式说明符和输出项在数量和类型上应该一一对应。
  • 104. 例3-5:格式输出 Formatted OutputExample 3-5:printfFormatted outPUT 双语课堂目 录第三讲 顺序结构main() { int i=3; printf("%d,%d\n",i,i++); } /*CW02-12.C*/4,3不同的编译系统对输出表列中的求值顺序不一定相同。
  • 105. 格式输入 Formatted Inputscanf scanf(format-control-string,address-list); 按格式控制字符串规定的格式,从指定的输入设备输入数据,并存放到地址表列中的各地址项指定的变量中 使用说明 格式控制字符串(format-control-string) 由双引号括起来的字符串,用于指定输入格式 地址表列(address-list) 由若干个变量的地址组成Formatted INPUT 双语课堂目 录第三讲 顺序结构23.5 s 78input streamRAM
  • 106. 格式输入 Formatted Input scanf(“%d,%d”, &a, &b) 取地址运算符:& &<变量> 得到变量在内存中的地址。Formatted INPUT 双语课堂目 录第三讲 顺序结构FF00FF02ab
  • 107. scanf的格式字符 Format CharactersFormatted INPUT 双语课堂目 录第三讲 顺序结构格式字符功 能d, i以十进制形式输入有符号整数o以八进制形式输入无符号整数x, X以十六进制形式输入无符号整数u以十进制形式输入无符号整数f以小数形式或指数形式输入实数e, E, g, G同f,它们之间可以互换c输入单个字符s输入字符串
  • 108. scanf的修饰符 Qualifier CharactersFormatted INPUT 双语课堂目 录第三讲 顺序结构修饰符意 义l用于输入长整型和双精度实型数据,可加在格式字符 d、o、x、u、f、e 前面。h用于输入短整型数据。m(正整数)域宽,指定输入数据所占的宽度。*表示本输入项读入后不赋给相应的变量,即跳过该输入值。
  • 109. scanf的格式说明符小结 Format Specification Characters SummaryFormatted INPUT 双语课堂目 录第三讲 顺序结构格式字符形 式d, i%d,%md,%ld,%mld,%i,……o%o,%mo,%lo,%mlox, X%x,%mx,%lx,%mlxu%u,%mu,%lu,%mluf%f,%mf,%lf,%mlfe, E, g, G%e,%me,%le,%mle,%g,……c%cs%s,%ms
  • 110. 格式输入 Formatted Input输入数据时采用的分隔符应与格式控制中的分隔符一致。 例1:scanf("%d%f%d", &a, &b, &c); 格式符中无普通字符时,可用空格、Tab键、回车键作分隔符。 如:12 3.45 678↙ 或 123.45678↙ 例2: scanf("%d,%f,%d", &a, &b, &c); 必须采用格式:12,3.45,678↙ 例3: scanf("a=%d, b=%d", &a, &b); 必须采用格式: a=12, b=345↙Formatted INPUT 双语课堂目 录第三讲 顺序结构
  • 111. 格式输入 Formatted Input无符号整数可用 %d、%o、%x 格式输入。 输入格式符带有 * :表示该数据不赋值。 例:scanf("%d%*d%d", &a, &c); 键入: 12 34 567↙ 则 a=12, c=567, 而 34 未赋值。 数据输入时不可规定精度,但可确定宽度。 例1:scanf(“%3f%3c”, &a, &b); 合法。 例2:scanf(”%3.2f%3c”, &a, &b); 非法。Formatted INPUT 双语课堂目 录第三讲 顺序结构
  • 112. 格式输入 Formatted InputExample 3-6: scanfFormatted INPUT 双语课堂目 录第三讲 顺序结构main() { char a,b,c; scanf(“%c%c%c”,&a,&b,&c); printf(“a=%c,b=%c,c=%c",a,b,c); } /*CW03-06.C*/abc a=a,b=b,c=ca b c a=a,b= ,c=ba b a=a,b= ,c=a b a=a,b= ,c=b1234用 c 格式字符输入字符时,若格式控制字符串中无普通字符,那么认为所有输入的字符(包括空格、制表符、换行符)均为有效字符。
  • 113. 深入分析输入流 Deep Into Input StreamFormatted INPUT 双语课堂目 录第三讲 顺序结构ab2,3.4输入缓冲区scanf(); getchar(); …输入流输入流
  • 114. 格式输入 Formatted Input用c格式字符输入字符时,若格式控制字符串中加入空格作为分隔符,那么输入时各数据之间可以加任意多个空格(或回车换行)。 例:scanf(“%c %c %c”,&a,&b,&c); 输入:a b c↙ 则 a=a,b=b,c=c 在下列情况下可认为数据输入结束: 遇空格、回车、跳格键(Tab)时 按指定的宽度结束 遇非法输入Formatted INPUT 双语课堂目 录第三讲 顺序结构
  • 115. 例3-7:顺序结构 Sequence Structure问题:输入圆柱体的截面圆半径和高,求其体积。 设截面圆半径r,高h,那么根据几何知识得到 圆柱体的体积v=πr2hFormatted INPUT 双语课堂目 录第三讲 顺序结构#define PI 3.14 main() { float r, h, v; printf(“Input r and h:\n"); scanf("%f%f", &r, &h); v=PI*r*r*h; printf(“v=%.2f\n“, v); } /*CW03-07.C*/Input r and h: 1 1 v=3.14
  • 116. 第四讲 选择结构 Selection StructuresPROGRAM DESIGN IN C LANGUAGE双语课堂目 录4.2 if选择结构if Selection Structure4.3 if-else选择结构if-else Selection Structure4.4 逻辑运算Logical Calculation4.5 多重选择结构Multiple-Selection Structure4.1 关系运算Relational Calculation
  • 117. 关系运算 Relational Calculation关系运算(比较运算) 比较两个值,结果为“真”或“假” 举例:a>3 如果a=8,则结果为“真” 如果a=1,则结果为“假” 用关系运算进行条件判断 关系表达式表示一个条件,根据其结果判断条件是否满足 举例:a>3 如果a=8,结果为“真”,即条件满足 如果a=1,结果为“假”,即条件不满足ReLATIONAL CALCULATION双语课堂目 录第四讲 选择结构
  • 118. 关系运算符 Relational OperatorsReLATIONAL CALCULATION双语课堂目 录第四讲 选择结构运算符含 义优先级结合性<小于6左结合<=小于或等于>大于>=大于或等于==等于7!=不等于
  • 119. 关系表达式 Relational Expressions关系表达式(Relational Expressions) <表达式1> <关系运算符> <表达式2> 表达式1和表达式2可以是任何表达式 举例ReLATIONAL CALCULATION双语课堂目 录第四讲 选择结构a>b m+n<=20 c!=‘y’ (x>z)==(y>z)
  • 120. 关系表达式 Relational Expressions关系表达式的值是一个逻辑值:“真”或“假” C语言没有逻辑类型,因此 用整数 1 表示“真” 用整数 0 表示“假” 即关系表达式的值是整数 1 或 0 举例 若a=1,b=2,c=3ReLATIONAL CALCULATION双语课堂目 录第四讲 选择结构a>b a+b<=c (a>c)==(b>c) ‘Y’!=‘y’0 1 1 1
  • 121. 关系表达式的使用 Use Of Relational Expressions问题:写出下面各条件的关系表达式 x为不小于 -5 的整数 x为非零的数 x的平方大于m与n的和ReLATIONAL CALCULATION双语课堂目 录第四讲 选择结构x>=-5 x!=0 x*x>(m+n)
  • 122. if选择结构 The if Selection Structure选择结构(Selection Structure) 用于在可选择的几个操作之间进行选择 伪代码语句举例 If student’s grade is greater than or equal to 60 Print “Passed” 如果条件为真(学生分数大于等于60) 那么就打印或显示“Passed”,然后程序按顺序执行下一条伪代码语句 如果条件为假 就忽略打印或显示操作,顺序执行下一条伪代码语句SELECTION STRUCTURES双语课堂目 录第四讲 选择结构
  • 123. if选择结构 The if Selection Structure选择结构是一个单入/单出结构SELECTION STRUCTURES双语课堂目 录FalsePrint “Passed”grade >= 60Trueif Selection Structureif (grade>=60) printf(“Passed”);条件判断 可以是任何表达式 0(zero):false 非0(nonzero):true第四讲 选择结构
  • 124. if-else选择结构 The if-else Selection Structureif Selection Structure 只有在条件为真时,才会执行一个操作;否则就会跳过这个操作 if-else Selection Structure 条件为真时所执行的操作与条件为假时所执行的操作不同 伪代码语句举例 If student’s grade is greater than or equal to 60 Print “Passed” Else Print “Failed”SELECTION STRUCTURES双语课堂目 录第四讲 选择结构
  • 125. if-else选择结构 The if-else Selection Structureif-else Selection Structure 伪代码转换成C代码SELECTION STRUCTURES双语课堂目 录Print “Passed”TruePrint “Failed”grade >= 60Falseif-else Selection Structure第四讲 选择结构if (grade>=60) printf(“Passed”); else printf(“Failed”);
  • 126. 条件运算符 Conditional Operator条件运算符:? : 三目运算符 右结合 条件表达式 ?: 举例SELECTION STRUCTURES双语课堂目 录第四讲 选择结构(grade>=60)?printf(“Passed”):printf(“Failed”);
  • 127. 嵌套选择结构 Nested Selection Structure嵌套的if-else结构(Nested If-else Structure) 对多种情况进行测试 伪代码语句举例 If 学生的分数大于等于 90 打印 “A” else If 学生的分数大于等于80 Print “B” else If 学生的分数大于等于70 Print “C” else If 学生的分数大于等于60 Print “D” else Print “E”SELECTION STRUCTURES双语课堂目 录第四讲 选择结构
  • 128. 嵌套的选择结构 Nested Selection Structure嵌套的if-else结构(Nested if-else Structure) 伪代码转换成C语言SELECTION STRUCTURES双语课堂目 录第四讲 选择结构if (grade>=90) printf(“A”); else if (grade>=80) printf(“B”); else if (grade>=80) printf(“C”); else if (grade>=60) printf(“D”); else printf(“E”);if (grade>=90) printf(“A”); else if (grade>=80) printf(“B”); else if (grade>=80) printf(“C”); else if (grade>=60) printf(“D”); else printf(“E”);
  • 129. 选择结构中的复合语句 Compound Statement Nested In if/else选择结构的if或else体可以是复合语句SELECTION STRUCTURES双语课堂目 录第四讲 选择结构if (grade>=60) printf(“Passed”); else { printf(“Failed\n”); printf(“You must take the course again!”); }复合语句 可以放在程序中单一语句能够放置的任何位置
  • 130. 关系运算的不足 Shortage Of Relational Calculation关系表达式只能表达一些简单的条件 grade>=60 total>1000 每个判断只是对一个条件进行测试 如果要对多个条件进行测试就要在独立的语句或嵌套的if或if-else结构中进行测试 例1:10>y>5 例2:x<-10或者x>0LOGICAL CALCULATION双语课堂目 录第四讲 选择结构if (y>5) if (y<10) …;if (x<-10) …; if (x>0) …;
  • 131. 逻辑运算 Logical Calculation逻辑运算 通过逻辑运算符把简单的条件组合起来,能够形成更加复杂的条件 例1:10>y>5 的逻辑表达式 (y>5)&&(y<10) 例2:x<-10或者x>0 的逻辑表达式 (x<-10)||(x>0) 逻辑运算符 !(逻辑非,logical NOT) &&(逻辑与,logical AND) ||(逻辑或,logical OR)LOGICAL CALCULATION双语课堂目 录第四讲 选择结构
  • 132. 逻辑表达式 Logical Expression逻辑表达式 [<表达式1>] <逻辑运算符> <表达式2> 表达式1和表达式2可以是任何表达式 举例LOGICAL CALCULATION双语课堂目 录第四讲 选择结构(x>5)||(x<-5) !(ac)&&(a+c>b)&&(b+c>a)逻辑表达式的值 1:true 0:false 整数
  • 133. 逻辑运算 Logical Calculation逻辑运算真值表LOGICAL CALCULATION双语课堂目 录第四讲 选择结构a!a1001aba&&b111100010000aba||b111101011000!&&||
  • 134. 逻辑运算 Logical Calculation运算符运算优先级小结LOGICAL CALCULATION双语课堂目 录第四讲 选择结构算术运算关系运算逻辑运算与、或赋值运算逻辑非从高到低
  • 135. 逻辑表达式的使用 Use Of Logical Expression将下面的条件用C语言的逻辑表达式表达 例1:1≤x≤10且x≠7 x>=1&&x<=10&&x!=7 例2:y能被4整除,但不能被100整除 (y%4==0)&&(y%100!=0) 逻辑与和逻辑非具有短路能力 例1:gender==‘F’&&age>65 如果gender不等于’F’,整个表达式的值就是假,求值过程将停止 例2:average>=90||finalExam>=90 如果average大于等于90,整个表达式的值就是真,求值过程将停止LOGICAL CALCULATION双语课堂目 录第四讲 选择结构
  • 136. 例4-1:逻辑表达式的使用 Use Of Logical Expression问题:任意输入一个字符,判断它是字母还是数字。LOGICAL CALCULATION双语课堂目 录第四讲 选择结构void main() { char c; c=getchar(); if ((c>=‘A’&&c<=‘Z’)||(c>=‘a’&&c<=‘z’)) printf(“%c is a letter.”, c); else if (c>=‘0’&&c<=‘9’) printf(“%c is a digit.”, c); else printf(“%c is neither a letter nor a digit.”, c); } /*CW04-01.C*/
  • 137. 多重选择结构 Multiple-Selection Structureswitch 在判断过程中,一个变量或表达式会分别针对其可能会取的每个整型常量值进行测试,并采取不同的动作MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构switch(expression) { case : action_1; [break;] case : action_2; [break;] …… case :action_n-1; [break;] [default: action_n; [break;]] }
  • 138. 例4-2:多重选择结构 Multiple-Selection Structure问题 根据考试成绩的等级打印相应的分数段MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构grade=getchar(); switch(grade) { case ‘A’: printf(“85~100\n”); case ‘B’: printf(“70~84\n”); case ‘C’: printf(“60~69\n”); case ‘D’: printf(“<60\n”); default: printf(“error\n”); }若grade=‘A’ 85~100 70~84 60~69 <60 error
  • 139. 例4-2:多重选择结构 Multiple-Selection Structure(cont.)分析例4-2的结果 流程图MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构print “60~69”print “70~84”print “85~100”print “<60”print “error”grade‘A’‘B’‘C’‘D’default
  • 140. 例4-3:多重选择结构 Multiple-Selection Structure改进例4-2 改进后的流程图MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构print “60~69”print “70~84”print “85~100”print “<60”print “error”grade‘A’‘B’‘C’‘D’default
  • 141. 例4-3:多重选择结构 Multiple-Selection Structure(cont.)switch中的break语句 改进后的代码MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构switch(grade) { case ‘A’: printf(“85~100\n”); break; case ‘B’: printf(“70~84\n”); break; case ‘C’: printf(“60~69\n”); break; case ‘D’: printf(“<60\n”); break; default: printf(“error\n”); }若grade=‘A’ 85~100break语句 终止switch语句的执行
  • 142. 例4-4:多重选择结构 Multiple-Selection Structure问题 任意输入两个数,和一个运算符,输出运算结果。MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构print op1*op2print op1-op2print op1+op2print op1/op2print “error”operator‘+’‘-’‘*’‘/’default
  • 143. 例4-4:多重选择结构 Multiple-Selection Structure代码(cw04-04.c)MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构main() { int op1, op2, operator; scanf("%d%d", &op1, &op2); operator=getchar(); switch(operator) { case ‘+’: printf(“=%d”, op1+op2); break; case ‘-’: printf(“=%d”, op1-op2); break; case ‘*’: printf(“=%d”, op1*op2); break; case ‘/’: printf(“=%d”, op1/op2); break; default: printf(“operator is invalid!”); } }
  • 144. 例4-4:多重选择结构 Multiple-Selection Structure(cont.)改进代码MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构main() { int op1, op2, operator, result, done=1; scanf("%d%d", &op1, &op2); operator=getchar(); switch(operator) { case ‘+’: result=op1+op2; break; case ‘-’: result=op1-op2; break; case ‘*’: result=op1*op2; break; case ‘/’: result=op1/op2; break; default: done=0; } if (done) printf(“%d%c%d=%d”, op1, operator, op2, result); else printf(“operator is invalid!”); } /*CW04-04.C*/标记变量(flag)
  • 145. 例4-5:多重选择结构 Multiple-Selection Structure问题 根据输入的月份,给出当月的天数。MULTIPLE-SELECTION STRUCTURE双语课堂目 录第四讲 选择结构main() { int m, d,year; scanf(“%d,%d", &year,&m); switch (m) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: d=31; break; case 4: case 6: case 9: case 11: d=30; break; case 2: if(year%4==0&&year%100!=0||year%400==0) d=29; else d=28; break; default: d=0; } d>0 ? printf("%d", d) : printf("invalid input!"); } /*CW04-05.C*/
  • 146. 小结 SummaryRelational Calculation Simple Condition Logical Calculation Compound Condition if Selection Structure if-else Selection Structure switch Multiple-Selection Structure breakSELECTION STRUCTURE双语课堂目 录第四讲 选择结构
  • 147. 第五讲 循环结构 Repetition StructuresPROGRAM DESIGN IN C LANGUAGE双语课堂目 录5.2 计数器控制的循环Counter-controlled structure5.3 标记控制的循环Flag-controlled stucture5.4 嵌套的控制结构Nested control structures5.5 do-while循环结构The do-while repetition5.1 while循环结构The while repetition structure5.6 for循环结构The for repetition structure5.7 结构化程序设计小结Structured programming summary5.8 程序设计举例Examples
  • 148. while循环结构 The while Repetition Structure循环结构(Repetition Structure) 程序员指定当某个条件一直为真时重复执行某个动作 Example in Pseudocode: While there are more items on my shopping list Purchase next item and cross it off my list 如果条件“购物单上还有其他商品”为真时,就执行动作“购买下一个商品,并把它从购物单上划掉” 如果该条件一直为真,这个动作就会重复执行 最终,该条件为假,循环过程就会终止,程序将执行这个循环结构之后的第一个伪代码语句 while 循环重复执行,直到条件为假THE While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构
  • 149. while循环结构 The while Repetition Structurewhile 语句 while (condition) action; Example in C:THE While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构int product=2; while (product<=1000) product=2*product;product<=1000product=2*productYN可以是两种语句 单语句 复合语句while 循环结构是单入/单出结构
  • 150. 计数器控制的循环 Counter-Controlled Repetition计数器控制的循环(Counter-controlled Repetition) 循环重复执行,直到计数器达到一个特定的值 确定循环(Definite repetition) 循环的次数是已知的 Example 5-1 1个班有10个学生,参加了一次考试,成绩(0~100内的整数)已知。计算这次考试的班级平均成绩。 算法 输入每个学生的成绩,累计总成绩,计算平均分,显示结果 采用计数器控制的循环来输入学生的成绩 每输入一个成绩就进行累加COUNTER-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构
  • 151. 计数器控制的循环 Counter-Controlled RepetitionExample 5-1 Pseudocode: 设置总分(total)为0 设置分数计数器(counter)为1 While 分数计数器<=10 输入下一个分数(grade) 把该分数加到总分上 对分数计数器加1 班级平均分(average)为总分除以10 显示班级平均分COUNTER-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构
  • 152. 计数器控制的循环 Counter-Controlled RepetitionExample 5-1(cw05-01.c)COUNTER-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构#include void main() { int counter, grade, total, average; total=0; counter=1; while (counter<=10) { printf("Enter grade:"); scanf("%d", &grade); total+=grade; counter++; } average=total/10; printf("Class average is %d\n", average); }初始化 (initialization) 执行循环 (execute loop) 输入 累加 结束 (termination) 最后的计算 输出结果
  • 153. 计数器控制的循环 Counter-Controlled RepetitionExample 5-1 ResultCOUNTER-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构Enter grade:60 Enter grade:70 Enter grade:65 Enter grade:76 Enter grade:73 Enter grade:56 Enter grade:78 Enter grade:64 Enter grade:89 Enter grade:76 Class average is 70
  • 154. 标记控制的循环 Flag-Controlled RepetitionExample 5-2 开发出一个班级平均分计算程序,每次执行该程序,都能够处理任意数量的学生分数。 思考:学生人数未知,何时结束输入? 标记控制的循环(Flag-controlled Repetition) 使用标记(flag)指定“数据输入的结束” 其他名称:信号值(signal value),哨兵(sentinel) 标记值不应与正常的用户输入混淆 本例可以采用-1 但同时标记值也是合法的输入 当用户输入标记值时,循环结束 不确定的循环(indefinite repetition) 循环次数未知FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构
  • 155. 标记控制的循环 Flag-Controlled Repetition自上而下,逐步求精(top-down, stepwise refinement) 算法的顶部(描述程序整体功能) 计算本次考试的班级平均分 划分成一系列较小的任务 初始化变量 输入考试的分数,求分数总和,并计数(统计分数个数) 计算并显示班级平均分 许多程序都有三个阶段(phase) 初始化(initialization) 初始化变量 处理(process) 输入数据,并相应的调整相关变量的值 结束(termination) 计算并输出最终结果FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构
  • 156. 标记控制的循环 Flag-Controlled Repetition进一步细化 初始化变量 输入考试的分数,求分数总和,并计数(计算分数个数) FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构设置总分(total)为0 设置计数器(counter)为0输入第一个分数(grade)(可能是标记值) While 用户还没有输入标记值 把当前分数加到总分中 分数的个数加1 输入下一个标记值(可能是标记值)
  • 157. 标记控制的循环 Flag-Controlled Repetition进一步细化(续) 计算并显示班级平均分 FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构If 计数器不等于0 总分除以计数器的结果就是班级平均分 显示班级平均分 Else 显示“没有输入成绩”被 0 除 “致命”错误 会导致程序“崩溃”
  • 158. 标记控制的循环 Flag-Controlled RepetitionExample 5-2(cw05-02.c) FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构#include void main() { float average; int counter, grade, total; total = 0; counter = 0; printf("Enter grade, -1 to end:"); scanf("%d", &grade); while (grade != -1) { total += grade; counter++; printf("Enter grade, -1 to end:"); scanf("%d", &grade); }新的类型初始化处理结束判断
  • 159. 标记控制的循环 Flag-Controlled RepetitionExample 5-2(cw05-02.c) FLAG-CONTROLLED REPETITION双语课堂目 录第五讲 循环结构 if (counter != 0) { average = (float)total / counter; printf("Class average is %.2f\n", average); } else printf("No grades were entered\n"); }Enter grade, -1 to end:70 Enter grade, -1 to end:60 Enter grade, -1 to end:65 Enter grade, -1 to end:-1 Class average is 65.00结束
  • 160. 嵌套的控制结构 Nested Control Structures构造程序的方式 堆叠控制结构(stacking) 嵌套控制结构(nesting) Example 5-3 每班10个学生期末考试结果的清单(1-通过,2-没有通过) 开发出一程序对结果进行分析 如果有8个学生通过,显示“优秀班级” 分析 程序每次执行处理10个考试结果 采用计数器控制的循环 使用两个统计计数器 一个统计通过的人数,另一个统计没通过的人数 每一个考试结果要么是1,要么是2 只对1进行测试,不是1的其他数就假定为2NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构
  • 161. 嵌套的控制结构 Nested Control Structures算法的顶部 分析考试结果,判断是否评为优秀班级 细化 初始化变量 输入10个考试结果,并计算通过考试和未通过考试的学生数目 显示考试结果的汇总,并判断是否应该评为优秀班级 进一步细化 初始化变量NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构通过数初始化为0 未通过数初始化为0 循环控制计数器初始化为1
  • 162. 嵌套的控制结构 Nested Control Structures进一步细化(续) 输入10个考试结果,并计算通过考试和未通过考试的学生数目NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构While 循环控制计数器的值<=10 输入一个考试结果 if 考试结果为1 通过计数器加1 else 未通过计数器加1 循环控制计数器加1
  • 163. 嵌套的控制结构 Nested Control Structures进一步细化(续) 显示考试结果的汇总,并判断是否应该评为优秀班级NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构显示通过考试的学生数目 显示未通过考试的学生数目 If 8个以上的学生通过了考试 显示“优秀班级”
  • 164. 嵌套的控制结构 Nested Control StructuresExample 5-3(cw05-03.c)NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构#include void main() { int passed=0, failed=0, counter=1, result; while (counter<=10) { printf("Enter result (1=pass, 2=fail):"); scanf("%d", &result); if (result==1) passed++; else failed++; counter++; }
  • 165. 嵌套的控制结构 Nested Control StructuresExample 5-3(cw05-03.c)NESTED CONTROL STRUCTURES双语课堂目 录第五讲 循环结构 printf("Passed %d\n", passed); printf("Failed %d\n", failed); if (passed>8) printf("Excellent Class\n"); }Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):2 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Enter result (1=pass, 2=fail):1 Passed 9 Failed 1 Excellent Class
  • 166. do-while循环结构 The do-while Repetition Structuredo-while 语句 do action while (condition);THE do-While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构conditionactionYNdo-while 循环结构是单入/单出结构先执行循环体语句,再判断循环条件
  • 167. do-while循环结构 The do-while Repetition StructureExample 5-4(cw05-04.c) 计算1+2+…+100THE do-While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构#include void main() { int s, i; s=0; i=1; do { s = s + i; i++; } while (i<=100); printf("1+2+...+100=%d\n", s); }
  • 168. do-while与while do-while and while比较do-while与while(cw05-05.c)THE do-While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构main() { int s=0, n; scanf(“%d”, &n); while (n<=2) { s += n; n++; } printf(“s=%d,n=%d”, s, n); }main() { int s=0, n; scanf(“%d”, &n); do { s += n; n++; } while (n<=2); printf(“s=%d,n=%d”, s, n); }1 s=3,n=33 s=0,n=31 s=3,n=33 s=3,n=41212
  • 169. for循环结构 The for Repetition Structurefor 语句 for (设置初值; 条件判断; 设置增减量) { ……… 循环主体语句; }THE FOR REPETITION STRUCTURE双语课堂目 录第五讲 循环结构没有分号条件判断循环主体语句YN设置增减量设置初值其他语句
  • 170. for循环结构 The for Repetition Structurefor 循环结构能够自动处理计数器控制的循环的细节 THE FOR REPETITION STRUCTURE双语课堂目 录第五讲 循环结构#include void main() { int counter; for (counter = 1; counter <= 10; counter++) printf("%d ", counter); } /*cw05-06b.c*/循环条件控制变量增1对控制变量进行初始化1 2 3 4 5 6 7 8 9 10
  • 171. for循环结构 The for Repetition Structurefor 语句使用说明 for ([expression1]; [expression2]; [expression3]) action; Notes: 三个表达式都是可选的(都可以为空) 如果表达式2为空,那么就假定该循环条件为真 因此会创建一个无限循环THE FOR REPETITION STRUCTURE双语课堂目 录第五讲 循环结构for (i=0;;i++) printf(“%2d”,i);for (i=0;1;i++) printf(“%2d”,i);=
  • 172. for循环结构 The for Repetition Structurefor 语句使用说明 for ([expression1]; [expression2]; [expression3]) action; Notes: 表达式1和表达式3可以是任何合法的表达式 常用逗号表达式THE FOR REPETITION STRUCTURE双语课堂目 录第五讲 循环结构for (s=0,i=1;i<=100;i++) s+=i;for (s=0,i=1;i<=100;s+=i,i++); 对多个变量初始化修改多个变量的值
  • 173. do-while循环结构 The do-while Repetition StructureExample 5-4(cw05-04.c) 计算1+2+…+100THE do-While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构#include void main() { int s, i; s=0; i=1; do { s = s + i; i++; } while (i<=100); printf("1+2+...+100=%d\n", s); }
  • 174. 嵌套循环 for语句的嵌套循环ExampleTHE do-While REPETITION STRUCTURE双语课堂目 录第五讲 循环结构#include int main(void) { int i, j; int n=6; for(i=1;i<=n;i++) { for(j=1;j<=i;j++) printf("*"); printf("\n"); } return 0; }输出图形
  • 175. break语句 The break Statementbreak 语句 break; 当在while、do-while、for或switch结构中执行break语句时,break语句会造成程序从该结构中退出 程序接着执行该结构之后的第一条语句 常规应用: 提前从循环结构中退出 跳过switch结构的剩余部分THE BREAK AND CONTINUE STATEMENTS双语课堂目 录第五讲 循环结构
  • 176. break语句 The break StatementExample: break (cw05-07.c) THE BREAK AND CONTINUE STATEMENTS双语课堂目 录第五讲 循环结构#include void main() { int x; for (x = 1; x <= 10; x++) { if (x == 5) break; printf("%d ", x); } printf("\nBroke out of loop at x == %d\n", x); }1 2 3 4 Broke ot of loop at x == 5
  • 177. break语句 The break StatementExample: break in switch and for structure THE BREAK AND CONTINUE STATEMENTS双语课堂目 录第五讲 循环结构for (i=1;i<=3;i++) { switch(i) { case 1: printf(“*\n”); break; case 2: printf(“**\n”); break; case 3: printf(“***\n”); break; } }* ** ***for (i=1;i<=3;i++) { if (i==1) {printf(“*\n”); break;} if (i==2) {printf(“**\n”); break;} if (i==3) {printf(“***\n”); break;} } } *
  • 178. continue语句 The continue Statementcontinue 语句 continue; 当在while、do-while或for结构中执行continue语句时,continue语句能够跳过该结构中剩余语句 执行下一个循环过程 Notes: 在while和do-while结构中 在continue语句被执行之后立即进行循环条件的测试 在for结构中 表达式3被执行之后,然后进行循环条件的测试THE BREAK AND CONTINUE STATEMENTS双语课堂目 录第五讲 循环结构
  • 179. continue语句 The continue StatementExample: continue (cw05-08a.c, cw05-08b.c) THE BREAK AND CONTINUE STATEMENTS双语课堂目 录第五讲 循环结构#include void main() { int x; x = 1; while (x <= 10) { if (x = = 5) continue; printf("%d ", x); x++; } }1 2 3 4#include void main() { int x; for (x = 1; x <= 10; x++) { if (x = = 5) continue; printf("%d ", x); } }1 2 3 4 6 7 8 9 10
  • 180. goto语句 The goto Statementgoto 语句 goto statement-label; 改变程序正常的流程控制 立即执行语句标号指向的语句 合理的使用: 与if语句一起构成循环结构 从循环体内跳到循环体外 特别是从多层嵌套循环的内部调到外层循环,或者直接跳出THE GOTO STATEMENTS双语课堂目 录第五讲 循环结构语句标号 是一个标识符 放在可执行语句前面结构化编程技术限制使用 goto 语句 滥用goto语句使得程序无结构可言,可读性差,调试和维护困难
  • 181. goto语句 The goto StatementExample: goto (cw05-09.c) THE GOTO STATEMENTS双语课堂目 录第五讲 循环结构#include void main() { int s=0, i=1; Loop: s = s + i; i++; if (i<=100) goto Loop; printf("1+2+...+100=%d\n", s); }1 2 3 4 Broke ot of loop at x == 5语句标号
  • 182. 结构化程序设计 Structured ProgrammingStructured programming Disciplined approach to writing programs Easier than unstructured programs to understand, test, debug, and modify programs Rules for structured programming Only single-entry/single-exit control structures are used Rules: 1. Begin with the “simplest flowchart” 2. Any rectangle (action) can be replaced by two rectangles (actions) in sequence 3. Any rectangle (action) can be replaced by any control structure 4. Rules 2 and 3 can be applied in any order and multiple timesSTRUCTURED PROGRAMMING SUMMARY双语课堂目 录第五讲 循环结构
  • 183. 控制结构 Control Structures (1/2)C语言的控制结构STRUCTURED PROGRAMMING SUMMARY双语课堂目 录第五讲 循环结构Sequence StructureTFTFTFbreakTFbreakTFbreakSelection Structuresswitchifif-else
  • 184. 控制结构 Control Structures (2/2)C语言的控制结构STRUCTURED PROGRAMMING SUMMARY双语课堂目 录第五讲 循环结构TFRepetition StructureswhileTFTFdo-whilefor
  • 185. 结构化程序设计规则 Rules for Structured Programming (1/2)Rule 1 and 2STRUCTURED PROGRAMMING SUMMARY双语课堂目 录Rule 1: Begin with the simplest flowchartRule 2: Any rectangle can be replaced by two rectangles in sequence第五讲 循环结构Rule 2Rule 2Rule 2
  • 186. 结构化程序设计规则 Rules for Structured Programming (2/2)Rule 3: Any rectangle can be replaced by any control structureSTRUCTURED PROGRAMMING SUMMARY双语课堂目 录Rule 3Rule 3Rule 3第五讲 循环结构
  • 187. 非结构化程序 Unstructured ProgramUnstructured flowchartSTRUCTURED PROGRAMMING SUMMARY双语课堂目 录第五讲 循环结构satckingnestingoverlapinggoto
  • 188. 结构化程序设计小结 Structured Programming SummaryAll programs can be broken down into 3 control structures: Sequence: handled automatically by compiler Selection: if, if-else or switch Repetition: while, do-while or for Can only be combined in two ways: Stacking (rule 2) Nesting (rule 3) Any selection can be rewritten as an if statement, and any repetition can be rewritten as a while statementSTRUCTURED PROGRAMMING SUMMARY双语课堂目 录第五讲 循环结构
  • 189. 结构化程序设计举例 Example 5-10问题 求下面公式的前n项之和 分析 累加求和: s = s + an 关键在于写出 an 的表达式 用计数器控制的循环实现STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构初始化累计和变量 s 为0 初始化计数器变量 i 为1 输入要累加的项数,放入变量 n While i <= n 计算第n项的值,结果放入an 累计,s = s + an 修改计数器变量,i++ 输出结果 s
  • 190. 结构化程序设计举例 Example 5-10第一种实现(cw05-10a.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include #include void main() { int i=1, n; float s=0, an; scanf(“%d”, &n); while (i<=n) { an=pow(-1,i-1)/(2*i-1); s+=an; i++; } printf(“sum=%.3f\n”, s); }不划算1 sum=1.0002 sum=0.6675 sum=0.8350 sum=0.000
  • 191. 结构化程序设计举例 Example 5-10第二种实现(cw05-10b.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int i=1, n, sign=1; float s=0, an; scanf(“%d”, &n); while (i<=n) { an=1.0/(2*i-1); s+=sign*an; sign*=-1; i++; } printf(“sum=%.3f\n”, s); }1 sum=1.0002 sum=0.6675 sum=0.8350 sum=0.000
  • 192. 结构化程序设计举例 Example 5-11问题 用下面的公式求π的近似值(直到最后一项的绝对值小于10-6为止): 分析 先计算等式右边的和 累加求和: s = s + an 当|an|<10-6时,停止累加 用标记控制的循环实现STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构初始化累计和变量 s 为0 初始化计数器变量 i 为1 第1项的值 an = 1 While |an| >= 10-6 累计,s = s + an 计算第n项的值,结果放入an 计算π=s*4 输出结果 π
  • 193. 结构化程序设计举例 Example 5-11实现(cw05-11.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int i=1, n, sign=1; double s=0, an; an=1; while (!(an<1e-6)) { s+=sign*an; i++; sign*=-1; an=1.0/(2*i-1); } printf("pi=%.8lf\n", s*4); }pi=3.14153162an 保存的是第i项的绝对值
  • 194. 结构化程序设计举例 Example 5-11另一种实现(cw05-11b.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int i=1, n, sign=1; double s=0, an; for (;;) { an=1.0/(2*i-1); if (an<1e-6) break; s+=sign*an; sign*=-1; i++; } printf(“pi=%.8lf\n", s*4); }pi=3.14153162使用 break 语句违背了结构化程序设计的原则 continue语句也有类似的问题TFTF
  • 195. 结构化程序设计举例 Example 5-12问题 任意输入10个数,找出最大数和最小数 分析 用计数器控制的循环实现 数的范围无法确定 把输入的第一个数作为最大数和最小数 将其余的数与最大数、最小数分别比较STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构
  • 196. 结构化程序设计举例 Example 5-12实现(cw05-12.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int i, d, max, min; printf("Input 10 integers:\n"); scanf("%d", &d); max=min=d; for (i=2;i<=10;i++) { scanf("%d", &d); if (d>max) {max=d; continue;} if (d
  • 197. 结构化程序设计举例 Example 5-13问题 判断整数 m 是否素数 实现(cw05-13.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include #include void main() { int m, k, i; scanf("%d", &m); k=sqrt(m); for (i=2;i<=k;i++) if (m%i==0) break; if (i>k) printf("%d is a prime number.\n", m); else printf("%d is not a prime number.\n", m); }
  • 198. 结构化程序设计举例 Example 5-14问题 找出1-100间的全部素数 实现(cw05-14.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include #include void main() { int m, k, i; for (m=1;m<=100;m++) { k=sqrt(m); for (i=2;i<=k;i++) if (m%i==0) break; if (i>k) printf("%4d", m); } }Example 5-13nesting
  • 199. 结构化程序设计举例 Example 5-15问题 输出图形 分析 共有10行 第n行有n个星号 用计数器控制的循环实现STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构* ** *** **** ***** ****** ******* ******** ********* **********
  • 200. 结构化程序设计举例 Example 5-15实现(cw05-15.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int m, n; for (n=1;n<=10;n++) { for (m=1;m<=n;m++) printf("*"); printf("\n"); } }
  • 201. 结构化程序设计举例 Example 5-16问题 输出图形 分析 共有10行 第n行先输出n-1个空格,再输出10-(n-1)个星号 用计数器控制的循环实现STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构********** ********* ******** ******* ****** ***** **** *** ** *
  • 202. 结构化程序设计举例 Example 5-16实现(cw05-16.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构#include void main() { int m, n; for (n=1;n<=10;n++) { for (m=1;m<=n-1;m++) printf(" "); for (;m<=10;m++) printf("*"); printf("\n"); } }
  • 203. 结构化程序设计举例 Example 5-17问题 输出图形STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构 * *** ***** ******* ********* * *** ***** ******* ********* ******* ***** *** *图1图2
  • 204. 结构化程序设计举例 Example 5-17实现(cw05-17a.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构main() { int m, n; for (n=1;n<=5;n++) { for (m=1;m<=5-n;m++) printf(" "); for (m=1;m<=2*n-1;m++) printf("*"); printf("\n"); } }
  • 205. 结构化程序设计举例 Example 5-17实现(cw05-17b.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构main() { int m, n; for (n=1;n<=5;n++) { for (m=1;m<=5-n;m++) printf(" "); for (m=1;m<=2*n-1;m++) printf("*"); printf("\n"); } for (n=4;n>=1;n--) { for (m=1;m<=5-n;m++) printf(" "); for (m=1;m<=2*n-1;m++) printf("*"); printf("\n"); } }
  • 206. 结构化程序设计举例 Example 5-18问题 用二分法求下面方程在区间[-10,10]上的根: 2x3-4x2+3x-6=0 二分法 STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构近似计算x1x2f(x1)f(x2)yxf(x)0x0f(x0)x0=(x1+x2)/2
  • 207. 结构化程序设计举例 Example 5-18二分法 确定有根的区间 指定一个区间[x1,x2],如果函数f(x)在此区间是单调变化的,则可以根据f(x1)和f(x2)是否同号来确定方程f(x)=0在区间[x1,x2]内是否有一个实根 把区间一分为二 若f(x1)和f(x2)不同号,则f(x)=0在区间[x1,x2]内有一个(且只有一个)实根; 如果f(x1)和f(x2)同号,则f(x)=0在区间[x1,x2]内没有实根,要重新改变x1和x2的值 重复 当确定f(x)=0在区间[x1,x2]内有实根后,可采用二分法将[x1,x2]区间一分为二,再判断在哪一个小区间中有实根 循环 如此不断进行下去,直到小区间足够小为止STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构
  • 208. 结构化程序设计举例 Example 5-18算法设计 输入并确定有根的初始区间 输入两个数放入 x1 和 x2 ,表示区间[x1 x2] 判断区间被是否有根 否则,重复上面两步,直到的到合法的区间 二分法求近似根 计算当前近似根 x0 = (x1+x2)/2 把当前区间一分为二 [x1 x0]和[x0 x2] 判断根在哪一个小区间 更新当前区间[x1 x2] 判断当前近似根是否达到精度要求 否则,重复上述步骤,直到满足要求 输出近似根STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构 do-while do-whileif-elseprocessoutputinput
  • 209. 结构化程序设计举例 Example 5-18算法设计(细化) 输入并确定有根的初始区间 输入两个数放入 x1 和 x2 ,表示区间[x1 x2] 计算 fx1 和 fx2 判断区间被是否有根,即 fx1 和 fx2 是否同号 否则,重复上面两步,直到的到合法的区间 二分法求近似根 计算当前近似根 x0 = (x1+x2)/2 计算 fx0 把当前区间一分为二 [x1 x0]和[x0 x2] 判断根在哪一个小区间 更新当前区间[x1 x2],和相应的 fx# 判断当前近似根是否达到精度要求 否则,重复上述步骤,直到满足要求 输出近似根STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构 do-while do-whileif-elseprocessoutputinput
  • 210. 结构化程序设计举例 Example 5-18实现(cw05-18.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构 do-while do-whileif-elseprocessoutputinput#include main() { float x0,x1,x2,fx0,fx1,fx2; do { printf("Input x1 , x2:"); scanf("%f,%f", &x1, &x2); fx1 = x1*(x1*(2*x1-4)+3)-6; fx2 = x2*(x2*(2*x2-4)+3)-6; } while (fx1*fx2>0);
  • 211. 结构化程序设计举例 Example 5-18实现(cw05-18.c) STRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构 do-while do-whileif-elseprocessoutputinput do { x0=(x1+x2)/2; fx0=x0*(x0*(2*x0-4)+3)-6; if (fx0*fx1<0) { x2=x0; fx2=fx0; } else { x1=x0; fx1=fx0; } } while (fabs(fx0)>=1e-5); printf("x=%.2f", x0); }
  • 212. 结构化程序设计举例 Example 5-18思考 “计算fx#”的代码能重用吗? 自定义函数 fx 用宏 那么,“判断区间[x1 x2]内是否有根”这个功能呢? 自定义函数 checkSTRUCTURED PROGRAMMING EXAMPLES 双语课堂目 录第五讲 循环结构fx1 = x1*(x1*(2*x1-4)+3)-6; fx2 = x2*(x2*(2*x2-4)+3)-6; fx0 = x0*(x0*(2*x0-4)+3)-6;fx1 = fx(x1); fx2 = fx(x2); fx0 = fx(x0);
  • 213. 第六讲 函数 Functions目录PROGRAM DESIGN IN C LANGUAGE双语课堂目 录6.2 C语言的程序模块Program modules in c6.3 函数的定义Function definitions6.4 函数原型Function prototypes6.5 头文件Head files6.1 简介Introduction6.7 递归Recursion6.8 存储类别Storage classes6.9 作用范围Scope6.10 编译多源文件的程序Compiling multiple-source-file programs6.6 函数调用Function call
  • 214. 简介 Introduction分而治之(divide and conquer) 从较小的程序片段或组件来构建程序 这些小片段被称为模块(module) 这些小片段或组件比原始程序更容易管理Functions 双语课堂目 录第六讲 函数mainfun_afun_bfun_cfun_cfun_dfun_efun_ffun_d
  • 215. C语言的程序模块 Program Modules in C函数(function) C语言中的模块 一个C程序由一个主函数和若干个函数构成 由主函数调用其他函数,其他函数也可以互相调用 同一个函数可以被一个或多个函数调用任意多次 程序把用户定义的函数和标准库(standard libary)函数组合在一起 C标准库提供了丰富的函数 数学计算:sqrt 字符串处理 输入/输出:printf, scanf 程序员可以编写函数来定义特定的任务 应该熟悉ANSI C中的丰富的函数集合 应该避免从头开始构建一切Program modules in c 双语课堂目 录第六讲 函数
  • 216. 数学库函数 Math Library Functions数学库函数 执行常用的数学计算 #include 函数调用的格式 function-name(argument) 如果有多个参数,则参数之间用逗号隔开 参数可以是常量、变量和表达式 举例 printf(“%.2f”, sqrt(900.0)); 调用函数sqrt,返回其参数900.0的平方根 所有的数学函数返回double型的Program modules in c 双语课堂目 录第六讲 函数
  • 217. 函数 Functions函数 使程序模块化(modulization) 在函数内声明的变量都是局部变量(local variable) 参数是函数间交流信息的途径,它们也是局部变量 函数的好处 分而治之 使程序的开发易于管理(managable program development) 软件重用(software reusability) 使用现有的函数作为构件来创建程序 抽象(abstraction):隐藏了实现的细节(库函数) 避免代码重复(repetition)Program modules in c 双语课堂目 录第六讲 函数
  • 218. 举例:函数 Example: Function举例:函数(cw06-01.c) 写一个程序,使用square函数计算从1到10所有整数的平方Function definitions 双语课堂目 录第六讲 函数#include int square(int); void main() { int x; for (x=1; x<=10; x++) printf("%d ", square(x)); } int square(int y) { return y*y; }函数原型函数调用函数定义1 4 9 16 25 36 49 64 81 100
  • 219. 函数的定义 Function Definitions函数定义的格式 return-value-type function-name(parameter-list) { declarations and statements } function-name(函数名):任何有效的标识符 return-value-type(返回值类型):结果的数据类型 缺省是 int void —— 表示函数不返回任何值 parameter-list(参数列表):声明参数,用逗号分隔 必须为每个参数指定数据类型 但 int 可以省略Function definitions 双语课堂目 录第六讲 函数
  • 220. 函数的定义 Function Definitions函数定义的格式 return-value-type function-name(parameter-list) { declarations and statements } declarations and statements(声明和语句):函数体 在函数体内可以声明变量,即局部变量 不能定义函数,即函数的定义不允许嵌套 Returning control:把程序的控制返回到调用函数的位置 } return; return expression;Function definitions 双语课堂目 录第六讲 函数不返回结果返回结果
  • 221. 举例:函数的定义 Example: Function Definitions举例:函数定义(cw06-02.c) Function definitions 双语课堂目 录第六讲 函数#include int maximum(int, int, int); void main() { int a, b, c; printf("enter three integers: "); scanf("%d%d%d", &a, &b, &c); printf("Maximum is: %d", maximum(a, b, c)); } int maximum(int x, int y, int z) { int max = x; if (y>max) max = y; if (z>max) max = z; return max; }maximumintintintint函数原型
  • 222. 函数原型 Function Prototypes函数原型 return-value-type function-name(parameter-list); 函数名 参数(类型、数量、顺序) 返回值类型 编译程序使用函数原型来测试函数调用 函数原型要与函数的定义匹配 如果函数的定义在函数调用的后面就需要函数原型 例如 int maximum(int, int, int);Function prototypes 双语课堂目 录第六讲 函数
  • 223. 函数原型 Function Prototypes函数原型在程序文件中的位置不同,作用范围不同 在所有函数的外面 函数原型将应用于所有出现在文件中函数原型之后的函数调用中 在函数内部 函数原型只能用于该函数中的函数调用Function prototypes 双语课堂目 录第六讲 函数main() { } void funcA() { int funcB(int); } int funcB(int) { }函数funcB只能在funcA中被使用
  • 224. 函数原型 Function Prototypes函数原型强迫参数采用正确的数据类型 举例 printf(“%.3f”, sqrt(4) ); 函数原型使编译程序把整数值4转换为double型的值4.0 没有与函数原型中的参数类型完全对应的参数值会在调用函数之前被转换成合适的数据类型 遵守C语言的提升规则Function prototypes 双语课堂目 录第六讲 函数double sqrt(double);
  • 225. 函数原型 Function Prototypes如果程序中没有包含函数原型 编译程序会使用该函数第一次出现的情形来形成自己的函数原型 函数的定义 函数的调用 默认情况下,编译程序假定函数返回int型的结果,但不会对参数进行任何假定 如果传递给函数的参数不正确,编译程序不会检测到这些错误Function prototypes 双语课堂目 录第六讲 函数
  • 226. 头文件 Head Files头文件 每个标准库函数都有对应的头文件 包含了标准库中所有函数的函数原型,以及那些函数所需的数据类型和常量的定义 stdio.h, math.h, string.h 使用#include命令把头文件包含到程序文件中 #include 例如,#include 程序员可以创建自己的头文件 使用.h扩展名 使用下面的命令格式包含头文件 #include “filename”Head files 双语课堂目 录第六讲 函数
  • 227. 函数调用 Function Call函数调用(function call) 激发函数(invoking functions) 提供函数名和参数(argument) 函数完成指定的任务 函数可以返回结果(result) 类比 老板命令工人去完成一项任务 工人获取信息,完成任务,返回报告 “隐藏”(hiding):老板不知道细节Program modules in c 双语课堂目 录第六讲 函数BossWorker1Worker2Worker3 Worker4Worker5主调函数函数调用被调函数
  • 228. 函数调用 Function Call函数调用的执行过程 Function call 双语课堂目 录第六讲 函数main() { int a, b, c; scanf("%d%d", &a, &b); c = max(a, b); printf("the larger is %d", c); }126int max(int a, int b) { int c; c=a>=b?a:b; return c; }3451、…… 2、主调函数暂停, 3、把实参的值拷贝给形参,控制权传给函数 max 。 4、……5、结束被调函数,把函数值返回给主调函数,同时把控制权还给主调函数。 6、……
  • 229. 参数传递 Passing Parameters函数间的数据传递 参数(传递) 结果(返回)Function call 双语课堂目 录第六讲 函数int max(int a, int b) { …… return c; } main() { …… c=max(a, b); }max()abcmain()参数传递返回值传递
  • 230. 按值调用和按引用调用 Call By Value And Call By Reference调用函数的两种途径 按值调用 把参数的值的副本传递给函数 在函数内改变参数的值不会影响调用函数中的参数的原始值 如果函数不需要修改参数的值,就采用这种调用方式 按引用调用 把参数传递给函数 在函数内改变参数的值将改变参数的原始值 用于可信的函数 在C语言中,所有调用都是按值调用Function call 双语课堂目 录第六讲 函数
  • 231. 形参和实参 Formal Parameter and Actual Parameter形参和实参 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; return c; } main() { int a, b, c; scanf(“%d%d”, &a, &b); c=max(a, b); }形式参数 简称“形参”。在函数定义时表示可以接受实际参数的值实际参数 简称“实参”。在函数调用时给出
  • 232. 形参 Formal Parameter形参 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; return c; } main() { int a, b, c; scanf(“%d%d”, &a, &b); c=max(a, b); }只有在函数被调用、启动后,才临时为其分配存储单元,并接受主调函数传来的数据。 在函数调用结束后,形参所占存储单元被释放。
  • 233. 实参 Actual Parameter实参 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; return c; } main() { int a, b, c; scanf(“%d%d”, &a, &b); c=max(a, b); }实参是函数调用时主调函数传送给被调函数的参数的实际值。 实参可以是常量、变量和表达式。 实参必须有确定的值。
  • 234. 参数传递 Passing Parameters实参和形参应该一一对应 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; return c; } main() { int x=6, y; y=max(x, x++); printf(“%d”, y); }当实参表列中有多个实参时,对实参的求值顺序并不确定。 Turbo C是按从右往左的顺序求值。b=x++; a=x;7在参数传递时
  • 235. 参数传递 Passing Parameters值传递 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; a++; b++; return c; } main() { int x=6, y=5, z; z=max(x, y); printf(“%d,%d,%d”,x,y,z); }实参与形参不共用存储单元。 参数传递时,把实参的值复制一份给形参。 形参值的变化不影响实参的值。 所以,形参和实参可以同名。6,5,66x5y6a5b
  • 236. 参数传递 Passing Parameters实参和形参的类型应该相同或赋值兼容 Function call 双语课堂目 录第六讲 函数int max(int a, int b) { int c=a>=b?a:b; return c; } main() { int x=6, y=5, z; z=max(x, y); printf(“%d”, z); }如果a, b是整型,则调用合法; 如果a, b是字符型,因为字符型与整型可以互换,所以也是合法的; 如果a, b是短整型,则进行类型自动转换,结果也正确; 如果a或b是实数,则结果有可能不正确。b=y; a=x;在参数传递时
  • 237. 函数返回值 Returning Results函数返回值的类型应该与函数的类型一致 如果不一致,以函数类型为准,对返回值进行类型转换Function call 双语课堂目 录第六讲 函数int max(int a, int b) { float c=a>=b?a:b; return c; } main() { int x=6, y=5, z; z = 2*max(x, y); printf(“%d”, z); }c 的类型? 返回值的类型?max(x,y) 的类型? 2*max(x,y) 的类型?
  • 238. 函数的嵌套调用 Nested Function Call嵌套调用 在调用一个函数的过程中又调用另一个函数Function call 双语课堂目 录第六讲 函数主函数调用函数 1函数 1调用函数 2函数 2123456789
  • 239. 函数的嵌套调用 Nested Function Call举例:计算圆环的面积(cw06-03.c) 分析 圆环的面积 = 外圆的面积 – 内圆的面积 可以定义两个函数 circleArea 计算圆的面积 ringArea 计算圆环的面积Function call 双语课堂目 录第六讲 函数r1r2circleAreadoubledoubleringAreadoubledoubledoubledouble circleArea(double r); double ringArea(double r1, double r2);
  • 240. 函数的嵌套调用 Nested Function Call举例:计算圆环的面积(cw06-03.c) Function call 双语课堂目 录第六讲 函数#include #define PI 3.14 double circleArea(double r); double ringArea(double r1, double r2); void main() { double r1, r2, s; printf("\tInput r1, r2: "); scanf("%lf%lf", &r1, &r2); s = ringArea(r1, r2); printf("\n\tThe area is:%.2lf\n", s); }
  • 241. 函数的嵌套调用 Nested Function Call举例:计算圆环的面积(cw06-03.c) Function call 双语课堂目 录第六讲 函数double circleArea(double r) { return PI*r*r; } double ringArea(double r1, double r2) { if (r1<=r2) return circleArea(r2)-circleArea(r1); else return circleArea(r1)-circleArea(r2); }Input r1, r2: 1 2 The area is: 9.42
  • 242. 递归函数 Recursive Functions递归函数(Recursive Functions) 直接或间接调用自己的函数Recursion 双语课堂目 录第六讲 函数函数 1调用函数 1函数 1调用函数 2函数 2调用函数 1
  • 243. 递归 Recursion用递归(函数)解决问题 递归函数只知道如何去解最简单的情形(基本情形) 简单的返回一个值 把复杂的问题分成两部分: 函数知道如何去做的部分 函数不知道如何去做的部分 这一部分与原问题相似,且更简单 函数可以调用自己的新形式来解决这个更小的问题(递归调用) 最终遇到基本情形 函数识别出基本情形,将结果返回给前一个情形 一系列的结果按顺序返回 直到把最终结果返回给原始的调用者(可能是main)Recursion 双语课堂目 录第六讲 函数
  • 244. 递归 Recursion举例:用递归方法计算n! 分析 5! = 5 * 4 * 3 * 2 * 1 5! = 5 * 4! 4! = 4 * 3!... 递归公式Recursion 双语课堂目 录第六讲 函数n ! =1 (n=0或1)n*(n-1)! (n>1)基本情形简化问题
  • 245. 递归 Recursion举例:用递归方法计算n!(cw06-05.c) Recursion 双语课堂目 录第六讲 函数#include long fac(int n) { long f; if (n==0||n==1) f=1; else f=n*fac(n-1); printf("\t%d!=%ld\n", n, f); return f; } void main( ) { printf("\n\t5!=%ld\n", fac(5)); }1!=1 2!=2 3!=6 4!=24 5!=120 5!=120递归调用
  • 246. 递归 Recursion举例:用递归方法计算n! 分析递归过程Recursion 双语课堂目 录第六讲 函数5!5*4!4*3!3*2!2*1!11205*244*63*22*11递归调用从递归调用返回值
  • 247. 递归 Recursion举例:用递归方法计算斐波拉契数列 0 1 1 2 3 5 8 … 分析 每个数是前两个数的和 递归公式 fib(n) = fib(n-1) + fib(n-2) fib(1) = 0 fib(2) = 1Recursion 双语课堂目 录第六讲 函数
  • 248. 递归 Recursion举例:用递归方法计算斐波拉契数列 #include int fib(int); int main(){ int n; for( n=1;n<=10;n++) printf("%d", fib(n)); return 0; } int fib(int n){ if (n==1||n==2) return 1; else return (fib(n-1)+fib(n-2)); }Recursion 双语课堂目 录第六讲 函数
  • 249. 递归与迭代 Recursion vs. Iteration循环 迭代:明确使用了循环结构 递归:重复调用递归函数 终止条件 迭代:循环条件不满足 递归:遇到基本情形 都有可能出现无限循环 选择 迭代:性能好 递归:可读性好Recursion 双语课堂目 录第六讲 函数
  • 250. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 问题 假设有三个分别命名为X,Y和Z的塔座,在塔座X上插有n个直径大小个不相同、依从小到大编号为1,2,…,n的圆盘。现要求将X轴上的n个圆盘移到塔座Z上,并按同样的顺序叠放。 移动时必须遵循以下规则: 每次只能移动一个圆盘; 圆盘可以插在X,Y和Z中的任一塔座上; 任何时候都不能将一个较大的圆盘压在较小的圆盘之上。Recursion 双语课堂目 录第六讲 函数XYZ
  • 251. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 分析 n=1时 将圆盘1从塔座X移到塔座Z。Recursion 双语课堂目 录第六讲 函数XYZXYZ基本情形
  • 252. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 分析 n>1时 Recursion 双语课堂目 录第六讲 函数XYZXYZXYZXYZ递归调用1. 利用塔座z为辅助塔座,将压在圆盘n之上的n-1个盘从塔座X移到塔座Y; (——与原问题类似) 2. 将圆盘n从塔座X移到塔座Z; 3. 利用塔座X为辅助塔座,将塔座Y上的n-1个圆盘移动到塔座Z。 (——与原问题类似)
  • 253. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 设计 move 函数:移动一个盘 把盘 n 从 s 塔移到 d 塔 hanoi 函数:移动n个盘的汉诺塔问题 把 n 个盘从 x 塔移到 z 塔,y 塔作为辅助塔Recursion 双语课堂目 录第六讲 函数void move(int n, char s, char d); void hanoi(int n, char x, char y, char z);
  • 254. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 实现(cw06-06.c) Recursion 双语课堂目 录第六讲 函数#include void move(int n, char s, char d); void hanoi(int n, char x, char y, char z); void main() { int n; printf("\t Input the number of disks:"); scanf("%d", &n); hanoi(n, 'X', 'Y', 'Z'); }
  • 255. 汉诺塔问题 Towers Of Hanoi递归问题举例:汉诺塔 实现(cw06-06.c) Recursion 双语课堂目 录第六讲 函数void hanoi(int n, char x, char y, char z) { if (n==1) move(n, x, z); else { hanoi(n-1, x, z, y); move(n, x, z); hanoi(n-1, y, x, z); } } void move(int n, char s, char d) { printf("\t%d\t%c-->%c\n", n, s, d); }
  • 256. 存储类别 Storage Classes变量定义的完整格式 存储类别 数据类型 变量名 数据类型 占据存储空间的大小 取值范围 存储类别 在内存中持续的时间(生存期) 在硬件中存放的位置 其它属性 作用范围 可以被引用的程序部分(可见性)Storage classes 双语课堂目 录第六讲 函数int a; void main() { int b; … } int max(int x, int y) { … }全局变量局部变量局部变量
  • 257. 存储类别 Storage Classes四种存储类别说明符 auto register extern static 两种存储持续时间 自动存储持续时间 auto register 静态存储持续时间 extern staticStorage classes 双语课堂目 录第六讲 函数
  • 258. 自动存储类别 Automatic Storage自动存储 变量在它所在的程序块内被创建和销毁 auto(自动变量):局部变量的缺省类别 函数体中声明的变量,函数的参数,程序块中声明的变量 register(寄存器变量):建议编译器把变量放进高速的寄存器 只适用于自动变量Storage classes 双语课堂目 录第六讲 函数auto int a, b;register int count = 1;
  • 259. 静态存储类别 Static Storage静态存储 在程序执行期间,变量存在 系统给定缺省初值:0 或 ‘\0’ static(静态变量):用于在函数体中声明的变量 函数结束后依然存在,并保留值 但不改变其作用范围,即只能在所在的程序块内被使用 extern(外部变量):在函数外声明的变量(全局变量)的缺省类别 在所有函数中都可以被使用Storage classes 双语课堂目 录第六讲 函数static int a, b;extern int total;
  • 260. 自动变量与静态变量 Automatic Variables and Static Variables举例:存储类别(cw06-07.c) Storage classes双语课堂目 录第六讲 函数void func(int a) { auto int b=10; static int c=10; b++; c++; printf("a=%d\tb=%d\tc=%d\n", a, b, c); } void main() { int i; for (i=1;i<=3;i++) func(i); }a=1 b=11 c=11 a=2 b=11 c=12 a=3 b=11 c=13
  • 261. 自动变量与静态变量 Automatic Variables and Static Variables举例:存储类别 Storage classes双语课堂目 录第六讲 函数cababab123动态存储区静态存储区FF00220822062206220422042202a=1 b=11 c=11 a=2 b=11 c=12 a=3 b=11 c=13
  • 262. 自动变量与静态变量 Automatic Variables and Static VariablesC语言程序的内存映像 Storage classes双语课堂目 录第六讲 函数存放全局变量和标明为静态类的局部变量。栈:保存函数调用时的返回地址、函数的形参、局部变量,以及CPU的当前状态。 堆:自由内存区域。程序代码全局变量堆栈程序可以访问的内存区域。数据段代码段动态存储区用户区静态存储区
  • 263. 作用范围 Scope标识符的作用范围 能够引用该标识符的程序部分 四种作用范围: 函数作用范围(function scope) 文件作用范围(file scope) 程序块作用范围(block scope) 函数原型作用范围(function prototype scope)Scope 双语课堂目 录第六讲 函数
  • 264. 文件作用范围 File Scope文件作用范围 在函数外声明的标识符,在所有函数中可以被引用 全局变量,函数定义,函数原型Scope 双语课堂目 录第六讲 函数int total; int max(int, int); void main() { … } int limit; int max(int x, int y) { … }作用范围 从声明的位置开始,到文件的末尾
  • 265. 函数作用范围 Function Scope函数作用范围 在函数体内定义的标识符,只能在函数体内被引用 语句标号Scope 双语课堂目 录第六讲 函数void main() { … loop: … goto loop; }
  • 266. 程序块作用范围 Block Scope程序块作用范围 在程序块内声明的变量,在程序块内被引用 函数体内声明的变量,函数的参数,程序块内的变量Scope 双语课堂目 录第六讲 函数int max(int x, int y) { … } void main() { int a; … { int a; … } … }作用范围 从声明的位置开始,到程序块的右大括号隐藏 同名变量,内部变量“隐藏了”外部变量
  • 267. 函数原型作用范围 Function Prototype Scope函数原型作用范围 函数原型中的参数Scope 双语课堂目 录第六讲 函数int max(int x, int y); void main() { … } int max(int x, int y) { … }
  • 268. 存储类别与作用范围 Storage Classes And Scope举例:存储类别与作用范围(cw06-08.c) Scope 双语课堂目 录第六讲 函数#include void a(void); /*function prototype*/ void b(void); /*function prototype*/ void c(void); /*function prototype*/ int x = 1; /*global variable*/ void main() { int x = 5; printf("local x in outer scope of main is %d\n", x); { /*start new scope*/ int x = 7; printf("local x in inner scope of main is %d\n", x); } /*end new scope*/ printf("\nlocal x in outer scope of main is %d\n", x);
  • 269. 存储类别与作用范围 Storage Classes And Scope举例:存储类别与作用范围(cw06-08.c) Scope 双语课堂目 录第六讲 函数 a(); b(); c(); a(); b(); c(); printf("local x in main is %d\n", x); } void a() { int x = 25; /*initialized each time a is called*/ printf("\nlocal x in a is %d after entering\n", x); x++; printf("local x in a is %d before exiting\n", x); }
  • 270. 存储类别与作用范围 Storage Classes And Scope举例:存储类别与作用范围(cw06-08.c) Scope 双语课堂目 录第六讲 函数void b() { static int x = 50; /*static initialization only*/ /*first time b is called*/ printf("\nlocal x in b is %d after entering\n", x); x++; printf("local x in b is %d before exiting\n", x); } void c() { printf("\nglobal x is %d on entering c\n", x); x*=10; printf("global x is %d on exiting c\n", x); }
  • 271. 存储类别与作用范围 Storage Classes And Scope举例:存储类别与作用范围(cw06-08.c) Scope 双语课堂目 录第六讲 函数local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 local x in a is 25 after entering a local x in a is 26 before exiting a local x in b is 50 after entering b local x in b is 51 before exiting b global x is 1 on entering c global x is 10 on exiting c
  • 272. 存储类别与作用范围 Storage Classes And Scope举例:存储类别与作用范围(cw06-08.c) Scope 双语课堂目 录第六讲 函数local x in a is 25 after entering a local x in a is 26 before exiting a local x in b is 51 after entering b local x in b is 52 before exiting b global x is 10 on entering c global x is 100 on exiting c local x in main is 5
  • 273. 包含多个源文件的程序 Programs With Multiple Source Files包含多个源文件的程序 每个函数的定义必须在一个文件内,不能被分割 全局变量可以被同一文件内的函数访问 如果需要被其他文件内的函数访问,则必须在其他文件内声明 extern 表示该变量是在另一个文件内定义的 在一个文件内定义的函数,也可以被其他文件内的函数调用 在每个文件内加入该函数的原型(声明为外部函数) 函数的原型不需要 externPrograms multiple source files双语课堂目 录第六讲 函数int myGlobal;extern int myGlobal;
  • 274. 包含多个源文件的程序 Programs With Multiple Source FilesExample: programs with multiple source filesPrograms with multiple source files双语课堂目 录第六讲 函数int a, b; extern int max(void); void main() { scanf("%d%d", &a, &b); printf("%d", max()); }extern int a, b; int max() { return (a>b?a:b); } ABcw06-09a.ccw06-09b.c
  • 275. 包含多个源文件的程序 Programs With Multiple Source Files包含多个源文件的程序 static 限制全局变量只能被同一文件内的函数访问 限制函数只能被同一文件内的函数调用Programs with multiple source files双语课堂目 录第六讲 函数static int myGlobal; static void myFunc() { … }
  • 276. 编译多个源文件的程序 Compiling Multiple-Source-File Programs编译多个源文件的程序 每个源文件必须被编译,然后链接成一个可执行文件 如果有一个文件作了改动,则必须重新编译所有相关的文件 一般会提供 make 工具用来管理和编译多源文件的程序 创建 makefile 文件记录编译规则 自动查找必须编译的源文件 可以创建工程(project)文件来管理多源文件的程序Programs with multiple source files双语课堂目 录第六讲 函数
  • 277. 预处理命令——#define 在C语言源程序中允许用一个标识符来表示一个字符串, 称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换, 这称为“宏代换”或“宏展开”。 宏定义是由源程序中的宏定义命令完成的。 宏代换是由预处理程序自动完成的。 在C语言中,“宏”分为有参数和无参数两种。 下面分别讨论这两种“宏”的定义和调用。Programs with multiple source files双语课堂目 录第六讲 函数
  • 278. 预处理命令——#define 1、无参宏定义 无参宏的宏名后不带参数。其定义的一般形式为: #define 标识符 字符串 其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。 “标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。 宏定义#define: 形式 #define 宏名 宏体 例: #include #define PI 3.1415926 double circum() { double radius; scanf(“%f”,&radius); return(2.0*radius*PI); } Programs with multiple source files双语课堂目 录第六讲 函数
  • 279. 预处理命令——#define 2使用自变量宏(有参数的宏) 形式 #define 宏名(参数) 宏体 例:#include #define POWER(X) X*X*X int main() { int i; printf(“Input an integer:”) scanf(“%d”,&i); printf(“%d*%d*d=%d\n”,i,i,i,POWER(i)); return 0; } Programs with multiple source files双语课堂目 录第六讲 函数
  • 280. 预处理命令——#define 例:#include #define POWER(X) X*X*X int main(void) { int i; printf(“Input an integer:”) scanf(“%d”,&i); printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,POWER(i+1)); return 0; } Programs with multiple source files双语课堂目 录第六讲 函数
  • 281. 预处理命令——#define 例:#include #define POWER(X) X*X*X int main(void) { int i; printf(“Input an integer:”) scanf(“%d”,&i); printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,POWER(i+1)); return 0; } printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,i+1*i+1*i+1)); Programs with multiple source files双语课堂目 录第六讲 函数
  • 282. 预处理命令——#define 例:#include #define POWER(X) (X)*(X)*(X) int main(void) { int i; printf(“Input an integer:”) scanf(“%d”,&i); printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,POWER(i+1)); return 0; } Programs with multiple source files双语课堂目 录第六讲 函数
  • 283. 预处理命令——#define 例:#include #define POWER(X) (X)*(X)*(X) int main(void) { int i; printf(“Input an integer:”) scanf(“%d”,&i); printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,POWER(i+1)); return 0; } printf(“%d*%d*d=%d\n”,i+1,i+1,i+1,(i+1)*(i+1)*(i+1)); Programs with multiple source files双语课堂目 录第六讲 函数
  • 284. 使用自定义的头文件 文件area.h #define PI 3.14 #define CIRCLE(r) ((PI)*(r)*(r)) #define RECTANGLE(length,height) ((length)*(height)) #define TRUANGLE(base,height) ((base)*(heigth)/2) 头文件就是放在程序最前面的文件。 #include #include int main(void) { float base, height; scanf(“%f”,& base); scanf(“%f”,&height); printf(“triangle is %.2f”, TRUANGLE(base,height)); return 0; }Programs with multiple source files双语课堂目 录第六讲 函数
  • 285. 程序设计举例 ExamplesExample: Functions(cw06-11.c) 问题 每个玩家掷两个骰子。每个骰子都有6个面。这些面中包含了1点、2点、3点、4点、5点和6点。当骰子静止下来之后,计算两个朝上的面中的点数和。 如果第一次投掷的结果是7 或11,那么这个玩家就获胜。 如果第一次投掷的结果是2、3或12,那么这个玩家就输了(即庄家获胜)。 如果第一次投掷的结果是4、5、6、8、9或10,那么这个和就是该玩家的“点数”。 为了获胜,玩家必须继续掷骰子,直到“掷出了点数”。在掷出点数之前,如果玩家掷出了7,那么玩家就输了。Examples双语课堂目 录第六讲 函数
  • 286. 程序设计举例 ExamplesExample: Functions(cw06-11.c) 设计 定义一个函数 rollDice,用来模拟掷一次骰子 产生两个随机数,返回它们的和(点数) 算法Examples双语课堂目 录第六讲 函数掷第一次胜输掷一次胜输?
  • 287. 程序设计举例 ExamplesExample: Functions(cw06-11.c) 设计 定义一个变量保存游戏进展的状态 gamestatus 0:失败 1:胜利 2:第一次掷就失败 算法 Examples双语课堂目 录第六讲 函数rollDiceEnd?rollDiceEnd?NNYYWin or fail
  • 288. 程序设计举例 ExamplesExample: Functions(cw06-11.c) Examples双语课堂目 录第六讲 函数#include #include #include int rollDice(void); void main() { int gameStatus, sum, myPoint; srand(time(NULL)); sum = rollDice();
  • 289. 程序设计举例 ExamplesExample: Functions(cw06-11.c) Examples双语课堂目 录第六讲 函数 switch(sum) { case 7: case 11: gameStatus = 1; break; case 2: case 3: case 12: gameStatus = 2; break; default: gameStatus = 0; myPoint = sum; printf("Point is %d\n", myPoint); break; }
  • 290. 程序设计举例 ExamplesExample: Functions(cw06-11.c) Examples双语课堂目 录第六讲 函数 while (gameStatus == 0) { sum = rollDice(); if (sum == myPoint) gameStatus = 1; else if (sum == 7) gameStatus = 2; } if (gameStatus == 1) printf("You wins!"); else printf("You loses!"); }
  • 291. 程序设计举例 ExamplesExample: Functions(cw06-11.c) Examples双语课堂目 录第六讲 函数int rollDice() { int dice1, dice2, sum; dice1 = rand()%6 + 1; dice2 = rand()%6 + 1; sum = dice1 + dice2; printf("You rolled %d + %d = %d\n", dice1, dice2, sum); return sum; }
  • 292. 第七讲 数组与字符串 Arrays and StringsPROGRAM DESIGN IN C LANGUAGE双语课堂目 录7.2 数组Arrays7.3 查找与排序Searching and sorting7.4 多维数组Multiplr subscripted arrays7.5 字符串Strings7.1 简介Introduction
  • 293. 简介 IntroductionArrays(数组) Data Structures of related data items Static entity(静态实体) same size throughout programIntroduction双语课堂目 录第七讲 数组与字符串6572837997877957…78
  • 294. 数组 Arrays数组(Array):由一组相同类型的变量组成的数据类型,它们以一个共同的名称表示。 在内存中数组占有一段连续的存储空间 保存一组有序数据 数组中的每一个数称为数组元素(element) 数组元素都属于同一个数据类型 数组元素的数目是固定且有限的 引用数组元素的格式 arrayname[position-number] 第一个位置编号(下标)是 0 数组 c 的 n 个元素如图所示Ayrrays双语课堂目 录第七讲 数组与字符串-45 6 0 72 1543 -89 0 62 -3 1 6453 78 c[6] c[0] c[1] c[2] c[3] c[11] c[10] c[9] c[8] c[7] c[5] c[4] c
  • 295. 数组 Arrays数组(Array) 数组元素都是普通变量 下标可以是整型常量和整型表达式 Ayrrays双语课堂目 录第七讲 数组与字符串-45 6 0 72 1543 -89 0 62 -3 1 6453 78 c[6] c[0] c[1] c[2] c[3] c[11] c[10] c[9] c[8] c[7] c[5] c[4] cc[0] = 3; scanf(“%d”, &c[1]); printf(“%d”, c[1]);若 x = 3, 那么 c[5-2] == c[3] == c[x]
  • 296. 定义数组 Defining Arrays定义数组的格式 arrayType arrayName[numberOfElements] 数组类型 数组名 元素个数(数组长度) 数组长度必须是一个整型常量或常量表达式Ayrrays双语课堂目 录第七讲 数组与字符串#define MAX 200; int c[12]; float f[1000]; int b[MAX], c[MAX*10];int n, m=5, d[m]; scanf(“%d”,&n); int c[n];float f[1000]; char name[10];
  • 297. 数组的初始化 Arrays Inilialization数组的初始化 arrayType arrayName[numberOfElements] = {valueList}; 初值表 如果数据表中的数据太多,产生语法错误(syntax error) 剩下的元素的初值是 0 数组的长度就是初值表中数值的个数Ayrrays双语课堂目 录第七讲 数组与字符串int a[5] = {1, 2, 3, 4, 5};int a[5] = {1};int a[ ] = {1, 2, 3, 4, 5};
  • 298. 数组的初始化的说明 Notes For Arrays Inilialization数组的初始化说明 初值表不能为空 没有初始化的数组,其元素的值不确定Ayrrays双语课堂目 录第七讲 数组与字符串int a[5] = { };int a[5]={1}; for (i=0;i<5;i++) printf(“ %d”,a[i]);int a[5]; for (i=0;i<5;i++) printf(“ %d”,a[i]); 1 0 0 0 0 872 0 1492 4160 186不可预知
  • 299. 使用数组 Using ArraysExample:数组的输入与输出 Ayrrays双语课堂目 录第七讲 数组与字符串#include int main(void) {int i,score[5]; for (i=0; i<=4; i++) { printf(“Input score:”); scanf(“%d”,&score[i]); } printf(”***Output***”); for (i=0; i<=4; i++) printf(“score[%d]=%d\n", i,score[i]); return 0; }
  • 300. 使用数组 Using ArraysExample:将数组中的最大值及最小值输出 Ayrrays双语课堂目 录第七讲 数组与字符串 #include int main() { int A[5]={74,48,30,89,62}; int i,min,max; min=max=A[0]; printf("elements in arrray A are "); for(i=0;i<5;i++) {printf("%d ",A[i]); if(A[i]>max) max=A[i]; if (A[i]
  • 301. 使用数组 Using ArraysExample:数组查找 Ayrrays双语课堂目 录第七讲 数组与字符串#define SIZE 6 int main() { int i,num,flag=0; int A[SIZE]={33,75,69,41,33,19}; scanf(“%d“,&num); for(i=0;i
  • 302. 使用数组 Using ArraysExample:Using Arrays(cw07-01.c) 从一个数组中读取数字,并以直方图的形式显示信息 Ayrrays双语课堂目 录第七讲 数组与字符串#include #define SIZE 10 void main() { int n[SIZE] = {19, 2, 15, 7, 11, 9, 13, 5, 17, 1}; int i ,j;用一系列 ‘*’ 来代替长方形************** *** *******
  • 303. 使用数组 Using ArraysExample:Using Arrays(cw07-01.c) Ayrrays双语课堂目 录第七讲 数组与字符串 printf("%s%13s%17s\n", "Element", "Value", "Histogram"); for (i=0; i<=SIZE-1; i++) { printf("%7d%13d", i, n[i]); for (j=1; j<=n[i]; j++) printf("%c", '*'); printf("\n"); } }
  • 304. 使用数组 Using ArraysExample:Using Arrays(cw07-01.c) 运行结果Ayrrays双语课堂目 录第七讲 数组与字符串Element Value Histogram 0 19 ******************* 1 3 *** 2 15 *************** 3 7 ******* 4 11 *********** 5 9 ********* 6 13 ************* 7 5 ***** 8 17 ***************** 9 1 *
  • 305. 使用数组 Using ArraysExample:Using Arrays(cw07-02a.c) 统计全班10名同学某门功课的平均成绩,找出最高分 把学生成绩保存到数组 scoreAyrrays双语课堂目 录第七讲 数组与字符串#include #define MAX 10 void main() { float score[MAX], sum, best; int i; printf("Input %d scores:\n",MAX); for (i=0; i
  • 306. 使用数组 Using ArraysExample:Using Arrays(cw07-02a.c) Ayrrays双语课堂目 录第七讲 数组与字符串 sum=best=score[0]; for (i=1;i
  • 307. #include #define MAX 10 void main() { float score[MAX], sum; int i, best; printf("Input %d scores:\n",MAX); for (i=0; i
  • 308. 使用数组 Using ArraysExample:Using Arrays(cw07-02b.c) Ayrrays双语课堂目 录第七讲 数组与字符串 sum=score[0]; best=0; for (i=1; i
  • 309. #include #include #include #define SIZE 7 void main() { int face, roll, frequency[SIZE]={0}; srand(time(NULL));使用数组 Using ArraysExample:Using Arrays(cw07-03.c) 把一个六面的骰子掷6000次,统计每一面出现的次数 用frequency[6]数组保存六个面出现的次数Ayrrays双语课堂目 录第七讲 数组与字符串初始化数组,为所有指定初值 0frequency[1], …, frequency[6]
  • 310. for (roll=1; roll<=1000; roll++) { face = rand()%6+1; frequency[face]++; } printf("%s%17s\n", "Face", "Frequency"); for (face=1; face<=SIZE-1; face++) printf("%4d%17d\n", face, frequency[face]); }使用数组 Using ArraysExample:Using Arrays(cw07-03.c) Ayrrays双语课堂目 录第七讲 数组与字符串
  • 311. 使用数组 Using ArraysExample:Using Arrays(cw07-04.c) 把一个任意的正整数 N 转换成 d 进制数 用 N 除以 d, 如果商不为 0,继续用商除以 d,直到商为 0 用数组 remainder 保存每一步的余数Ayrrays双语课堂目 录第七讲 数组与字符串NN/8N%8134816841682102125202
  • 312. #include #define MAX 10 void main() { int N, d, len; int remainder[MAX]; printf("Input a decimal integer and a base:"); scanf("%d%d", &N, &d); printf("Converting...\n");使用数组 Using ArraysExample:Using Arrays(cw07-04.c) Ayrrays双语课堂目 录第七讲 数组与字符串
  • 313. len=0; while (N) { len++; remainder[len]=N%d; N=N/d; } printf("equals "); for (;len>0;len--) printf("%d",remainder[len]); }使用数组 Using ArraysExample:Using Arrays(cw07-04.c) Ayrrays双语课堂目 录第七讲 数组与字符串
  • 314. 多维数组 Multiple-Subscripted Arrays多维数组 一个有行号和列号的表 矩阵或行列式 Example int a[3][4];MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串Row 0 Row 1 Row 2 Column 0 Column 1 Column 2 Column 3 a[ 0 ][ 0 ] a[ 1 ][ 0 ] a[ 2 ][ 0 ] a[ 0 ][ 1 ] a[ 1 ][ 1 ] a[ 2 ][ 1 ] a[ 0 ][ 2 ] a[ 1 ][ 2 ] a[ 2 ][ 2 ] a[ 0 ][ 3 ] a[ 1 ][ 3 ] a[ 2 ][ 3 ] Row subscript Array name Column subscript
  • 315. 多维数组的定义 Multiple-Subscripted Arrays’ Definition定义多维数组的格式 type-name array-name[row-number][column-number]; 类型名 数组名 常量表达式 常量表达式 Example MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[3][3], b[30][3]; char name[30][20]; float score[30][5];a[3][3] 二维数组可以看作是由一维数组组成的数组,即数组元素是一维数组的一维数组。a[0]a[0][0]a[0][1]a[0][2]a[1]a[1][0]a[1][1]a[1][2]a[2]a[2][0]a[2][1]a[2][2]
  • 316. 引用多维数组的元素 Referencing Multiple-Subscripted Arrays’ Elements引用多维数组的元素的格式 array-name[row-subscript][column-subscript]; 数组名 行下标 列下标 Example MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[3][4]; for (m=0;m<3;m++) for (n=0;n<4;n++) a[m][n]=m*n;
  • 317. 多维数组的存储形式 Multiple-Subscripted Arrays’ Storage二维数组的存储形式 二维数组的元素是按行顺序存放的 Example int a[2][3];MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]12 32 -1 87 0 53 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]a数组 a 的存储形式
  • 318. 多维数组的初始化 Multiple-Subscripted Arrays’ Initialization二维数组的初始化 四种方式: 给全部元素赋初值 给部分元素赋初值 给全部元素赋初值时,不指定第一维的长度,但要指定第二维的长度 给部分元素赋初值时,不指定第一维的长度,但要指定第二维的长度MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串
  • 319. 多维数组的初始化 Multiple-Subscripted Arrays’ Initialization二维数组的初始化 给全部元素赋初值MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[2][3]={{10,11,12},{13,14,15}}; int a[2][3]={10,11,12,13,14,15};a[0][0]a[0][1]a[0][2]101112a[1][0]a[1][1]a[1][2]131415用括号按行分组
  • 320. 多维数组的初始化 Multiple-Subscripted Arrays’ Initialization二维数组的初始化 给部分元素赋初值MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[2][3]={{10,11},{13}};a[0][0]a[0][1]a[0][2]10110a[1][0]a[1][1]a[1][2]1300int a[2][3]={10,11,13};a[0][0]a[0][1]a[0][2]101113a[1][0]a[1][1]a[1][2]000没有明确初始化的元素被自动初始化
  • 321. 多维数组的初始化 Multiple-Subscripted Arrays’ Initialization二维数组的初始化 给全部元素赋初值时,不指定第一维的长度,但要指定第二维的长度MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[ ][3]={{10,11,12},{13,14,15}}; int a[ ][3]={10,11,12,13,14,15};a[0][0]a[0][1]a[0][2]101112a[1][0]a[1][1]a[1][2]131415
  • 322. 多维数组的初始化 Multiple-Subscripted Arrays’ Initialization二维数组的初始化 给部分元素赋初值时,不指定第一维的长度,但要指定第二维的长度MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int a[ ][3]={{10,11},{13}};a[0][0]a[0][1]a[0][2]10110a[1][0]a[1][1]a[1][2]1300
  • 323. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample: Multiple-Subscripted Arrays 将一个二维数组行和列元素互换,存到另一个二维数组中MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串b的第i行第j列的元素 等于 a的第j行第i列的元素for(i=0;i<3;i++) for(j=0;j<2;j++) b[i][j] = a[j][i]
  • 324. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample: Multiple-Subscripted Arrays (ca07-13.c)MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串#include void main() { int a[2][3]={1,2,3,4,5,6}, b[3][2]; int i, j; printf("matrix a is:\n"); for (i=0; i<2; i++) { for (j=0; j<3; j++) { b[j][i] = a[i][j]; printf("%3d", a[i][j]); } printf("\n"); }
  • 325. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample: Multiple-Subscripted Arrays (ca07-13.c)MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串 printf("matrix b is:\n"); for (i=0; i<3; i++) { for (j=0; j<2; j++) printf("%3d", b[i][j]); printf("\n"); } }matrix a is: 1 2 3 4 5 6 matrix b is: 1 4 2 5 3 6
  • 326. 把数组传递给函数 Passing Arrays to Functions把数组作为参数传递给函数 实参用数组名 通常要把数组的长度传递给函数 对应的函数定义 实参与形参的类型相同 可以不指定形参数组长度 函数原型的特殊形式Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串int myArray[20]; myFunction(myArray, 20);void myFunction(int array[], int arraySize) { }void myFunction(int [], int);
  • 327. 把数组传递给函数 Passing Arrays to Functions把数组作为实参传递给函数 数组的传递模拟了引用传递(call-by-reference)例9-10 Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串void bubble_sort(int array[ ], int len) {…} main() { int list[10]; … bubble_sort(list, 10); }list[0] list[1] list[2] … list[9]FF00FF00listFF00array数组名是数组第一个元素的地址 所以,依然是按值传递(传递的是地址)
  • 328. 把数组传递给函数 Passing Arrays to Functions把数组作为实参传递给函数 数组名是一个指针变量,保存的是数组第一个元素的地址(cw07-05.c) Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串#include void main() { int array[10]; printf("array = %p\n" "&array[0] = %p\n", array, &array[0]); }array = 19b8 &array[0] = 19b8%p 输出地址的格式说明字符printf的格式控制字符串可以分多行写,但每一行必须用“”括起来
  • 329. 把数组传递给函数 Passing Arrays to Functions把数组元素传递给函数 数组元素就是一个普通的变量 按值传递(call-by-value) Example: Passing arrays and elements to functions (cw07-06.c)Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串#include void modifyArray(int [], int); void modifyElement(int); void main() { int a[] = {0, 1, 2, 3, 4}, i;
  • 330. 把数组传递给函数 Passing Arrays to FunctionsExample:(cw07-06.c)Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串 printf("\nThe values of the original array are:\n"); for (i=0;i
  • 331. 把数组传递给函数 Passing Arrays to FunctionsExample:(cw07-06.c)Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串void modifyArray(int array[], int size) { int j; for (j=0;j
  • 332. 把数组传递给函数 Passing Arrays to FunctionsExample:(cw07-06.c)Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串The values of the original array are: 0 1 2 3 4 The values of the modified array are: 0 2 4 6 8 The value of a[3] is 6 Value in modifyElement is 12 The value of a[3] is 6
  • 333. 查找 Searching查找 查找数组中的特定元素(key value) 常用方法 顺序查找(sequential searching) 折半查找(binary searching)Searching Arrays双语课堂目 录第七讲 数组与字符串
  • 334. 顺序查找 Sequential Searching顺序查找 用关键字与数组的每个元素进行比较 适用于小型和(或)没有排序的数组 平均而言,要与数组的一半元素进行比较Sequential Searching双语课堂目 录第七讲 数组与字符串6572837997877957917887
  • 335. 顺序查找 Sequential SearchingExample: Sequential searching(cw07-07.c) Sequential Searching双语课堂目 录第七讲 数组与字符串#define N 10 void main() { int list[N+1]={0,65,72,83,79,97,87,75,57,91,78}; int key,i; printf("Input search key:"); scanf("%d",&key); for (i=1;(list[i]!=key)&&(i<=N);i++); if (i>N) printf("Not found!"); else printf("Success! The position is %d.",i); }
  • 336. 折半查找 Binary Searching折半查找 用于已经排好序的数组 用数组的中间元素与关键字比较 如果相等,则查找成功 如果keymiddle,则查找后半部分 重复上述步骤Binary Searching双语课堂目 录第七讲 数组与字符串5765727578798387919783lowmidhigh
  • 337. 折半查找 Binary SearchingExample: Binary searching(cw07-08.c) Binary Searching双语课堂目 录第七讲 数组与字符串#include #define N 10 void main() { int i, low, mid, high, key, found; int list[N+1]={0,57,65,72,75,78,79,83,87,91,97}; printf("Sorted list:\n"); for (i=1;i<=N;i++) printf("%-4d", list[i]); printf("\n"); printf("Input search key:"); scanf("%d", &key);
  • 338. 折半查找 Binary SearchingExample: Binary searching(cw07-08.c) Binary Searching双语课堂目 录第七讲 数组与字符串 low=1; high=N; found=0; while ((low<=high) && (! found)) { mid=(low+high)/2; if (key>list[mid]) low=mid+1; else if (key==list[mid]) found=1; else high=mid-1; } if (found) printf("Success! The position is %d.", mid); else printf("Not found!"); }
  • 339. 排序 Sorting排序 数据排序(按特定的顺序来安排数据)是最重要的计算应用之一 实际上,每个组织都必须排列某些数据 常用方法 直接插入排序(directive insert sorting) 简单选择排序(simple selection sorting) 冒泡排序(bubble sorting)Sorting Arrays双语课堂目 录第七讲 数组与字符串
  • 340. 数据插入 Insert Data数据插入 把一个数据插入到已排好序的有序表中,从而得到一个新的、长度增1的有序表Directive Insert Sorting双语课堂目 录第七讲 数组与字符串5765727578798791978357657275787983879197576572757879879197
  • 341. 数据插入 Insert DataExample: Inserting data (cw07-09.c)Directive Insert Sorting双语课堂目 录第七讲 数组与字符串#include #define N 20 void main() { int i, j, x, len=9; int list[N]={57,65,72,75,78,79,87,91,97}; printf("Sorted list:\n"); for (i=0;i
  • 342. 数据插入 Insert DataExample: Inserting data (cw07-09.c)Directive Insert Sorting双语课堂目 录第七讲 数组与字符串 for (i=0;(x>list[i])&&(ii;j--) list[j]=list[j-1]; list[i]=x; len++; printf("The new list:\n"); for (i=0;i
  • 343. 直接插入排序 Directive Insert Sorting直接插入排序 Directive Insert Sorting双语课堂目 录第七讲 数组与字符串(78) 45 25 31 13 66 92 8初始状态(45 78) 25 31 13 66 92 8插入第2个数(25 45 78) 31 13 66 92 8插入第3个数(8 13 25 31 45 66 78 92)插入最后一个数……
  • 344. 直接插入排序 Directive Insert SortingExample: directive insert sorting (cw07-10.c)Directive Insert Sorting双语课堂目 录第七讲 数组与字符串#include #define N 10 void main() { int i, j, k, len; int list[N], x; printf("Input several integers to construct a list:"); scanf("%d", &len); for (i=0;i
  • 345. 直接插入排序 Directive Insert SortingExample: directive insert sorting (cw07-10.c)Directive Insert Sorting双语课堂目 录第七讲 数组与字符串 printf("\nTo sort...\n"); for (i=1;ilist[j])&&(jj;k--) list[k]=list[k-1]; list[j]=x; } printf("Finished! The list has been sorted:\n"); for (i=0;i
  • 346. 简单选择排序 Simple Selection Sorting简单选择排序 Simple Selection Sorting双语课堂目 录第七讲 数组与字符串78 45 25 31 13 66 92 8初始状态(8) 45 31 13 25 66 92 78找到最小数(8 13) 31 45 66 92 25 78找到第二小的数(8 13 25 31 45 66 78 92)最大数被找到……一趟简单选择排序的操作:通过n-i次数据间的比较,从n-i+1个记录中选出最小的数,并和第i个数交换。
  • 347. 简单选择排序 Simple Selection SortingExample: Simple selection sorting (cw07-12.c)Simple Selection Sorting双语课堂目 录第七讲 数组与字符串#include #define N 10 void main() { int i, j, len, min; int list[N], tmp; printf("Input several integers to construct a list:"); scanf("%d", &len); for (i=0;i
  • 348. 简单选择排序 Simple Selection SortingExample: Simple selection sorting (cw07-12.c)Simple Selection Sorting双语课堂目 录第七讲 数组与字符串 printf("\nTo sort...\n"); for (i=0;ilist[j]) min=j; tmp=list[i]; list[i]=list[min]; list[min]=tmp; } printf("Finished! The list has been sorted:\n"); for (i=0;i
  • 349. 简单选择排序 Simple Selection SortingExample: Simple selection sorting (cw07-12.c)Simple Selection Sorting双语课堂目 录第七讲 数组与字符串 printf("\nTo sort...\n"); for (i=0;ilist[j]) min=j; tmp=list[i]; list[i]=list[min]; list[min]=tmp; } printf("Finished! The list has been sorted:\n"); for (i=0;i
  • 350. 冒泡排序 Bubble Sorting冒泡排序 将相邻两个数比较,把小的调到前面,大数放到后面。Bubble Sorting双语课堂目 录第七讲 数组与字符串78 45 32 10 29 80 92 8 61 5545 78 32 10 29 80 92 8 61 5545 32 78 10 29 80 92 8 61 5545 32 10 78 29 80 92 8 61 5545 32 10 29 78 80 92 8 61 5545 32 10 29 78 80 92 8 61 5545 32 10 29 78 80 92 8 61 5545 32 10 29 78 80 8 92 61 5545 32 10 29 78 80 8 61 92 5545 32 10 29 78 80 8 61 55 9232 10 29 45 78 8 61 55 80 9210 29 32 45 8 61 55 78 80 92…8 10 29 32 45 55 61 78 80 92小数大数N-1 趟
  • 351. 冒泡排序 Bubble SortingExample: Bubble sorting (cw07-11.c)Bubble Sorting双语课堂目 录第七讲 数组与字符串#include #define N 10 void main() { int i, j, len; int list[N], tmp; printf("Input several integers to construct a list:"); scanf("%d", &len); for (i=0;i
  • 352. 冒泡排序 Bubble SortingExample: Bubble sorting (cw07-11.c)Bubble Sorting双语课堂目 录第七讲 数组与字符串 printf("\nTo sort...\n"); for (i=0;ilist[j+1]) { tmp=list[j]; list[j]=list[j+1]; list[j+1]=tmp; } printf("Finished! The list has been sorted:\n"); for (i=0;i
  • 353. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample: Multiple-Subscripted Arrays 有一个3×4的矩阵,找出每行元素中的最大值,并使该值成为该行的首列元素 分析 对每行元素从右往左相邻两数作比较,大数调到左边MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串利用从冒泡法排序算法中得到的经验
  • 354. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample: Multiple-Subscripted Arrays (ca07-14.c)MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串…… for (i=0; i<3; i++) for (j=3; j>0; j--) if (num[i][j]>num[i][j-1]) { tmp = num[i][j]; num[i][j] = num[i][j-1]; num[i][j-1] = tmp; } ……
  • 355. 把多维数组传递给函数 Passing Multiple-Subscripted Arrays To Functions把多维数组传递给函数 数组元素作为函数的实参 值传递 多维数组名作为函数的实参 模拟引用传递MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串void exchange(int a[][4]); void main() { int a[3][4]; … exchange(a); … } 第1括号可以为空,其他下标必须指定
  • 356. 传递“值”还是“地址”到函数例9-17输出变量的地址Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串void fun(int a); main() { int a=13; printf(“in main a=%d,addr=%p”,a,&a); fun(a); return 0; }0253FDB0void fun(int a) { printf(“in fun a=%d,addr=%p”,a,&a); }13130253FDD4
  • 357. 传递“值”还是“地址”到函数输出 输出数组的地址例9-18 Passing Ayrrays To Functions双语课堂目 录第七讲 数组与字符串void fun(int b[]); main() { int i, list[10]={20,8,13,6}; for(i=0;i<10;i++) printf(“list[%d]=%2d,addr=%p\n”,I,list[i],&list[i]); fun(list); }list[0] list[1] list[2] … list[9]FF00FF00listFF00bvoid fun(int b[]){ for(i=0;i<10;i++) printf(“b[%d]=%2d,addr=%p\n”,i,b[i],&b[i]);}
  • 358. 字符串 StringsCharacters(字符) Character constant An int value represented as a character in single quotes 'z' represents the integer value of z Strings(字符串) Series of characters treated as a single unit Can include letters, digits and special characters (*, /, $) String constant written in double quotes "Hello"STRINGS双语课堂目 录第七讲 数组与字符串
  • 359. 字符串的定义 Strings’ Definition在C语言中,字符串是用空字符(’\0’)结束的字符数组 STRINGS双语课堂目 录第七讲 数组与字符串char name[20]; …name字符串名就是该字符数组第一个元素的地址
  • 360. 字符数组的初始化 Character Arrays’ Initialization给字符数组的全部元素赋初值 STRINGS双语课堂目 录第七讲 数组与字符串char a[5]={‘C’,’h’,’i’,’n’,’a’};a[0]a[1]a[2]a[3]a[4]‘C’‘h’‘i’‘n’‘a’
  • 361. 字符数组的初始化 Character Arrays’ Initialization给字符数组的部分元素赋初值 STRINGS双语课堂目 录第七讲 数组与字符串char a[5]={‘C’,’h’,’i’};a[0]a[1]a[2]a[3]a[4]‘C’‘h’‘i’‘\0’‘\0’缺省的初值为 ‘\0’
  • 362. 字符数组的初始化 Character Arrays’ Initialization给全部元素赋初值时,可以不指定长度 STRINGS双语课堂目 录第七讲 数组与字符串char a[ ]={‘C’,’h’,’i’,’n’,’a’};a[0]a[1]a[2]a[3]a[4]‘C’‘h’‘i’‘n’‘a’char a[5]={‘C’,’h’,’i’,’n’,’a’};
  • 363. char a[ ] = {“China”};char a[ ] = “China”;字符数组的初始化 Character Arrays’ Initialization用字符串常量给字符数组赋初值 STRINGS双语课堂目 录第七讲 数组与字符串char a[6] = {“China”};char a[6] = “China”;a[0]a[1]a[2]a[3]a[4]a[5]‘C’‘h’‘i’‘n’‘a’‘\0’来自字符串常量的 结束字符 ‘\0’ 。
  • 364. 字符串的输入输出 Strings’ Input/Output有以下方式: scanf()与printf()函数 逐个字符输入输出 %c 作为整体一次输入输出 %s 用字符串输入输出函数 gets putsSTRINGS双语课堂目 录第七讲 数组与字符串
  • 365. 字符串的输入输出 Strings’ Input/Output用%c逐个字符的输入输出 (cw07-15.c)STRINGS双语课堂目 录第七讲 数组与字符串#include #define MAX 5 void main() { int n; char c[MAX]; printf("Input %d characters:\n",MAX); for (n=0;n
  • 366. 字符串的输入输出 Strings’ Input/Output用%s实现字符串作为整体一次性的输入输出 (cw07-16.c)STRINGS双语课堂目 录第七讲 数组与字符串#include #define MAX 5 void main() { char c[MAX]; printf("Input c[%d]:\n",MAX); scanf("%s",c); printf("Show c:\n"); printf("%s",c); }输入和输出项都是数组名 在输入时,空格、制表符和换行符都被作为字符串的分隔符,不被读入 在输出时,一旦遇到 ‘\0’ 就结束
  • 367. 字符串的输入输出 Strings’ Input/Output用标准库提供的输入输出函数 (cw07-17.c)STRINGS双语课堂目 录第七讲 数组与字符串#include #define MAX 5 void main() { char c[MAX]; printf("Input c[%d]:\n",MAX); gets(c); printf("Show c:\n"); puts(c); }在输入时,换行符被作为数据的分隔符,不被读入 但是,空格和制表符可以被读入
  • 368. 字符和字符串处理库 Character And String Handling Library字符处理库: 字符的检测和处理函数 字符串处理库: 字符串处理函数 strcat(string1, string2) strcpy(string1, string2) strcmp(string1, string2) strlen(string) strlwr(string) strupr(string) 字符串转换库:(general utilities lib) 把数字字符串转换成整数和浮点数STRINGS双语课堂目 录第七讲 数组与字符串
  • 369. 字符串应用举例 Examples: String HandlingExample: String Handling 输入一行字符,统计其中有多少个单词,单词之间用空格隔开STRINGS双语课堂目 录第七讲 数组与字符串Iamfrom…\0算法: 逐一检测字符,遇到第一个非空格字符即为一个单词的开始,再次遇到空格就表示最新的单词结束 定义一个标记变量 记住当前字符的前一个字符(最近检测的)是否是空格
  • 370. 字符串应用举例 Examples: String HandlingExample: String Handling 定义标记变量 word 0 最近检测的字符是空格 期待新单词出现 1 最近检测的字符不是空格 正在检测单词 期待单词的结束STRINGS双语课堂目 录第七讲 数组与字符串i=0 word=0c=s[i]!=‘\0’c==‘ ’word=0i++word==0word=1 num++NYNYNY
  • 371. 字符串应用举例 Examples: String HandlingExample: String Handling (cw07-18.c)STRINGS双语课堂目 录第七讲 数组与字符串#include void main() { char c, s[81]; int i, num, word; printf("Input a sentence:\n"); gets(s);
  • 372. 字符串应用举例 Examples: String HandlingExample: String Handling (cw07-18.c)STRINGS双语课堂目 录第七讲 数组与字符串 num=word=i=0; while ((c=s[i])!='\0') { if (c==' ') word=0; else if (word==0) { word=1; num++; } i++; } printf("There are %d words in this sentence.\n", num); }扩展: 输出这些单词 统计每个单词出现的次数
  • 373. 字符串应用举例 Examples: String HandlingExample: String Handling 任意输入两个字符串,将它们连接成一个字符串,不使用strcat函数STRINGS双语课堂目 录第七讲 数组与字符串abc\0xyz\0abcxyz\0
  • 374. 字符串应用举例 Examples: String HandlingExample: String Handling (cw07-19.c)STRINGS双语课堂目 录第七讲 数组与字符串#include void main() { char str1[81], str2[81], str[161]; int i, j; printf("Input two strings:\n"); gets(str1); gets(str2); for(i=0;str1[i]!='\0';i++) str[i]=str1[i]; for(j=0;str2[j]!='\0';i++,j++) str[i]=str2[j]; str[i]='\0'; printf("\nNow, you get a new string:\n%s\n", str); }
  • 375. 字符串应用举例 Examples: String HandlingExample: String Handling 输入一字符串,内有若干个字符,再输入一个字符,要求程序将字符串中该字符删去STRINGS双语课堂目 录第七讲 数组与字符串wuhanda\0wuhanda\0读写char str[81]
  • 376. 字符串应用举例 Examples: String HandlingExample: String Handling (cw07-20.c)STRINGS双语课堂目 录第七讲 数组与字符串#include void main() { void delLetter(char str[], char c); char str[81], c; printf("Input a string:\n"); gets(str); printf("Input a letter:\n"); c=getchar(); delLetter(str, c); printf("Delete all \'%c\' from the string.\n", c); printf("The string:\n"); puts(str); }
  • 377. 字符串应用举例 Examples: String HandlingExample: String Handling (cw07-20.c)STRINGS双语课堂目 录第七讲 数组与字符串void delLetter(char str[81], char c) { int i, j; for (i=j=0;str[i]!='\0';i++) if (str[i]!=c) { str[j]=str[i]; j++; } str[j]='\0'; }
  • 378. 字符串数组的定义与初始化赋值 Strings’ Arrays’ Definition and Initialization字符串本身是用空字符(’\0’)结束的字符数组,而字符串数组,就如同是二维数组,或是字符数组的数组。 STRINGS双语课堂目 录第七讲 数组与字符串char 字符数组名[数组大小][字符串长度] char names [3][10]={“David”,”Jane Wang”,”Tom Lee ”} names字符串数组名就是该字符串数组第一个元素的地址…DavidJane WagTom Lee \0divaDgaWdenaJ\0
  • 379. 字符串数组应用举例 Examples: Strings’ Arrays HandlingExample: 字符串数组的输入输出 (cw09-23.c)STRINGS双语课堂目 录第七讲 数组与字符串#include int main(void) { char students[3][10]; int i; for(i=0;i<3;i++) { printf(“Inpunt student%d’s name:”,i); gets(students[i]); } puts(“***Out Put***”); for(i=0;i<3;i++) printf(“Inpunt student[%d]=%s\n”,i,student[i]); return 0; }
  • 380. 程序设计举例 Programming ExamplesExample: TicTacToe 写程序实现“井”字棋游戏。 “井”字棋游戏规则: 每次一方只能在某一个空格处下一颗棋子 胜负判断: 若棋盘的某一行,或某一列,抑或某一对角线上的三个格子被某一方的棋子占据,则该方胜利; 否则,为平局PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串
  • 381. 程序设计举例 Programming ExamplesExample: TicTacToe 过程分析: PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串玩家胜利计算机胜利初始化棋盘玩家下一颗棋子胜利?计算机下一颗棋子胜利?YYNN怎么表示?怎么判断?计算机如何决策?
  • 382. 程序设计举例 Programming ExamplesExample: TicTacToe 功能分解: PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串玩家胜利计算机胜利初始化棋盘玩家下一颗棋子胜利?计算机下一颗棋子胜利?YYNN初始化棋盘显示棋盘玩家走一步判断胜负计算机走一步判断胜负
  • 383. 程序设计举例 Programming ExamplesExample: TicTacToe 模块划分: PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串初始化棋盘: init_matrix()显示棋盘: disp_matrix()玩家走一步: get_player_move()判断胜负: check()计算机走一步: get_computer_move()main
  • 384. 程序设计举例 Programming ExamplesExample: TicTacToe 数据结构: 棋盘PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串3*3的二维字符数组: char matrix[3][3]; 全局变量。玩家的棋子用‘X’表示; 计算机的棋子用‘O’表示; ‘ ’表示空。一步棋 棋子的位置:一对坐标
  • 385. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串char matrix[3][3]; /* the ticktacktoe matrix */ void main(void) { char done; printf("This is the game of ticktacktoe.\n"); printf("You will be playing against the computer.\n"); done = ' '; init_matrix();done 保存当前游戏的状态和结局
  • 386. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串 do { disp_matrix(); get_player_move(); done = check(); /* see if winner */ if (done != ' ') break; /* winner! */ get_computer_move(); done = check(); /* see if winner */ } while (done == ' '); if (done == 'X') printf("You won!\n"); else printf("I won!!!!\n"); disp_matrix(); /* show final positions */ }
  • 387. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串/* Initialize the matrix. */ void init_matrix(void) { int i, j; for (i=0; i<3; i++) for (j=0; j<3; j++) matrix[i][j] = ' '; }
  • 388. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串/* Get a player's move. */ void get_player_move(void) { int x, y; printf("Enter X, Y coordinates for your move: "); scanf("%d%*c%d", &x, &y); x--; y--; if (matrix[x][y] != ' ') { printf("Invalid move, try again.\n"); get_player_move(); } else matrix[x][y] = 'X'; }
  • 389. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c) PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串/* Get a move from the computer. */ void get_computer_move(void) { int i, j; for (i=0; i<3; i++) { for (j=0; j<3; j++) if (matrix[i][j] == ' ') break; if (matrix[i][j] == ' ') break; } if (i*j == 9) { printf("draw\n"); exit(0); } else matrix[i][j] = 'O'; }
  • 390. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串/* Display the matrix on the screen. */ void disp_matrix(void) { int t; for (t=0; t<3; t++) { printf(" %c | %c | %c", matrix[t][0], matrix[t][1], matrix[t][2]); if (t != 2) printf("\n---|---|---\n"); } printf("\n"); }
  • 391. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串/* See if there is a winner. */ char check(void) { int i; for (i=0; i<3; i++) /* check rows */ if (matrix[i][0] == matrix[i][1] && matrix[i][0] == matrix[i][2]) return matrix[i][0]; for (i=0; i<3; i++) /* check colums */ if (matrix[0][i] == matrix[1][i] && matrix[0][i] == matrix[2][i]) return matrix[0][i];
  • 392. 程序设计举例 Programming ExamplesExample: TicTacToe (tictac.c)PROGRAMMING EXAMPLES双语课堂目 录第七讲 数组与字符串 /* test disgonals */ if (matrix[0][0] == matrix[1][1] && matrix[1][1] == matrix[2][2]) return matrix[0][0]; if (matrix[0][2] == matrix[1][1] && matrix[1][1] == matrix[2][0]) return matrix[0][2]; return ' '; }
  • 393. 第八讲 指针 PointersPROGRAM DESIGN IN C LANGUAGE双语课堂目 录8.2 指针变量Pointer variables8.7 指针数组Arrays of pointers8.8 指针的指针Pointers to pointers8.9 函数指针Pointers to functions8.1 简介Introduction8.4 指针参数Pointer arguments8.3 指针运算符Pointer operators8.6 指针与数组Pointers and arrays8.5 指针表达式和运算Pointer expressions and arithmetic8.10 指针函数Pointer functions
  • 394. 简介 IntroductionPointers Powerful, but difficult to master Simulate call-by-reference Close relationship with arrays and strings Create and control dynamic data structures List, queue, stack and treeTHE POINTERS 双语课堂目 录第八讲 指针
  • 395. 指针和地址 Pointers and Addresses指针就是变量的地址 THE POINTERS 双语课堂目 录第八讲 指针int x; x=23;内存单元的地址 一个常量,就是指向变量的指针。变量名 其实就是符号化的内存单元地址。内存单元的内容 就是变量的值。FF00x23直接引用 Direct reference 通过变量名直接引用变量的值
  • 396. 指针变量 Pointer Variables指针变量就是包含内存地址的变量 THE POINTERS 双语课堂目 录第八讲 指针int x=23; int *x_pointer; x_pointer=&x;FF00x23FFF0x_pointerFF00指针变量 保存变量的地址。 变量 x_pointer 的值是变量 x 的地址(指针)。 目前,指针 x_pointer 指向变量 x 。间接引用 Indirect reference 通过指针间接引用变量的值
  • 397. 指针变量的声明 Pointer Variable Declarations指针变量的声明 type-name * pointer-variable-name; * 表示 x_pointer 是一个指针变量 x_pointer 是 int* 类型的指针,读作: 指向 int 的指针 指向整数类型的对象 指针可以声明为指向任何数据类型的对象 声明多个指针时,每个变量前都必须有 * THE POINTERS 双语课堂目 录第八讲 指针int *x_pointer;int *x_pointer, *y_pointer; char *charPtr;
  • 398. 指针变量的初始化 Pointer Variable Initializations指针变量的初始化 在声明或赋值语句中初始化指针 指针变量可以被初始化为 0 ,NULL 或 地址 0 和 NULL 是等价的(用NULL更好) NULL 是在(和几个其他头文件)中定义的符号常量THE POINTERS 双语课堂目 录第八讲 指针int x, *p=&x;int x, *p=0xffe;int x, *p=(int *)0xffe;强制类型转换int x, *p=NULL;空指针:不指向任何对象
  • 399. 指针运算符 Pointer Operators&(address operator,地址运算符) Returns address of operandTHE POINTERS 双语课堂目 录第八讲 指针int y, *yPtr; y = 5; yPtr = &y;5yPtrfff0yff00yPtry5Address of y is value of yPtryPtr “points to” yff00
  • 400. 指针运算符 Pointer Operators*(indirective operator,间接运算符,指针运算符) Returns a alias of what its operand points to *yPtr returns y (because yPtr points to y) 可以用在赋值语句中THE POINTERS 双语课堂目 录第八讲 指针int y=5, *yPtr; yPtr = &y;int y, *yPtr; yPtr = &y; *yPtr = 5;
  • 401. 指针运算符举例 Example: Pointer OperatorsExample: Pointer operators (cw08-01.c) THE POINTERS 双语课堂目 录第八讲 指针#include void main() { int a, *aPtr; a = 7; aPtr = &a; printf("The address of a is %p" "\nThe value of aPtr is %p", &a, aPtr); printf("\n\nThe value of a is %d" "\nThe value of *aPtr is %d", a, *aPtr); printf("\n\nShowing that * and & are inverses of each other." "\n&*aPtr = %p" "\n*&aPtr = %p", &*aPtr, *&aPtr); }
  • 402. 指针运算符举例 Example: Pointer OperatorsExample: Pointer operators (cw08-01.c) 运行结果THE POINTERS 双语课堂目 录第八讲 指针The address of a is 1A58 The value of aPtr is 1A58 The value of a is 7 The value of *aPtr is 7 Showing that * and & are inverses of each other. &*aPtr = 1A58 *&aPtr = 1A58* 和 & 是互反的
  • 403. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针可以进行以下运算: 赋值运算 给指针变量赋值 关系运算 两个指针之间的比较 算术运算 加(减)一个整数 两个指针相减THE POINTERS 双语课堂目 录第八讲 指针
  • 404. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的赋值运算: 可以把同类型的指针赋给指针变量THE POINTERS 双语课堂目 录第八讲 指针int x=10, *p, *q; p = &x; q = p; printf(“*q=%d", *q);*q=1010x2000p2000q2000
  • 405. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的赋值运算: 把类型不同的指针赋值给指针变量时要进行类型转换 但 void * 类型的指针是一个例外THE POINTERS 双语课堂目 录第八讲 指针int a, *intPtr=&a; char *charPtr; charPtr = (char*)intPtr;int a, *intPtr=&a; char *charPtr; void *voidPtr; voidPtr = intPtr; charPtr = voidPtr;void* 通用指针,代表任何指针类型 不能间接引用
  • 406. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的关系运算: 比较两个指针包含的内存地址THE POINTERS 双语课堂目 录第八讲 指针p1 < p2 p1 <= p2 p1 > p2 p1 >= p2 p1 == p2 p1 != p22000p12002p2char *charPtr; … charPtr >= (char*)2000与同类型的常量指针比较 常常与 0 比较
  • 407. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的算术运算: 自增自减(++,--) 加上一个整数(+,+=,-,-=) 两个指针相减 在数组上执行才有意义THE POINTERS 双语课堂目 录第八讲 指针
  • 408. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的算术运算 举例 vPtr + 2THE POINTERS 双语课堂目 录第八讲 指针int v[4],*vPtr; vPtr = v; vPtr = vPtr + 2;2000200220042006数组 vvPtr2000 + 2 = 20022000 + 2*2 = 2004vPtr基类型的长度?
  • 409. 指针表达式和算术运算 Pointer Expressions and Arithmetic指针的算术运算 举例 vP2 – vP1 = 2THE POINTERS 双语课堂目 录第八讲 指针int v[4],*vP1, *vP2; vP1 = v; vP2 = &v[2];2000200220042006数组 vvP1vP2vP2和vP1之间元素的个数?指针的算术运算在数组上使用才有意义
  • 410. 指针与函数 Pointer Arguments指针的另一个好处 解决在函数间传递多个返回值得问题 用指针参数模拟引用调用 用指针作为函数的形式参数 调用函数时,用 & 运算符把实际参数的地址传递给函数 在被调用函数中,用 * 运算符间接引用实际参数 THE POINTERS 双语课堂目 录第八讲 指针
  • 411. 指针与函数举例 Example: Pointer ArgumentsExample: call by value (cw08-02a.c)THE POINTERS 双语课堂目 录第八讲 指针#include int callByValue(int); void main() { int number = 5; printf("The original value of number is %d", number); number = callByValue(number); printf("\nThe new value of number is %d", number); } int callByValue(int n) { return n*n*n; }The original value of number is 5 The new value of number is 125
  • 412. 指针与函数举例 Example: Pointer ArgumentsExample: call by reference with pointer arguments (cw08-02b.c)THE POINTERS 双语课堂目 录第八讲 指针#include void callByReference(int*); void main() { int number = 5; printf("The original value of number is %d", number); callByReference(&number); printf("\nThe new value of number is %d", number); } void callByReference(int *nPtr) { *nPtr = *nPtr**nPtr**nPtr; }The original value of number is 5 The new value of number is 125
  • 413. 指针与函数举例 Example: Pointer ArgumentsExample: call by reference with pointer arguments 分析THE POINTERS 双语课堂目 录第八讲 指针void main() { int number = 5; callByReference(&number); }void callByReference(int *nPtr) { *nPtr = *nPtr**nPtr**nPtr; }void main() { int number = 5; callByReference(&number); }void callByReference(int *nPtr) { *nPtr = *nPtr**nPtr**nPtr; }void main() { int number = 5; callByReference(&number); }void callByReference(int *nPtr) { *nPtr = *nPtr**nPtr**nPtr; }nPtr5numbernPtr125numbernPtr125number调用前调用后返回
  • 414. 指针与函数举例 Example: Pointer ArgumentsExample: swap the values of two arguments THE POINTERS 双语课堂目 录第八讲 指针void swap(int x, int y) { int tmp; tmp=x; x=y; y=tmp; } void main() { int a=3, b=5; swap(a, b); printf("a=%d,b=%d",a,b); }a=3,b=5void swap(int *x, int *y) { int tmp; tmp=*x; *x=*y; *y=tmp; } void main() { int a=3, b=5; swap(&a, &b); printf("a=%d,b=%d",a,b); }a=5,b=3
  • 415. 指针与函数举例 Example: Pointer ArgumentsExample: 返回多个数值的函数 THE POINTERS 双语课堂目 录第八讲 指针void rect(int ,int, int*,int *); int main(void ) { int a=5, b=8,area,length; rect(a, b,&area,&length); printf(“area=%d,length=%d", area, length); return 0; } void rect(int x,int y, int* ptr1,int * ptr2) { *ptr1=x*y; *ptr2=2*(x+y); }area=40, length =26
  • 416. 指针与数组的关系 The Relationship Between Pointers and Arrays数组和指针是密切相关的 数组名可以认为是常量指针 指针可以用来完成任何涉及数组下标的操作 将 bPtr 设置为等于数组 b 中的地一个元素的地址 bPtr = b; 等价于 bPtr = &b[0]; THE POINTERS 双语课堂目 录第八讲 指针int b[5]; int *bPtr;
  • 417. 指针与数组的关系 The Relationship Between Pointers and Arrays数组和指针是密切相关的 引用数组元素的表达式 数组元素 b[3] 可以用 *(bPtr + 3) 来引用 3是偏移量(offset) 这种表示法称为指针/偏移量表示法 还可以用 bPtr[3] 来引用 称为指针/下标表示法 与 b[3] 相同 还可以用 *(b + 3) 来引用 把数组本身作为指针处理THE POINTERS 双语课堂目 录第八讲 指针
  • 418. 指针与数组的关系 The Relationship Between Pointers and Arrays引用数组元素的方法小结 数组和指针几乎可以互换使用THE POINTERS 双语课堂目 录第八讲 指针main() { int i, a[5]={1,2,3,4,5}; for (i=0; i<5; i++) printf("%2d",a[i]); }下标法main() { int i, a[5]={1,2,3,4,5}; for (i=0; i<5; i++) printf("%2d",*(a+i)); }地址法main() { int a[5]={1,2,3,4,5}, *p; for (p=a; p<(a+5); p++) printf("%2d",*p); }指针法
  • 419. 指针与数组的关系 The Relationship Between Pointers and Arrays数组和指针互换使用中的注意事项 THE POINTERS 双语课堂目 录第八讲 指针因为a是数组名,即数组的首地址,它的值在程序运行期间是固定不变的! 是一个常量指针。错main() { int a[5]={1,2,3,4,5}, *p; for ( p=a; a<(p+5); a++ ) printf("%2d",*a); }
  • 420. 指针与数组的关系 The Relationship Between Pointers and Arrays数组和指针互换使用中的注意事项 THE POINTERS 双语课堂目 录第八讲 指针要注意指针变量的当前值。ppa[0]a[1]a[2]a[3]a[4]数组amain() { int i, a[5], *p; p=a; for ( i=0; i<5; i++ ) scanf( "%d", p++ ); for ( i=0; i<5; i++, p++ ) printf( "%d ", *p ); }错p = a;
  • 421. 指针与数组的关系 The Relationship Between Pointers and Arrays数组和指针互换使用中的注意事项 注意运算符的优先级THE POINTERS 双语课堂目 录第八讲 指针* aPtr ++* (aPtr ++)等价考虑: *(aPtr++) 与 *(++aPtr)int a=0, *aPtr=&a; printf("a=%d,aPtr=%p\n", a, aPtr); printf("%d\n", *aPtr++); printf("a=%d,aPtr=%p\n", a, aPtr);a=0,aPtr=1BCC 0 a=0,aPtr=1BCE
  • 422. 指针与数组的关系 The Relationship Between Pointers and Arrays举例:数组和指针的互换使用 按引用调用的冒泡排序THE POINTERS 双语课堂目 录第八讲 指针void sort( int *x , int n) { … } void main() { int a[10]; … … sort( a , 10); … }a, xa[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]地址
  • 423. 字符串指针 Pointers Point To Strings字符串指针 让字符指针指向字符串(字符数组)THE POINTERS 双语课堂目 录第八讲 指针char str[20]=“China”, *p=str; printf(“%s”, p);China\0str, pchar *p=“China”; printf(“%s”, p);C语言对字符串常量是按字符数组处理的。char *p; p=“China”; printf(“%s”, p);China\0p
  • 424. 字符串指针 Pointers Point To Strings字符数组和字符(串)指针 初始化和赋值THE POINTERS 双语课堂目 录第八讲 指针char str[5]= “wuhan”;char *p=“wuhan”;char *p; p=“wuhan”;char str[5]; str= “wuhan”;=≠错对
  • 425. 字符串指针 Pointers Point To Strings字符数组和字符(串)指针 输入字符串THE POINTERS 双语课堂目 录第八讲 指针char *p; scanf(“%s”, p);char str[5], *p; p=str; scanf(“%s”, p);char str[5]; scanf(“%s”, str);错对对在编译时为字符串数组分配内存单元,有确定的地址 虽然为字符指针变量分配了内存单元,但其值(地址)是不确定的,不可以使用
  • 426. 字符串指针 Pointers Point To Strings举例:字符数组和字符(串)指针的互换使用 字符串的复制THE POINTERS 双语课堂目 录第八讲 指针China\0Chinese\0afrmbtoChina\0e\0bvoid strCopy(char *frm, char *to) { while((*to=*frm)!='\0') { frm++; to++; } } void main() { char *a="China"; char *b="Chinese"; strCopy(a, b); printf("%s", b); }China
  • 427. 指针数组 Arrays Of Pointers指针数组 数组元素是指针 type-name *array-name[constant-expression]; 常用来构造字符串数组: 字符串并不在 suit 数组中 suit 数组只包含指向字符串的指针THE POINTERS 双语课堂目 录第八讲 指针char *suit[4] = {“Hearts”, “Diamonds”, “Clubs”, “Spades”};suit[3] suit[2] suit[1] suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’ ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’\0’ ’C’ ’l’ ’u’ ’b’ ’s’ ’\0’ ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’\0’ suit 的长度是固定的,但却可以访问任意长度的字符串
  • 428. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 定义数据结构 字符串(指针)数组 suit 保存牌的花色名 字符串(指针)数组 face 保存牌的号码 二维数组 deck 表示一副牌,行对应花色,列对应号码 保存洗牌后牌的序号THE POINTERS 双语课堂目 录第八讲 指针deck[ 2 ][ 12 ] represents the King of ClubsHeartsDiamondsClubsSpades0 1 2 3 Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King 0 1 2 3 4 5 6 7 8 9 10 11 12 Clubs King
  • 429. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 设计算法(自顶向下,逐步求精) 第一次细化THE POINTERS 双语课堂目 录第八讲 指针对52张牌进行洗牌和发牌初始化 suit 数组 初始化 face 数组 初始化 deck 数组 对 52 张牌洗牌 对 52 张牌发牌
  • 430. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 设计算法(自顶向下,逐步求精) 第二次细化THE POINTERS 双语课堂目 录第八讲 指针初始化 suit 数组 初始化 face 数组 初始化 deck 数组 对 52 张牌中的每张 在随机选择的纸牌空位上放置纸牌序号 对 52 张牌中的每张 查找 deck 数组中纸牌的序号,并显示纸牌的花色和号码
  • 431. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 设计算法(自顶向下,逐步求精) 第三次细化THE POINTERS 双语课堂目 录第八讲 指针初始化 suit 数组 初始化 face 数组 初始化 deck 数组 对 52 张牌中的每张 随机选择纸牌位置 当所选纸牌位置已经被选过(有序号) 随机选择纸牌位置 在所选纸牌位置中放置纸牌序号 对 52 张牌中的每张 对于 deck 数组的每个位置 如果该位置包含期望的纸牌序号 显示纸牌的花色和号码
  • 432. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 实现(cw08-05.c)THE POINTERS 双语课堂目 录第八讲 指针#include #include #include void shuffle(int[][13]); void deal(int[][13], char*[], char*[]); void main() { char *suit[]={"Hearts", "Diamonds", "Clubs", "Spades"}; char *face[]={"Ace","Two","Three", "Four","Five","Six", "Seven","Eight","Nine", "Ten","Jack","Queen","King"}; int deck[4][13]={0};
  • 433. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 实现(cw08-05.c)THE POINTERS 双语课堂目 录第八讲 指针 srand(time(0)); shuffle(deck); deal(deck, face, suit); }
  • 434. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 实现(cw08-05.c)THE POINTERS 双语课堂目 录第八讲 指针void shuffle(int wDeck[][13]) { int row, column, card; for (card=1; card<=52; card++) { do { row = rand()%4; column = rand()%13; } while(wDeck[row][column]!=0); wDeck[row][column]=card; } }
  • 435. 指针数组 Arrays Of Pointers举例:洗牌和发牌的模拟 实现(cw08-05.c)THE POINTERS 双语课堂目 录第八讲 指针void deal(int wDeck[][13], char *wFace[], char *wSuit[]) { int card, row, column; for (card=1; card<=52; card++) for (row=0; row<4; row++) for (column=0; column<13; column++) if (wDeck[row][column]==card) printf("%5s of %-8s%c", wFace[column], wSuit[row], card%2==0?'\n':'\t'); }
  • 436. 第九讲 结构 StructuresPROGRAM DESIGN IN C LANGUAGE双语课堂目 录9.2 结构定义Structure definitions9.3 初始化结构Initializing structures9.5 在函数中使用结构Using structures with functions9.6 结构数组Arrays of structures9.1 简介Introduction9.7 链表Linked list9.4 访问结构成员Accessing structure members
  • 437. 简介 IntroductionStructures(结构) Collections of related variables Can contain variables of different data types Commonly used to define records to be stored in files Combined with pointers, can create linked lists, stacks, queues, and treesSTRUCTURES 双语课堂目 录第九讲 结构
  • 438. 结构定义 Structure Definitions结构体,即可将一群类型不同的数据组合在一起。 使用其他类型的对象来构造它们 结构的声明举例 STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct 结构体名称 { 数据类型 字段名称1; 数据类型 字段名称2; …… 数据类型 字段名称n; }; struct 结构体名称 变量1,变量2,……Struct mydata{ char name[15]; char id[10]; int math; int eng; } struct mydata student;
  • 439. 结构定义 Structure Definitions结构是派生的数据类型 使用其他类型的对象来构造它们 结构定义举例 struct:引入了结构定义 card:结构的名称,必须与 struct 一起使用 struct card 结构包含两个 char * 类型的成员(member): face suitSTRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct card { char *face; char *suit; };为程序创建了一个新的数据类型 struct card
  • 440. 结构定义 Structure Definitions结构定义说明 相同结构的成员名不可以相同 不同结构的成员名可以相同,不互相冲突STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct date { int year,month,day; }; struct Book { char title[50],writer[20],publisher[50]; int year,month; }; int year,month,day;
  • 441. 结构定义 Structure Definitions结构定义说明 结构的成员可以使基本类型和构造类型(数组和其他结构)STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct date { int year,month,day; }; struct StuRec { int num; char name[20]; struct date birthday; };
  • 442. 结构定义 Structure Definitions结构定义说明 结构不能包含自身的实例 但可以包含指向自身的指针STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct student { char name[20]; char gender; float scores[4]; struct student next; /*error*/ struct student *nextPtr; /*correct*/ };
  • 443. 结构变量 Structure Variables结构定义说明 结构定义只是创建了新的数据类型,并不能保留内存空间 必须声明结构变量 声明结构变量 定义结构后,像声明普通变量一样声明结构变量STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct date { int year,month,day; }; struct date birth;year month dayFF00 FF02 FF04birthbirth 的存储形式
  • 444. 结构变量 Structure Variables声明结构变量 在定义结构的同时,声明结构变量 直接(只)声明结构变量STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构struct date { int year,month,day; } birth, days[4], *bPtr;struct { int year,month,day; } birth, days[4], *bPtr;没有结构名,无法再次使用
  • 445. 结构操作 Structures Operations在结构(变量)上可以执行的操作 将结构变量赋给相同类型的结构变量 得到结构变量的地址 访问结构变量的成员 使用 sizeof 确定结构变量的大小STRUCTURE DEFINITIONS双语课堂目 录第九讲 结构
  • 446. 初始化结构 Initializing Structures初始化结构(变量) 给全部成员赋初值INITIALIZING STRUCTURES双语课堂目 录第九讲 结构struct StuRec { int num; char name[20]; struct date { int year,month,day; } birthday; float score; } student={101, “WangHai”, 1982, 5, 21, 80};num (2B)name (20B)birthday(6B)score (4B)yearmonthday101WangHai198252180.0
  • 447. 初始化结构 Initializing Structures初始化结构(变量) 给部分成员赋初值INITIALIZING STRUCTURES双语课堂目 录第九讲 结构struct StuRec { int num; char name[20]; struct date { int year,month,day; } birthday; float score; } student={101, “WangHai”};num (2B)name (20B)birthday(6B)score (4B)yearmonthday101WangHai0000.0
  • 448. 访问结构成员 Accessing Structure Members访问结构成员的两种方式 结构成员运算符:. 用于结构变量 结构指针运算符:-> 用于指向结构的指针 等价于 (*cardPtr).faceACCESSING MEMBERS OF STRUCTURES双语课堂目 录第九讲 结构struct card myCard; printf(“%s”, myCard.face);struct card *cardPtr; printf(“%s”, cardPtr->face);
  • 449. 访问结构成员 Accessing Structure MembersExample: Accessing structure members (cw09-01.c)ACCESSING MEMBERS OF STRUCTURES双语课堂目 录第九讲 结构#include struct card { char *face; char *suit; }; void main() { struct card a, *aPtr; a.face = "Ace"; a.suit = "Spades"; aPtr = &a;与数组的不同: 结构变量名不是指针
  • 450. 访问结构成员 Accessing Structure MembersExample: Accessing structure members (cw09-01.c)ACCESSING MEMBERS OF STRUCTURES双语课堂目 录第九讲 结构 printf("%s%s%s\n%s%s%s\n%s%s%s\n", a.face, " of ", a.suit, aPtr->face, " of ", aPtr->suit, (*aPtr).face, " of ", (*aPtr).suit); }Ace of Spades Ace of Spades Ace of Spades注意: 结构不能作为整体输入输出 必须逐个成员进行输入输出
  • 451. 在函数中使用结构 Using Structures With Functions把结构的单个成员传递给函数 按值调用传递 被调用函数不能修改调用函数中的结构成员 把整个结构传递给函数 按值调用传递 被调用函数不能修改调用函数中的结构 把结构指针传递给函数 按引用调用传递 被调用函数能修改调用函数中的结构USING STRUCTURES WITH FUNCTIONS双语课堂目 录第九讲 结构
  • 452. 在函数中使用结构 Using Structures With FunctionsExample: Passing structures to functions 编写函数实现结构的复制(cw09-02.c)USING STRUCTURES WITH FUNCTIONS双语课堂目 录第九讲 结构#include struct date { int year, month, day; }; void show(char *, struct date); void copy(struct date, struct date); void clone(struct date, struct date *); void main() { struct date d1, d2, d3, d4; d1.year = 2004; d1.month = 5; d1.day = 1; show("d1", d1);
  • 453. 在函数中使用结构 Using Structures With FunctionsExample: Passing structures to functions 编写函数实现结构的复制(cw09-02.c)USING STRUCTURES WITH FUNCTIONS双语课堂目 录第九讲 结构 d2 = d1; show("d2", d2); copy(d1, d3); show("d3", d3); clone(d1, &d4); show("d4", d4); } void show(char *name, struct date d) { printf("%s: %d-%d-%d\n", name, d.year, d.month, d.day); }
  • 454. 在函数中使用结构 Using Structures With FunctionsExample: Passing structures to functions 编写函数实现结构的复制(cw09-02.c)USING STRUCTURES WITH FUNCTIONS双语课堂目 录第九讲 结构void copy(struct date s, struct date d) { d = s; } void clone(struct date s, struct date *dPtr) { *dPtr = s; }d1: 2004-5-1 d2: 2004-5-1 d3: 0-0-24 d4: 2004-5-1
  • 455. 在函数中使用结构 Using Structures With Functions把整个结构返回 因为结构变量之间可以赋值 按值调用把数组传递给函数 把数组作为结构的成员,然后把结构传递给函数 被调用函数不能修改调用函数中的数组USING STRUCTURES WITH FUNCTIONS双语课堂目 录第九讲 结构
  • 456. 定义类型的别名 typedeftypedef 为已经定义的数据类型创建一个别名(或同义词) 举例 创建了一个新的类型名 Date ,它是 struct date 的别名 注意:并没有创建新的类型 可以简化程序代码,提高程序的可移植性TYPEDEF双语课堂目 录第九讲 结构typedef struct date Date;void show(char *, Date d); void copy(Date s, Date d);typedef int Integer;
  • 457. 定义类型的别名 typedeftypedef 举例 TYPEDEF双语课堂目 录第九讲 结构int main(void) { typedef float temper; temper f,c; scanf(“%f”,&c); f=(float)(9.0/5.0)*c+32 ; printf(“%.2f celsius is equal to %f Fahrenheit degree\n”,c,f); return 0; }
  • 458. 结构数组 Arrays Of Structures结构数组 数组的元素是结构 常用结构来表示记录,那么结构数组就可以表示一组记录 举例 全班 N 个学生,每个学生有学号、姓名、四门课的成绩ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构学号姓名成绩1成绩2成绩3成绩4101WangHai80787681102ZhaoFei68667175………………………………130LiRui82768184
  • 459. 结构数组 Arrays Of Structures结构数组 举例 全班 N 个学生,每个学生有学号、姓名、四门课的成绩 那么,可以定义结构数组来保存 N 个学生的数据 这样,每个学生的数据就对应一个结构(一条记录),便于编程处理ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构struct student { int num; char name[20]; float scores[4]; }; struct student students[30];
  • 460. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 修改原来的数据结构 用一个纸牌结构数组保存一副牌 纸牌的花色和号码名依然保存在字符串数组中 这样,数组中的纸牌俨然已有一个顺序了,则可以改进算法 洗牌:随机打乱纸牌在数组中的位置 不存在无限延期 发牌:按纸牌在数组中的顺序显示输出 数组遍历一次ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构
  • 461. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 实现(cw09-03.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构#include #include #include struct card { char *face; char *suit; }; typedef struct card Card; void fillDeck(Card*, char*[], char*[]); void shuffle(Card*); void deal(Card*);
  • 462. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 实现(cw09-03.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构void main() { Card deck[52]; char *face[] = {"Ace","Deuce","Three", "Four","Five", "Six","Seven","Eight", "Nine","Ten", "Jack","Queen","King"}; char *suit[] = {"Hearts","Diamonds","Clubs","Spades"}; srand(time(NULL)); fillDeck(deck, face, suit); shuffle(deck); deal(deck); }
  • 463. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 实现(cw09-03.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构void fillDeck(Card *wDeck, char *wFace[], char *wSuit[]) { int i; for (i=0; i<=51; i++) { wDeck[i].face = wFace[i%13]; wDeck[i].suit = wSuit[i/13]; } }
  • 464. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 实现(cw09-03.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构void shuffle(Card *wDeck) { int i, j; Card temp; for (i=0; i<=51; i++) { j = rand()%52; temp = wDeck[i]; wDeck[i] = wDeck[j]; wDeck[j] = temp; } }
  • 465. 结构数组 Arrays Of Structures举例:高性能洗牌和发牌仿真程序 实现(cw09-03.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构void deal(Card *wDeck) { int i; for (i=0; i<=51; i++) { printf("%5s of %-8s%c", wDeck[i].face, wDeck[i].suit, (i+1)%2 ? '\t' : '\n'); } }
  • 466. 结构数组 Arrays Of Structures举例:检索 某班有 n 个学生,每个学生的数据包括学号、姓名、年龄和性别。要求给定任意一个学号,程序能输出检索的结果,并显示对应的学生的数据。(cw09-04.c) 分析 用结构体数组保存学生数据 采用顺序查找法ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构输入学生信息输入查询条件查找学生信息,报告结果
  • 467. 结构数组 Arrays Of Structures举例:检索 实现(cw09-04.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构#include #define MAX 20 void main() { struct StuRec { int num; char name[20]; char gender; int age; } student[MAX]; int i, N, num;
  • 468. 结构数组 Arrays Of Structures举例:检索 实现(cw09-04.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构 printf("\tInput a integer as the number of students:"); scanf("%d", &N); printf("\tInput %d students' information:\n",N); printf("\n\tNo.\tName\tGender\tAge\n"); for (i=0;i
  • 469. 结构数组 Arrays Of Structures举例:检索 实现(cw09-04.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构 printf("\n\tInput a number:"); scanf("%d", &num); printf("\n\tPlease wait. Searching...\n"); for (i=0;i
  • 470. 结构数组 Arrays Of Structures举例:检索 增加要求:可以多次查找(cw09-04m.c) ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构输入学生信息输入查询条件查找学生信息,报告结果是否继续查询YN
  • 471. 结构数组 Arrays Of Structures举例:检索 修订后的部分代码(cw09-04m.c) ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构 do { scanf("%d", &num); for (i=0;i
  • 472. 结构数组 Arrays Of Structures举例:点票程序 有三个候选人,N个选举人,每次输入一个得票的候选人的名字,要求最后输出各人的得票结果。 定义数据结构ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构struct candidate { char name[20]; /*姓名*/ int count; /*得票数*/ } cand[3];
  • 473. 结构数组 Arrays Of Structures举例:点票程序 算法ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构输入候选人信息输入选票查找得票人信息找到否?得票人的票数增一输出点票结果点完否?YNNY
  • 474. 结构数组 Arrays Of Structures举例:点票程序 实现(cw09-05.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构…… do { printf("Vote:\t"); gets(name); for (i=0;i
  • 475. 结构数组 Arrays Of Structures举例:改进点票程序 假设选举人都可以是候选人 分析点票过程中数组的变化ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构litaolitao wanghai litao zhaofei ……litaowanghailitaowanghaizhaofei
  • 476. 结构数组 Arrays Of Structures举例:改进的点票程序 数据结构和算法ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构struct candidate { char name[20]; int count; } cand[M];输入选票查找得票人信息找到否?得票人的票数增一输出点票结果点完否?YNNY加入新的候选人; 其得票数赋值“1”。
  • 477. 结构数组 Arrays Of Structures举例:改进的点票程序 实现(cw09-06.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构。。。 printf("Vote:\t"); gets(name); found=0; for (i=0;i
  • 478. 结构数组 Arrays Of Structures举例:增强点票程序 要求按候选人得票数 从高到低顺序输出结果。 修改算法ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构输入选票查找得票人信息找到否?得票人的票数增一输出点票结果点完否?YNNY加入新的候选人; 其得票数赋值“1”。按得票数进行排序
  • 479. 结构数组 Arrays Of Structures举例:增强点票程序 实现(cw09-07.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构… for (i=0;i
  • 480. 结构数组 Arrays Of Structures举例:优化点票程序 如果候选人的信息较多,为了提高排序过程中数据交换的性能,增设一数组order,用来保存排序结果。 分析ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构01234530514220Wanghai M 43 P …12Zhaofei F 41 P …6Lilan F 38 N …35Huangjin M 52 P …9Wuma M 29 N …15Hecheng M 36 P …order的初态order的末态从高到低0 1 2 3 4 5
  • 481. 结构数组 Arrays Of Structures举例:优化点票程序 实现(cw09-08.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构 for (i=0;i
  • 482. 结构数组 Arrays Of Structures举例:优化点票程序 实现(cw09-08.c)ARRAYS OF STRUCTURES双语课堂目 录第九讲 结构 for (i=0;i
  • 483. 数据结构 Data StructuresDynamic data structures(动态数据结构) Data structures that grow and shrink during execution Linked lists(链表) Allow insertions and removals anywhere Stacks(栈) Allow insertions and removals only at top of the stack Queues(对列) Allow insertions at the back and removals from the frontLINKED LISTS双语课堂目 录第九讲 结构
  • 484. 自引用的结构 Self-Referenial Structures自引用的结构 包含指向相同结构类型的指针成员 可以链接到一起,构成有用的数据结构:链表、栈、队列和树LINKED LISTS双语课堂目 录第九讲 结构struct node { int data; struct node *nextPtr; };2042数据成员指针结点(node)空指针链头指针
  • 485. 动态内存分配 Dynamic Memory Allocation动态内存分配 在程序执行期间获取或释放内存 相关的函数 malloc free sizeofLINKED LISTS双语课堂目 录第九讲 结构
  • 486. 动态内存分配 Dynamic Memory Allocationmalloc 把要分配的字节数作为参数 用 sizeof 确定对象的大小 返回指向分配内存的 void* 类型的指针 void* 类型的指针可以被赋值给任何类型的指针变量 如果没有可用内存,则返回 NULL free 释放用 malloc 分配的内存 用指向要被释放的内存区的指针作为参数LINKED LISTS双语课堂目 录第九讲 结构newPtr = malloc(sizeof(struct node));free(newPtr);
  • 487. 链表 Linked Lists链表 用指针链接连接的自引用结构的线性集合,这些结构称为结点 通过指向链表的第一个结点的指针访问链表 后续的结点通过存储在每个结点中的链接指针成员来访问 链表中最后一个结点的链接指针被设置为NULL,以标志链表的结尾 什么时候用链表替代数组 数据成员的数目无法事先确定 对数据进行快速的排序LINKED LISTS双语课堂目 录第九讲 结构2042
  • 488. 链表 Linked ListsExample: Linked list 输入任意个整数创建链表 实现常用的操作:遍历,插入,删除,空表判断 (cw09-11.c)LINKED LISTS双语课堂目 录第九讲 结构#include #include struct listNode { int data; struct listNode *nextPtr; }; typedef struct listNode ListNode; typedef ListNode* ListNodePtr;
  • 489. 链表 Linked ListsExample: Linked list 主函数LINKED LISTS双语课堂目 录第九讲 结构void insert(ListNodePtr*, int); int delete(ListNodePtr*, int); int isEmpty(ListNodePtr); void printList(ListNodePtr); void menu(void); void main() { ListNodePtr listPtr = NULL; int choice; int item; menu(); printf("? "); scanf("%d", &choice);
  • 490. 链表 Linked ListsExample: Linked list 主函数LINKED LISTS双语课堂目 录第九讲 结构 while (choice != 3) { switch (choice) { case 1: printf("Enter an integer: "); scanf("%d", &item); insert(&listPtr, item); printList(listPtr); break;
  • 491. 链表 Linked ListsExample: Linked list 主函数LINKED LISTS双语课堂目 录第九讲 结构 case 2: if (!isEmpty(listPtr)) { printf("Enter an integer to be deleted: "); scanf("%d", &item); if (delete(&listPtr, item)) { printf("%d deleted.\n", item); printList(listPtr); } else printf("%d not found.\n", item); } else printf("List is Empty!\n"); break;
  • 492. 链表 Linked ListsExample: Linked list 主函数LINKED LISTS双语课堂目 录第九讲 结构 default: printf("Invalid choice.\n\n"); menu(); break; } printf("? "); scanf("%d", &choice); } printf("Bye-bye!\n"); }
  • 493. 链表 Linked ListsExample: Linked list 显示菜单函数LINKED LISTS双语课堂目 录第九讲 结构void menu(void) { printf("Enter your choice:\n" "1 to insert an element into the list.\n" "2 to delete an element from the list.\n" "3 to ent.\n"); }
  • 494. 链表 Linked ListsExample: Linked list 插入结点函数LINKED LISTS双语课堂目 录第九讲 结构2042listPtr35newPtrprePtrcurPtr
  • 495. 链表 Linked ListsExample: Linked list 插入结点函数LINKED LISTS双语课堂目 录第九讲 结构void insert(ListNodePtr *sPtr, int data) { ListNodePtr newPtr, prePtr, curPtr; newPtr = malloc(sizeof(ListNode)); if (newPtr != NULL) { newPtr->data = data; newPtr->nextPtr = NULL; prePtr = NULL; curPtr = *sPtr; while (curPtr != NULL && data > curPtr->data) { prePtr = curPtr; curPtr = curPtr->nextPtr; }
  • 496. 链表 Linked ListsExample: Linked list 插入结点函数LINKED LISTS双语课堂目 录第九讲 结构 if (prePtr == NULL) { newPtr->nextPtr = curPtr; *sPtr = newPtr; } else { prePtr->nextPtr = newPtr; newPtr->nextPtr = curPtr; } } else printf("%d not inserted. No memory available.\n", data); }如果新结点是第一个节点,则必须调整链表的头指针
  • 497. 链表 Linked ListsExample: Linked list 删除结点函数LINKED LISTS双语课堂目 录第九讲 结构tempPtrprePtrcurPtr2042listPtr35
  • 498. 链表 Linked ListsExample: Linked list 删除结点函数LINKED LISTS双语课堂目 录第九讲 结构int delete(ListNodePtr *sPtr, int data) { ListNodePtr prePtr, curPtr, tempPtr; if (data == (*sPtr)->data) { tempPtr = *sPtr; *sPtr = (*sPtr)->nextPtr; free(tempPtr); return 1; } else { prePtr = *sPtr; curPtr = (*sPtr)->nextPtr;如果删除的是第一个节点,必须调整链表的头指针
  • 499. 链表 Linked ListsExample: Linked list 删除结点函数LINKED LISTS双语课堂目 录第九讲 结构 while (curPtr != NULL && curPtr->data != data) { prePtr = curPtr; curPtr = curPtr->nextPtr; } if (curPtr != NULL) { tempPtr = curPtr; prePtr->nextPtr = curPtr->nextPtr; free(tempPtr); return 1; } } return 0; }
  • 500. 链表 Linked ListsExample: Linked list 判空和输出(遍历)函数LINKED LISTS双语课堂目 录第九讲 结构int isEmpty(ListNodePtr listPtr) { return listPtr == NULL; } void printList(ListNodePtr curPtr) { if (curPtr == NULL) printf("List is Empty.\n\n"); else { printf("The list is:\n"); while (curPtr != NULL) { printf("%d --> ", curPtr->data); curPtr = curPtr->nextPtr; } printf("NULL\n\n"); } }
  • 501. 共用体 Union共用体LINKED LISTS双语课堂目 录第九讲 结构定义联合定义一般形式 union 联合类型名 { 数据类型 成员名1; 数据类型 成员名2; …… 数据类型 成员名n; }; 其中union为关键字。
  • 502. 共用体 Union举例:LINKED LISTS双语课堂目 录第九讲 结构 union u_type /* 定义联合类型u_type */ { char ch; int i; long li; }cnvt, * pcnvt; /* 说明联合类型的变量 */ 联合类型占用内存情况 联合类型的变量占用内存空间的大小等于成员分量中最长的成员分量所占用内存的长度。 对于联合变量cnvt,其内存占用情况如图所示:(4个字节)
  • 503. 共用体 Union联合类型占用内存情况:LINKED LISTS双语课堂目 录第九讲 结构 联合类型的变量占用内存空间的大小等于成员分量中最长的成员分量所占用内存的长度。 对于联合变量cnvt,其内存占用情况如图所示:(4个字节)cnvtchili
  • 504. 共用体 Union联合与结构的异同:LINKED LISTS双语课堂目 录第九讲 结构 联合与结构都是由多个成员分量组成的一个整体; 联合与结构在定义、说明和使用(成员引用、指针)上十分相似。 结构:多个成员分量分别占用不同的存储空间构成一个整体;成员分量之间是相互独立的,所进行的各种操作互不影响。 联合:多个成员分量共同占用同一存储空间;成员分量之间是相互联系的,所进行的操作相互依赖。
  • 505. 枚举类型 Enumeration枚举类型是一种特殊的常量定义方式LINKED LISTS双语课堂目 录第九讲 结构枚举类型定义一般形式 enum 枚举类型名 { 枚举常量1, 枚举常量2, …… }; 其中enum为关键字。enum desktop { pen,pencil,eraser,book,tape } mine;
  • 506. 第十讲 文件处理 File ProcessingPROGRAM DESIGN IN C LANGUAGE双语课堂目 录10.2 文件和流Files and streams10.3 顺序存取文件Sequential access files10.4 随机存取文件Random access files10.5 举例Examples10.1 简介Introduction
  • 507. 简介 IntroductionData files(数据文件) Can be created, updated, and processed by C programs Are used for permanent storage of large amounts of data Storage of data in variables and arrays is only temporaryFILE PROCESSING 双语课堂目 录第十讲 文件处理
  • 508. 简介 Introduction文件的定义FILE PROCESSING 双语课堂目 录第十讲 文件处理文件:存储在外部介质上(如磁盘等外存储器)的数据或信息的集合。 例如:程序文件中保存着程序,而数据文件中保存着数据。 C7.C: C语言的源程序 文本文件 C7.OBJ: 目标文件 二进制文件 C7.EXE: 可执行文件 二进制文件 文件是一个有序的数据序列。文件的所有数据之间有着严格的排列次序的关系(类似数组类型的数据),要访问文件中的数据,必须按照它们的排列顺序,依次进行访问。
  • 509. 简介 Introduction文件的分类FILE PROCESSING 双语课堂目 录第十讲 文件处理从文件数据的组织形式看:数据的组织形式是指数据在磁盘上是以什么格式进行存储的。 从这个角度看,文件分为两类: ASCII文件(或称文本文件,即TEXT文件) 二进制文件   文本文件中保存的数据,采用ASCII码作为存储方式,先将全部数据转换为ASCII码形式。每个ASCII字符占用一个字节。 ASCII文件在DOS操作系统下可以直接阅读。 二进制文件中保存的数据,是将数据在内存中二进制存储格式不做任何转换,直接存入文件中。 二进制文件在操作系统下不能直接阅读。
  • 510. 文件的操作方式 处理文件的函数可分两类:一为有缓冲区的文件处理函数也称标准I/O或stream(数据流) I/O函数。 另一种是没有缓冲区的文件处理函数。 系统对文件的处理过程就是对文件进行输入/输出操作的过程。 处理文件:读取数据、将数据写入文件、更新文件内容、增加文件内容等FILE PROCESSING 双语课堂目 录第十讲 文件处理
  • 511. 文件的操作方式 文件输入/输出的一般过程:FILE PROCESSING 双语课堂目 录第十讲 文件处理文件程序 数据区输出文件缓冲区输入文件缓冲区计算机内存计算机外存写文件称为输出读文件称为输入
  • 512. 文件的操作步骤 打开文件————操作文件————关闭文件 打开文件:建立用户程序与文件的联系,为文件开辟文件缓冲区。 操作文件:是指对文件的读、写、追加和定位操作。 读操作:是从文件中读出数据,即将文件中的数据读入计算机; 写操作:是向文件中写入数据,即向文件输出数据。 追加操作:将数据写到原有数据的后面。 定位操作:文件读写位置指针。 关闭文件:切断文件与程序的联系,将文件缓冲区的内容写入磁盘,并释放文件缓冲区。FILE PROCESSING 双语课堂目 录第十讲 文件处理C语言通过标准I/O库(stdio.h)函数实现文件操作
  • 513. 文件指针 FILE文件指针FILE PROCESSING 双语课堂目 录第十讲 文件处理 在缓冲文件系统中,对每个正在使用的文件都要说明并使用一个FILE类型的结构变量,该结构变量用于存放文件的有关信息,如文件名、文件状态等。 在C语言中,无论是一般磁盘文件还是设备文件,都要通过文件结构的数据集合进行输入输出处理。 文件结构不需要用户自己定义,是由系统事先已经定义好的,固定包含在头文件 stdio.h 中。  FILE *变量1,*变量2,……. 例:FILE *fptr;
  • 514. 文件处理 文件打开FILE PROCESSING 双语课堂目 录第十讲 文件处理打开文件应使用fopen函数。其调用的一般形式为: FILE *文件指针名; 文件指针名=fopen("文件名","使用文件方式"); FILE *fptr; fptr=fopen(”abc.txt”,”r”); 文件名:需要打开的文件名称(字符串)。 文件使用方式:是具有特定含义的符号。如书266页表 12-1 函数功能: 按指定的文件使用方式打开指定的文件。 若文件打开成功,则返回值为非NULL指针; 若文件打开失败,返回NULL。
  • 515. 文件打开方式小结      文件使用方式     含   义   ━━━━━━━━━━━━━━━━━━━━━━━━━━ “r”  (只读) 为读取打开一个文本文件 “w”  (只写) 为写入打开一个文本文件 "a"   (追加) 向文本文件尾增加数据 "rb"  (只读) 为读取打开一个二进制文件 "wb"  (只写) 为写入打开一个二进制文件 "ab"  (追加) 向二进制文件尾增加数据 "r+"  (读写) 为读/写打开一个文本文件 "w+"  (读写) 为读/写建立一个新的文本文件 "a+"  (读写) 为读/写打开一个文本文件 "rb+"  (读写) 为读/写打开一个二进制文件 "wb+"  (读写) 为读/写建立一个新的二进制文件 “ab+”  (读写) 为读/写打开一个二进制文件FILE PROCESSING 双语课堂目 录第十讲 文件处理
  • 516. 文件处理 关闭文件(fclose)FILE PROCESSING 双语课堂目 录第十讲 文件处理 fclose函数的调用形式是: FILE * fptr; fptr=fopen(”abc.txt”,”r”); fclose (fptr); fptr :已经打开的文件指针。 函数功能:关闭fp指定的文件,切断缓冲区与该文件的联系,并释放文件指针。 若文件关闭成功,则返回值为0; 若文件关闭失败,返回非0值。
  • 517. 第十一讲 预处理器 The PreprocessorPROGRAM DESIGN IN C LANGUAGE双语课堂目 录11.2 文件包含The #include preprocessor directive11.3 符号常量The #define preprocessor directive: symbolic constants11.4 宏The #define preprocessor directive: macro11.5 条件编译Conditional compilation11.1 简介Introduction
  • 518. 简介 Introduction预处理(preprocessing) Occurs before a program is compiled Inclusion of other files Definition of symbolic constants and macros Conditional compilation of program code Conditional execution of preprocessor directives 预处理命令(preprocessor directive)的格式 Lines begin with # Only whitespace characters before directives on a line The Preprocessor 双语课堂目 录第十一讲 预处理器
  • 519. 文件包含 The #include Preprocessor Directive#include Copy of a specified file included in place of the directive #include Searches standard library for file Use for standard library files #include "filename" Searches current directory, then standard library Use for user-defined files Used for: Programs with multiple source files to be compiled together Header file – has common declarations and definitions (classes, structures, function prototypes) #include statement in each fileThe Preprocessor 双语课堂目 录第十一讲 预处理器
  • 520. 符号常量 The #define Preprocessor Directive: symbolic constants#define Preprocessor directive used to create symbolic constants and macros Symbolic constants When program compiled, all occurrences of symbolic constant replaced with replacement text Format #define identifier replacement-text Example Everything to right of identifier replaces text Cannot redefine symbolic constants once they have been createdThe Preprocessor 双语课堂目 录第十一讲 预处理器#define PI 3.14159#define PI = 3.14159
  • 521. 多维数组的应用举例 Examples: Multiple-Subscripted ArraysExample:转置矩阵(ca07-15.c)MULTIPLE-SUBSCRIPTED ARRAYS双语课堂目 录第七讲 数组与字符串int main(void){ int i,j,matrx[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; for (i=0; i<3; i++) { for(j=0;j<4;j++) printf(“%4d”,matrix[i][j]); printf(“\n”); } printf(“after reversed:\n”); for(j=0;j<4;j++) { for(i=0;i<3;i++) printf(“4%d”,matrix[i][j]) printf(“\n”); } return 0; }