C++实验01C++程序设计上机指导谭成予.docx
《C++实验01C++程序设计上机指导谭成予.docx》由会员分享,可在线阅读,更多相关《C++实验01C++程序设计上机指导谭成予.docx(60页珍藏版)》请在冰豆网上搜索。
C++实验01C++程序设计上机指导谭成予
武汉大学计算机学院《C++程序设计》课内实验要求
C++程序设计上机指导
谭成予编著
上机指导1VC编译环境的使用和C++基本语法编写练习
目的和要求:
1.开始练习VisualC++中编写、编译、调试和运行Windows应用程序以及可视化编程的基本使用方法。
2.C++和C语言有区别的基本语法编程练习,主要包括C++中数据类型、引用、new和delete、函数重载等。
3.通过编程练习,初步掌握面向过程和面向对象的本质差别。
内容和步骤:
1.VC编译环境的安装
请VisualC++(建议2005版本及以上)编译环境,按照03-C++程序设计课内上机参考资料\01-VisualC++2005简介.ppt和03-C++程序设计课内上机参考资料\02-vs2005使用简介.pdf的介绍,完成以下操作。
:
(1)VC的安装,回答以下问题
安装过程中,设置开发语言为C++,操作方法:
;
安装之后,修改开发语言为C++,操作方法:
;
(2)安装MSDN,安装好之后,尝试使用MSDN查找资料。
(3)按照如下描述的步骤,尝试设置VC的选项。
a)用户可通过“选项”(Options)对话框来设置各种选项,当从主菜单中选择“工具”/“选项”时该对话框将显示出来,如图1所示。
图1VisualC++2005选项对话框
b)单击左边窗格中任意一项旁边的加号(+),将显示出子主题列表。
如图1显示的是“项目和解决方案”下面的“常规”子主题的选项。
右边窗格显示对应于左边窗格选定主题的设置选项。
单击选项对话框右上方的Help按钮(符号?
),将显示当前选项的解释。
用户平时关心的只有少数几个选项,但花点时间看看都有哪些选项可以设置将对用户很有帮助。
用户可能希望选择某个路径作为创建新项目时的默认路径,这可以通过如图1所示的“项目和解决方案”下面的“常规”子主题的选项来实现。
c)通过在左边窗格中选择“项目和解决方案”下面的“VC++项目设置”主题,可以设置应用于所有C++项目的选项。
d)通过选择主菜单上的“项目”下面的“属性”菜单项,可以设定当前项目所特有的选项,该菜单项是定制的,以反映当前项目的名称。
2.VCIDE(创建,编辑、编译等)的基本操作使用
(1)创建新项目和源程序
a)创建新项目
i.在VisualC++中编写C程序的第一步是:
创建新的项目,例如Win32控制台项目。
这个操作可以通过两种方法来实现:
其一,单击主菜单中“文件”下面的“新建”/“项目”选项;其二,是单击标准工具栏中的“新建项目”工具按钮。
无论是上面的哪种方式,都将弹出如图2所示的“新建项目”对话框。
图2VisualC++2005新建项目对话框
ii.在“新建项目”对话框中,请选择左边窗格中“项目类型”的“VisualC++”下面的“Win32”。
然后,选择右边窗格中“模板”下方的“Win32控制台应用程序”。
第三,可以在下方的窗格内输入新建项目及其解决方案的名称,例如输入项目名称“aa”;并确认新建项目的位置。
最后,单击“确认”按钮,将显示如图3所示的“Win32应用程序向导”对话框。
iii.单击“Win32应用程序向导”对话框中的“下一步”按钮,将显示如图4所示的“Win32应用程序向导——应用程序设置”对话框。
图3Win32应用程序向导
iv.在如图4所示的“Win32应用程序向导——应用程序设置”对话框中,用户可在“应用程序类型”中,选择“控制台应用程序”。
在“附件”选项中可以选择“空项目”或者“预编译头”,这里将要编写的是纯C程序,因此推荐选择“空项目”。
最后,点击“完成”按钮,将显示如图4所示的新建项目的编辑主界面。
图4Win32应用程序向导——应用程序设置
b)创建新的源程序文件
i.图5所示的是刚刚新建的项目aa的编辑主界面,注意此时项目aa是一个空的容器,其中还没有任何源程序文件。
此时,需要做的是创建新的源程序文件,这可通过两种方式完成:
第一种方法是,选择主菜单中“项目”下面的“添加新项”;第二种方法是,在图5中左边窗格的解决方案管理器中的“aa”|“源文件”上面右击,在弹出的菜单中选择“添加”|“新建项”。
这时,将显示如图6所示的“添加新项”对话框。
图5编辑项目的主界面
图6添加新项对话框
ii.在“添加新项”对话框中,在“类别”窗格中选择“代码”选项。
在“模板”窗格中选择“C++文件”。
在下方的窗格中输入新建的源文件名称,例如hello。
最后,单击“添加”按钮,系统将显示如图7所示的项目及源程序编辑窗口。
图7项目及其源程序编辑界面
iii.在图7所示的项目及源程序编辑界面中右边窗格是源文件的编辑窗口,在此窗口中输入用户所需要编写的C程序。
例如,现在输入下面的C程序代码:
例题1-1整数溢出范例程序。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
/*整型数据溢出范例。
源文件:
LT1-1.C*/
#include
#include
intmain(void)
{
shortinta,b;
a=32767;
b=a+1;
printf("a=%d,b=%d\n",a,b);
system("PAUSE");
return0;
}/*main函数结束*/
iv.用户可用快捷键Ctrl-S来保存编写的源文件,也可以通过“文件”或者“编辑’菜单中相应选项来实现保存、粘贴等编辑功能。
现在请回答以下的问题:
回答以下问题
你使用的VC环境中,有哪些类型的项目文件?
(2)编辑已存在的项目及源程序
a)如果需要修改或者重新编译之前已经编写好的项目和源程序,可以通过“文件”菜单下面的“打开”|“项目/解决方案”,或者通过标准工具栏中的“打开文件”按钮。
这时将出现如图8所示的“打开项目”对话框。
图8打开项目对话框
b)用户可以在图8所示的“打开项目”对话框中,选择之前保存项目的文件夹以及该项目的文件名,然后单击“打开”按钮即可。
VisualC++中的项目文件夹的名称将与之前创建时给出的项目名称相同,该文件夹还将容纳所有构成该项目定义的文件。
如果不加修改,则解决方案具有与项目文件夹相同的名称,而且包含项目文件夹和定义解决方案内容的文件。
用户在解决方案文件夹中可以看到该文件夹包含如下3个文件:
●扩展名为.sln的文件,记录着关于解决方案中项目的信息。
●扩展名为.suo的文件,记录着应用于解决方案的用户选项。
●扩展名为.ncb的文件,记录着与解决方案的Intellisense有关的数据。
Intellisense是在编辑器窗口中输入代码时提供自动完成和提示功能的工具。
例如在“D:
\ProgramFiles\MultiGen-Paradigm\aa”文件夹中可以看到与之前创建的解决方案aa有关的3个文件:
aa.sln、aa.suo和ss.ncb。
用户在项目文件夹中查看,可以看到最初有6个文件,其中名称为ReadMe.txt的文件包含该项目所有文件的内容摘要。
在项目文件夹中可能存在一个文件是ProjectName.vcproj.ComputerName.UserName.user,例如之前创建的aa项目文件夹中存在文件aa.vcproj.LENOVO-DB8C1480.user.user,这个文件的作用是存储为该项目设定的选项。
其中“LENOVO-DB8C1480”是作者使用的计算机名。
c)如果希望在源代码编辑窗口中显示行号,请从主菜单上选择“工具”|“选项”,在“选项”对话框中左边窗格选择“文本编辑器”下面的“C/C++选项”|“常规”,在右边窗格中选择“行号”即可。
(3)编译并构建解决方案
在VisualC++中编写程序被称为“构建解决方案”,可通过F7快捷键或者选择主菜单下的“生成”|“生成解决方案”。
另外还可通过单击“生成”工具栏上的相应按钮。
如果程序中有错误,则会在主界面下方的输出窗格中显示错误提示信息,例如图1-17所示的窗口中提示程序存在一个错误:
错误信息是“errorC2146:
语法错误:
缺少“;”(在标识符“system”的前面)”,用户可按照提示在
printf("Hello!
World!
\n")
这一行的最后面加上分号(;),然后重新选择生成解决方案,直到系统提示成功为止。
在成功创建了解决方案之后,用户可以在相应的项目文件夹中看到一个新的子文件夹Debug,例如之前创建的项目aa中出现的新文件夹是:
D:
\ProgramFiles\MultiGen-Paradigm\aa\debug。
在该文件夹中包含多个文件。
这些文件的扩展名和用途分别是;
●.exe文件:
这是程序的可执行文件,仅当编译和链接步骤都成功之后才能生成该文件。
●.obj文件:
编译器根据程序源文件生成这些包含机器代码的目标文件,它们与库文件一起被链接器使用,最后生成.exe文件。
●.ilk文件:
该文件在重新构建项目时被链接器使用,它使链接器能够将根据修改的源代码生成的目标文件增量地链接到现有的.exe文件,从而避免每次修改程序时都重新链接所有文件。
●.pch文件:
这是预编译头文件。
使用预编译头文件,大块无需修改的代码(尤其是那些C++库提供的代码)可以被处理一次并存储在.pch文件中。
使用.pch文件能够大大减少构建程序所需的时间。
●.pdb文件:
该文件包含在调试模式中执行程序时要使用的调试信息。
在调试模式中,可以动态检查程序执行过程中所生成的信息。
●.idb文件:
包含重新构建解决方案时要使用的信息。
(4)运行解决方案
在成功编译过解决方案之后,可以按下Ctrl-F5组合键来执行程序。
也可以通过主菜单下的“调试”|“开始执行”,或者单击标准工具栏中的“开始调试”按钮来执行程序。
之后会看到如图9所示的程序执行窗口。
图9程序运行窗口
3.VisualC++中调试工具的使用
故障是程序中的错误,而调试就是寻找并消除故障的过程。
调试是编程过程中不可缺少的组成部分,它自始至终与编程相伴。
在详细描述VisualC++的调试工具之前,先来看看程序中故障的产生过程。
(1)调试器使用简介
调试器是一个程序,它控制着程序的执行过程:
程序员可以一行一行地单步调试源程序,或者运行程序中特定的位置。
在源代码中每个使得调试器停下来的位置,程序员可以在继续执行之前检查乃至修改变量的值。
如果修改了源代码,必须重新编译并使程序从头开始执行。
首先需要将该实例项目的编译配置设定为Win32Debug而不是Win32Release。
编译配置为程序的编译操作选择一组项目设定值,当我们选择主菜单上的“项目”|“属性”菜单项时可以看到这些设定。
当前有效的编译配置显示在标准工具栏上一堆相邻的下拉列表中。
程序员还可以通过主菜单上的“生成”|“管理配置器”菜单项来设置调试配置。
标准工具栏如图10所示。
图10标准工具栏
调试工具栏如图11所示,其中“逐语句”和“逐过程“按钮代表着调试器的一种特定工作模式:
单步调试代码,即每次执行一条语句,二者的区别是“逐语句”会跟踪到函数内部,对被调用的函数中的每条语句都采用单步调试方式;“逐过程”不会跟踪到函数内部,每次函数调用都把函数体内的所有代码当作一条语句一次执行。
当然,无论哪种单步调试方式,执行一条语句之后,程序员都必须通过检查变量的值来判断这条语句是否出现错误。
对于大型程序而言,单步调试方式显然是不切实际的。
相对于单步调试方式,断点模式是指执行到源代码中特定的位置(被称为断点)处暂停,所以,断点模式更节省时间,更为实用。
图11调试工具栏
(2)设置断点
断点是程序中使调试器自动暂停执行的位置。
程序员可以设置多个断点,这样程序在运行过程中就可以在程序员选定的感兴趣的位置停止。
程序员可以在执行到各个断点处查看程序中变量的值,一旦变量值不符合预订值时,就可以帮助判断程序代码中哪里出现错误,并进行修改。
通常只需要检查可能有错误的特定区域,所以,通常应该在人为包含错误的位置设置断点,然后运行程序,使程序停止在第一个断点处。
然后,如果愿意,程序员可以从该断点处开始单步执行。
把源程序的某行设置为断点或者取消断点的常用方法有两种:
●第一方法是:
选择主菜单上的“调试”|“切换断点”,就可以把当前行所在的代码设置为断点。
●第二种方法是:
在该语句行号左边的灰色显示列单击即可。
某个代码行被设置为断点之后,在该代码行左边的灰色区域中将出现一个红色的圆圈符号,它被称为图示符,表明该行存在断点。
我们可以通过右击图示符的方法来删除断点。
图12所示的编辑器窗格中,已经为之前的示例程序设置了一个断点。
图12断点设置
更为高级的设置断点的方法是:
●使用Alt-F9组合键;
●选择主菜单上“调试”中的“窗口”|“断点”;
●选择调试工具栏上最右边的“断点按钮。
采用上述三种方法中的任意一种,在主界面的下方将或出现如图13所示的断点窗口。
其中会显示所有已经设置的断点,而短线窗口中工具栏上的“新建“按钮可以帮助设置新的断点,而“列”按钮可以帮助设置要显示的断点信息,例如显示包含断点的源文件名或函数名。
图13设置断点窗口
(3)设置跟踪点
跟踪点是一种特殊的断点,它具有与之相关联的自定义动作。
创建跟踪点的方法是:
右击希望设置为跟踪点的代码行,然后从弹出菜单中选择“断点”|“插入跟踪点”,这时将出现如图14所示的“命中断点时”对话框。
在该对话框中可以设置跟踪点动作是“打印消息”或者运行某个宏,例如,可以在设置打印消息为:
$FUNCTION,Thevalueofbis{b}
那么,当抵达该跟踪点时,上述设置产生的输出将显示在应用程序窗口中的输出窗格中。
当然,也可以在图14所示的命中断点时对话框中设置程序执行到跟踪点上是暂停执行还是继续执行,红色类型符号表明某行那个源代码中存在不使执行停止的跟踪点。
图14命中断点时对话框
(4)启动调试模式
在如图15所示的调试菜单选项上,有在4种调试模式中启动应用程序的方式。
图15调试菜单
(1)启动调试:
使得程序执行到第一个断点处,然后使得执行暂停。
在检查过需要在该断点处检查的所有变量之后,可以再次选择相同的菜单项将使得程序继续执行到下一个断点处。
(2)附加到进程:
允许程序员调试某个已经在运行中的程序(进程)。
该选项将显示机器上正在运行的进程列表,程序员可以选择希望调试的进程。
这个选项是提供给高级用户使用的,除非十分肯定地知道自己在做什么。
否则不要使用此项调试关键的操作系统进程,否则可能引起锁死机器,或者引起其他问题。
(3)逐语句(StepInto):
一条一条语句的执行,并跟踪到函数代码块的内部。
(4)逐过程(StepOver):
逐条语句执行,但是对于可能调用函数的所有代码,都将一次性执行。
(5)检查和修改变量的值
下面以之前的范例程序为例来说明调试模式的使用方法,然后,选择主菜单上的“调试”中的“启动调试”选项,程序将执行到断点处暂停。
此时,程序员需要检查程序中某些变量的取值,通常有通过自动窗口查看和在编辑器窗口查看两种方法。
a)自动窗口查看变量值
图16显示的是调试过程的主界面窗口,其中左下方是自动窗口,其中,显示有程序中变量的数值。
从图16的自动窗口中,可以看出执行到第8行的断点处时,变量b的取值是-32768,而不是希望的32768,因此,可以判断出错误出现在程序的第8行之前。
如果此时无法判断第8行之前究竟是哪一行出现了错误,这时可以选择主菜单上的“调试”中的“停止调试”选项,用于终止本次调试状态。
然后重新调试程序,选择“逐过程”的单步调试方式,逐条执行每条语句,很快就可以发现错误出现在第7行的代码行中。
图16自动窗口查看变量值
自动窗口中共有5个选项卡,各选项卡需要显示的信息如下所示:
●自动窗口:
显示当前语句及相关的前一条语句正在使用的自动变量。
●局部变量:
显示当前函数中局部变量的值。
通常,新变量随着程序的执行依次进入其作用域,然后在退出定义它们的代码块时再离开其作用域。
在本例中,该窗口始终显示变量a和b的值。
●线程:
允许程序员检查并控制高级语言程序中的线程。
●模块:
列出当前执行的代码模块的细节。
如果应用程序崩溃,通过比较发生崩溃时的地址与该选项卡上地址列的地址范围,程序员就可以确定崩溃发生在哪个模块中。
●监视1:
程序员可以通过主菜单上的“调试”中的“快速监视”菜单项,把希望监视的变量或表达式添加到监视1选项卡上。
程序员也可以通过单击该窗口中的某行,然后通过输入变量名的方法来实现添加监视对象。
注意,包含附加信息的任何变量,例如数组、指针或者类对象,自动窗口中其名称的左边都会出现一个加号。
单击该加号,可以展开该变量的视图。
b)编辑器窗口查看变量值
如果程序员需要查看单个变量的值,而且改变了在编辑器窗口是可见的,则最简单的方法查看该变量值的方法是:
把光标停留在该变量上方一秒钟。
弹出的工具提示将给出该变量的当前数值。
如果要查看的是表达式的值,则首先选中该表达式使得其醒目显示,然后把光标停留在该表达式上方一秒钟,此时弹出的工具提示同样会显示出该表达式的值。
c)修改变量值
监视窗口允许程序员修改被监视的变量的值。
程序员可以在显示出来的数值明显错误的情况下使用该功能,数值错误的原因可能是程序中存在故障,或者是所有代码都不合适。
如果程序员设置“正确的”数值之后,则程序将继续向前执行,从而帮助程序员测试其他部分,并有可能找出一些其他错误。
在监视窗口修改变量的方法是:
右击监视窗口中需要修改数值的变量值,在弹出菜单中选择“编辑值”,其次,输入新值即可。
然后就可以继续执行程序余下的代码,用来判断余下的代码行中是否存在错误。
下面请按照上面介绍的方法,对“例题1-1”完成调试工作,并回答以下问题:
请问用断点调试方法,你会将断点设置在第行。
4.new和delete的使用
(1)请仔细阅读以下程序,并在下划线出填写正确的语句,并上机调试此程序。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
//new、delete练习1,为单个变量分配空间
#include
usingnamespacestd;
intmain(void)
{
int*p1,*p2;
;//为简单变量分配内存
;//为简单变量分配内存,并初始化为6
*p1=10;
cout<<*p1<cout<<*p2<;
cin.ignore();
return0;
}/*endmain*/
(2)请仔细阅读以下程序,并在下划线出填写正确的语句,并上机调试此程序。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
//new、delete练习2,为数组分配空间
#include
usingnamespacestd;
intmain(void)
{
int*p;
;//请比较与p=newint(6);的不同
for(inti=0;i<6;i++)
cin>>p[i];
for(i=0;i<6;i++)
cout<<*(p+i)<<"";
;
cin.ignore();
return0;
}/*endmain*/
(3)下面请回答以下问题:
a)new、delete和malloc、free有什么区别?
b)new能不能和free配对使用?
c)思考题:
如果new分配失败,系统会抛出什么异常,编程时应该如何处理?
5.内联函数、函数重载的使用
以下的程序中只定义了主函数,缺少max函数的定义,请补充max函数的定义,要求将max函数定义为内联函数。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
//计算两个数据的最大值
#include
usingnamespacestd;
intmain(void)
{
inta,b,c;
cout<<"Inputtwodata:
";
cin>>a>>b;
cout<<"Themaxis:
"<cin.ignore();
return0;
}/*endmain*/
下面请回答以下问题:
a)C++为什么会设置内联函数?
b)假设上面的程序中变量a、b、c的类型可能是int、double和字符串中的任意一种,请你用函数重载的形式重写上面的程序。
6.引用的使用
(1)引用参数的使用
请仔细阅读下面的程序,如果将第17行的“swap(&a,&b); ”修改为“swap(a,b); ”,请问swap函数应该如何修改?
请按上述要求修改下面的程序,并上机调试。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
//计算两个数据的最大值
#include
usingnamespacestd;
voidswap(int*x,int*y) //函数定义,形参为指针
{
inttemp;
temp=*x;
*x=*y;
*y=temp;
}
intmain(void)
{
inta=5,b=10;
cout<<"BeforeSwapa="<swap(&a,&b); //传地址调用
cout<<"AfterSwapa="<cin.ignore();
return0;
}/*endmain*/
(2)返回引用的函数
请仔细阅读以下的程序,指出程序中存在的错误,并上机改正错误。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
//计算两个数据的最大值
#include
usingnamespacestd;
int&f1(intn