C++(第十一周1-程序结构)_第1页
C++(第十一周1-程序结构)_第2页
C++(第十一周1-程序结构)_第3页
C++(第十一周1-程序结构)_第4页
C++(第十一周1-程序结构)_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+程序设计海滨学院 王灵晓第6章 程序结构0、用VC建立多文件的工程1、外部存储类型2、静态存储类型3、作用域4、可见性5、生命期6、头文件7、多文件结构8、编译预处理0、用VC建立多文件的工程 用VC建立多文件的工程的截图1、新建2、新建工程的名字和存储位置3、工程的FilesView4、往工程中添加源文件5、往工程中添加源文件6、往工程中添加源文件7、往工程中添加源文件8、双击源文件,往文件中写入C+程序1、外部存储类型 一个C+程序可以由一个或多个源文件组成 一个文件如何使用另一个文件中的变量?其中只有一个源文件有main函数,而其他的文件不能有main。#include int ma

2、in() coutaendl;1.cpp文件int a = 199;2.cpp文件1、变量a在文件2.cpp中定义,文件1.cpp中使用变量a。2、直接使用另一个文件的变量,会产生以下错误:解决方法:构成一个程序的多个源文件之间,通过声明数据或函数为外部的(extern)来进行沟通。#include extern int a;int main()coutaendl;1.cpp文件int a = 199;2.cpp文件 所有函数声明一般都放在源文件的开始位置 默认的函数声明或定义总是extern的void f();int main()f();1.cpp文件#include void f()cou

3、tf;2.cpp文件等价于:extern void f(); 关键字extern告诉连接程序,在所有组成该程序的文件中搜索变量或函数的定义。extern void f();int main()f();1.cpp文件#include void f()coutf;3.cpp文件/2.cpp文件编译器遇到extern,连接程序在2.cpp和3.cpp中找函数f的定义,在3.cpp中找到了;如果1.cpp中没有extern void f(),则编译器不会到所有文件中找f函数的定义。int a = 199;1.cpp文件#include extern int a;void f()coutf:a;cout

4、endl;3.cpp文件#include extern int a;extern void f();int main() coutmain:a; coutendl; f();2.cpp文件定义变量a编译器遇到extern int a;它会在这三个文件中找变量a的定义,在1.cpp文件中找到了。 带extern的变量说明是变量声明,不是变量定义。以下都会造成直接或间接地错误:1、如果共同的变量一次都没有定义;2、或者在各个文件中分别定义;3、或者声明的类型不一致int a=1;int b=1;extern int c;1.cpp文件int a;extern double b;extern int

5、 c;2.cpp文件在各个文件中分别定义声明的类型不一致变量一次都没有定义2、静态存储类型 静态全局变量在全局变量前加一个static,使该变量只在这个源文件中可用,这个变量为这个源文件所独享,这称之为静态全局变量。#include extern int n;int main()coutn;1.cpp文件static int n=199;2.cpp文件1、程序可以通过编译2、程序无法通过连接,产生错误3、静态全局变量对组成该程序的其他源文件是无效的 静态函数void f();int main()f();1.cpp文件#include void f()coutf;2.cpp文件函数的声明和定义默

6、认情况下,在整个程序中,是extern的1、1.cpp能调用2.cpp中的函数f,因为函数的声明和定义默认情况下是extern的2、怎样修改,才能使得“1.cpp不能调用2.cpp中的函数f ”?在函数前面加上static。这样使该函数只在一个源文件中有效,在其他源文件中无效。void f();int main()f();1.cpp文件#include static void f()coutf;2.cpp文件1、程序可以通过编译2、程序无法通过连接,产生错误3、作用域 作用域 局部作用域作用域是标识符在程序中有效地范围。第一种局部作用域:当标识符的声明出现在由一对花括号所括起来的一段时,它的作

7、用域从声明点开始,到块结束处为止。void f(int y)couty);/.第二种局部作用域:如果在if语句和switch语句中,进行条件测试的表达式中声明标识符,则标识符的作用域在该语句中。void f()/.if(int i=5)i=2;elsei=0;/.couti; /errorvoid f()/.switch(int i=1)case 1:cout1;break;case 2:/./.cout5)int i=1;elsedouble i=1.0;/.couti; /errorint i的作用域从此开始,到此结束double i的作用域从此开始,到此结束第三种局部作用域:在for语句

8、的第一个表达式中声明的标识符,其作用域在该语句中。void f()/.for(int i=0; i100; +i)couti;/.couti; /error 函数作用域标号是唯一具有函数作用域的标识符,goto语句使用标号。标号声明使得该标识符在一个函数内的任何位置均可以被使用。局部变量不具有函数作用域。void f()goto LL;coutABC;LL:coutout here;void f()int i=0;LL:coutout here;if(i+=0)goto LL;goto和switch不应使控制从一个声明的作用域之外跳到该声明的作用域内,因为这种跳转越过了变量的声明语句,使变量不

9、能被初始化。 函数原型作用域 文件作用域函数原型声明(不是函数定义)中所作的参数声明在该作用域中。这个作用域开始于函数原型声明的左括号,结束于函数原型声明的右括号。文件作用域是在所有函数定义之外说明的,其作用域从说明点开始,一直延伸到源文件结束。文件作用域即为静态全局的。int a=1;int main()int b=1;void f()4、可见性 可见性与作用域是一致的。作用域指的是标识符有效的范围,可见性是分析在某一位置标识符的有效性。 标识符的可见性范围不超过作用域,作用域则包含可见范围。 可见性在分析两个同名标识符作用域嵌套的特殊情况时,非常有用。在内层作用域中,外层作用域中声明的同名

10、标识符是不可见的。#include int id=1;int main()coutidendl;int id=2;coutidendl;cout:idendl;coutidendl;1、外层的id有文件作用域,内层的id有块作用域。2、内层的id隐藏了外层的id,在定义了内层id后,就不能简单访问外层id了,而要用:来访问。3、在内层的块作用域结束后,外层id又变得可见了。5、生命期 生命期 静态生命期生命期也叫生存期。生命期与存储区域密切相关。存储区域主要有代码区、数据区、栈区、堆区。对应的生命期为静态生命期、局部生命期、动态生命期。1、这种生命期与程序的运行期相同,只要程序一开始运行,这种

11、生命期的变量就存在,当程序结束时,其生命期就结束。2、全局变量、静态全局变量、静态局部变量都具有静态生命期。具有文件作用域的变量具有静态生命期。3、静态生命期的变量,若无显式初始化,则自动初始化为0. 局部生命期1、在函数内部声明的变量或者是块中声明的变量具有局部生命期。2、这种变量的生命期开始于程序执行经过其声明点时,而结束于其作用域结束处。3、具有局部生命期的变量也具有局部作用域。反之不然。4、具有局部生命期的变量在栈区。5、具有局部生命期的变量如果未被初始化,则内容不可知。void f()static int a=1;int b=2;/.1、a、b都有局部作用域2、a具有静态生命期,b具

12、有局部生命期 动态生命期1、具有这种生命期的变量驻留在内存的堆中。2、当用函数malloc或new为变量分配空间时,生命期开始。3、当用free或delete释放该变量的空间或程序结束时,生命期结束。6、头文件extern void f();extern void g();int main()f();g();1.cpp文件#include “my.h”int main()f();g();1.cpp文件extern void f();extern void g();my.h文件同一名字的声明可以多次,具有外部存储类型的声明可以在多个源文件中引用,因此方便的方法是将它们放在头文件中。头文件起着源文

13、件之间接口的作用。7、多文件结构1、一个C+源文件如何生成exe可执行文件?一个C+源文件翻译临时文件目标文件objexe可执行文件预处理编译连接2、多个C+源文件如何生成一个exe可执行文件?一个C+源文件翻译临时文件目标文件objexe可执行文件预处理编译连接一个C+源文件翻译临时文件目标文件obj预处理编译8、编译预处理 预处理程序 #include指令预处理程序也称预处理器,它包含在编译器中。预处理首先读源文件。预处理输出是“翻译单元”,它是存放在内存中的临时文件。#include让预处理程序把一个源文件嵌入到当前源文件中,该点处。#include有两种格式,一种:#include 这

14、种格式用于嵌入C+语言提供的头文件,这些文件一般存在于C+系统目录中的include子目录下。C+预处理器遇到这条指令后,就到include子目录下搜索给出的文件,并把它嵌入到当前文件中。这是标准方式。另一种格式:#include “文件名”编译器首先在当前文件所在目录中进行搜索,如果找不到,再按标准方式进行搜索。这种方式适合于规定用户自己建立的头文件。 #define指令在C中,#define最常用的方法是建立常量,但已经被C+的const定义语句所代替。#define还可以定义带参数的宏,但也已经被C+的inline内嵌函数所代替。#define的一个有效地使用是在条件编译中。 条件编译指

15、令条件编译的指令有:#if, #else,#elif, #ifdef ,#ifndef, #undef 条件编译的一个有效使用是协调多个头文件。#ifndef LL#define LL 78#endif#include int main()coutLLendl;1、#ifndef和#endif配对使用,一个是开始,一个是结束。2022-5-1738第7章 数组1、数组定义2、访问数组元素3、初始化数组4、向函数传递数组5、二维数组6、数组应用:排序2022-5-17391、数组定义 什么是数组 一维数组的说明方法数组是一个由若干同类型变量组成的集合。类型说明符 数组名常量表达式举例:char

16、buffer5;常量表达式表示数组中元素的个数,即数组长度2022-5-1740 数组定义表示的意义举例:char a5;意义:a代表整个数组。表示数组a有5个元素,每个元素都是char字符型。数组的第一个元素用a0表示,第二个用a1表示,第三个是a2,第四个是a3,第五个是a4,一共就这五个元素。2022-5-1741#include int main()char a5=0123;cout数组第一个元素是:;couta0endl;1、”0123”占用5个字节,还有02、输出结果如下:2022-5-1742 数组下标数组下标:是数组元素到数组开始的偏移量。第一个元素第一个元素第第2个元素个元素

17、第第3个元素个元素第第4个元素个元素第第5个元素个元素数组开始第一个元素到数组开始的偏移量是0,第二个元素的偏移量是1,以此类推。每项的大小是相同的。每项到数组开始的偏移量是固定的。2022-5-1743 数组定义中的常量表达式int main()int size=50;int asize;int size=50;int main()int asize;ERROR:这两个size是变量const int size=50;const int n=size*sizeof(int);int main()int asize;int bn;OK:Size和n都是常量。2022-5-17442、访问数组元

18、素 数组中特定的元素通过下标访问,长度为n的数组,其下标范围为0n-1 在数组定义后,给数组赋初值时,必须一个个元素逐个访问。int main()char a10=0123;int main()char a10;a0=0;a1=1;a2=2;a3=3;a4=0;2022-5-17453、初始化数组 数组的初始化数组可以初始化,即在定义时,使它包含程序马上能使用的值。例如:int a10 = 1,2,3,4,5,6,7,8,9,0; /请问a2是几?1、初始化数组的值的个数不能多于数组元素个数2、初始化数组的值也不能通过跳过逗号的方式来省略。 例如:int a10 = 1,2,3,5,6,7,8

19、,9,0; /error int a10 = 1,2,3,4,5,; /error int a10 = ; /error3、初始化值的个数可少于数组元素个数。当初始化值的个数少于数组元素个数时,前面的按序初始化相应值,后面的初始化为0.2022-5-1746 初始化字符数组初始化字符数组有两种方法,一种是:char a10 = “Hello”; 等同于char a10 = “Hello”;初始化时,系统自动在数组没有填值的位置用0补上。所以”Hello”会占用6个数组元素,请问是哪6个。另一种方法:char a10 = H,e,l,l,o,0;一次一个元素地初始化数组。这种方法通常用于输入不容

20、易在键盘上生成的那些不可见字符。2022-5-1747 省略数组大小在定义数组的场合,无论如何,编译器必须知道数组的大小。有初始化的数组定义可以省略方括号中的数组大小。例如:int a = 1,2,3,4,5;这种情况下,编译器是怎么知道数组大小的?编译器统计花括号之间的元素个数,以求出数组的大小。2022-5-1748在没有规定数组大小的情况下,程序怎么知道数组的大小呢?#include int main()int a = 1,2,5;cout数组的大小:sizeof(a)/sizeof(int)endl;1、sizeof(a)返回数组a的字节数。sizeof不是函数,而是操作符,它在编译时

21、计算大小,而不是在程序运行期间。2、数组的元素大小是sizeof(int),所以数组中元素的个数是sizeof(a)/sizeof(int)。2022-5-1749对于字符串的初始化,要注意数组实际分配的空间大小是字符串中字符个数加上末尾的0结束符。#include #include int main()char s = Hello;cout“数组的大小:” sizeof(s)/sizeof(char)endl;cout字符串的长度:strlen(s)endl;1、数组大小,要把结束符0算入。2、strlen计算字符串长度时不计算结束符。3、strlen函数需要头文件string.h2022-

22、5-17504、向函数传递数组 无论何时,将数组作为参数传给函数,实际上只是把数组的地址传给函数。 传递给标准库函数#include #include int main() int a10; unsigned short b234; memset(a,0,10*sizeof(int); memset(b,1,234*sizeof(unsigned short);1、memset函数是标准库函数,头文件在vc中是mem.h2、memset可以一个字节一个字节地设置为一个指定的值数组名作参数,数组作参数,它仅仅只是一个数组的起始地址而已。2022-5-1751 传递给自定义函数从上面的例子可以看出

23、,向函数传递数组时,往往传递两个值:数组起始地址,数组的大小。#include void f(int a, int n)int i,sum=0;for(i=0;in;+i)sum += i;coutsumendl;int main()int a10=1,2,3,4,5,6,7,8,9,0;f(a,10);1、数组参数的书写方式:int a,如果在方括号里写明了大小,编译器将忽略之。空方括号只是告诉函数,该参数是数组的起始地址。2、传递两个参数:数组起始地址、数组大小2022-5-17525、二维数组 二维数组定义C+的数值可以有多个下标,需要两个下标才能标识某个元素的数组称为二维数组。例如:i

24、nt c510; 数组c是二维数组,每个元素是int类型,每个元素用cij表示 2022-5-1753 0,0 0,1 0,2 0,3 1,0 1,11,21,30行1行0列1列2列3列a00a01a02a03a10a11a12a13二维数组经常用来表示按行和列格式存放信息的数值表,习惯上,第一个下标表示元素所在行,第二个表示列。 (以教室为例)1、int a24;有两行四列。2、二维数组是按先行后列的顺序在内存中线性排列的。2022-5-1754 二维数组初始化二维数组也能在定义时初始化。int a24 = 1,2,3,4,5,6,7,8;1、二维数组a,有两行,四列,也就是“有两行,每行4

25、个元素”。2、初始化的值按行用花括号组合在一起。1,2,3,4是第一行的值,5,6,7,8是第二行的值。a00a01a02a03a10a11a12a13123456782022-5-1755如果某行没有足够的初始化值,那么该行中的剩余元素都被初始化为0.int a24 = 1,2,3,5,6;1、二维数组a,有两行,四列,也就是“有两行,每行4个元素”。2、如果某行没有足够的初始化值,那么该行中的剩余元素都被初始化为0.a00a01a02a03a10a11a12a13123056002022-5-1756初始化还可以将多个花括号简化为一个花括号。int a24 = 1,2,3,4,5;1、二维

26、数组a,有两行,四列,也就是“有两行,每行4个元素”。2、初始化还可以将多个花括号简化为一个花括号。3、这些初始化值先赋值给第一行,再给第二行,不足的,初始化为0.a00a01a02a03a10a11a12a13123450002022-5-1757 省略第一维大小如果对全部元素都赋初值,则定义数组时对第一维的大小可以省略,但第二维的大小不能省。#include int main()int a4=1,2,3,4,5,6,7,8;a00a01a02a03a10a11a12编译器计算出2行4列。也分配2行4列的空间。2022-5-1758在定义时,也可以只对部分元素赋初值

27、而省略第一维的大小,但应分行赋初值。例如: int a4=1,2,3,0,4,5;等价于: int a34=1,2,3,0,0,0,4,5,0;等价于: int a34=1,2,3,0,0,0,0,0,4,5,0,0; 作为参数传递作为参数传递一个二维数组给函数,其意义也为内存地址,所以原型中,声明整数数组参数的形式只能省略左边的方括号。2022-5-1759#include void f(int x3, int m, int n)for(int i=0; im; +i)for(int j=0; jn; +j)coutxij;coutendl;int main()int a23=1,2,3,4

28、,5;f(a,2,3);1、程序中定义了二维数组a,2行3列。2、void f(int x3, int m, int n)作为参数传递一个二维数组给函数,其意义也为内存地址,所以原型中,声明整数数组参数的形式只能省略左边的方括号。3、形参中int x3, 数组a定义为int a23,右边的方括号必须一样。4、函数调用f(a,2,3),用二维数组名a作为参数,它是数组的起始地址。5、二重循环遍历二维数组,i是行下标,j是列下标。2022-5-1760 降维处理由于二维数组在内存中是线性排列的,所以可以在被调用的函数中用单重循环来遍历二维数组中的所有元素,此时只要传递数组名和元素总个数。#incl

29、ude void f(int x, int n)for(int i=0; in; +i)coutxi;int main()int a23=1,2,3,4,5;f(&a00,2*3);1、 int a23是二维数组,2行3列2、形参是int x,实参&a00,用第一个元素的地址作为数组的起始地址。3、2行3列,所以有2*3个元素,所以第二个参数是2*34、用单重循环扫描这2*3个元素。 2022-5-1761v二维数组元素的访问二维数组元素的访问: 按行序访问:按行序访问:int a34;for(i=0;i3;i+) for(j=0;j4;j+) aij外循环变量控制行,内循环变

30、量控制列按列序访问:按列序访问:int a34;for(j=0;j4;j+) for(i=0;i3;i+) aij.外循环变量控制列,内循环变量控制行列变化的快行变化的快2022-5-1762v常用的字符串处理函数常用的字符串处理函数包含在头文件包含在头文件 string.hu字符串输出函数字符串输出函数putsputs格式:格式:puts(puts(字符数组字符数组) )功能:向显示器输出字符串(输出完,换行)功能:向显示器输出字符串(输出完,换行)说明:字符数组必须以说明:字符数组必须以00结束结束u字符串输入函数字符串输入函数getsgets格式:格式:gets(gets(字符数组字符数

31、组) )功能:从键盘输入一功能:从键盘输入一以以回车结束的字符串放入字符数组中,回车结束的字符串放入字符数组中, 并自动加并自动加00例例 #include main( ) char string80; printf(“Input a string:”); gets(string); puts(string); 输入输入: How are you?输出输出: How are you?2022-5-1763u字符串拷贝函数strcpy格式:strcpy(字符数组1,字符串2)功能:将字符串2,拷贝到字符数组1中去返值:返回字符数组1的首地址说明:字符数组1必须足够大 拷贝时0一同拷贝 不能使用赋值语句为一个字符数组赋值例 char str120, str220; str1=“Hello!”; () str2=str1; ()2022-5-1764u字符串比较函数字符串比较函数strcmpstrcmp格式:格式:strcmpstrcmp( (字符串字符串1,1,字符串字符串2)2)功能:比较两个字符串功能:比较两个字符串比较规则:对两串从左向右逐个字符比较(比较规则:对两串从左向右逐个字符比较(ASCIIASCII码),直到遇码),直到遇到不同字符或到不同字符或00为止为止。返值:返回返值:返回intin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论