学习目标:
- 了解C++的发展历程
- 了解C++的新特性
- 掌握C++的新数据类型、新的术语与技术手段
- 掌握基本的C++编程方法
C++程序
C++程序的编译与执行
C++源代码为.cpp文件,其编辑、编译及运行过程和C语言基本一样,分为编辑、编译、链接和执行4个步骤。
C++程序的格式与构成
//changedata.cpp
#include <iostream> //包含输入/输出头文件
using namespace std; //使用标准命名空间
void ChangeData(int* a, int* b); //函数原型声明
int main()
{
int x,y;
cout<<"Please input two numbers:\n"; //提示输入两个数
cin>>x; //从键盘输入两个数到x和y
cin>>y;
cout<<"x="<<x<<",y="<<y<<endl; //输出x和y的值并换行
ChangeData(&x,&y); //调用子函数来交换x和y的值
cout<<"The result of changing are: \n";
cout<<"x="<<x<<",y="<<y<<endl; //输出交换后的x和y的值并换行
return 0;
}
void ChangeData(int* a, int* b) //定义函数ChangeData的原型
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
使用数组——>抽象、封装——->使用结构体———>操作、私有————>使用类
struct Student{ //声明一个表示学生的结构体类型
long lNum; //学号
char sName[12]; //姓名
float fGrade; //成绩
};
class OurClass{ //声明一个班级类
private:
char cName[20]; //定义班级名称
Student stu[N]; //定义N个学生
public:
void Input(); //输入学生信息
void Print(); //输出学生信息
void Sort(); //按学生成绩进行排序
};
C++的一些新特性
1、注释
① 注释符“//”只注释“//”后面的内容,且只注释当前行的内容,不可跨行进行。若要注释多行,可在每行开头添加“//”。例如://changedata.cpp//get the sum of x and y
② “/”和“/”可以注释多行内容,即可以跨行注释,但必须成对出现。
2.新的数据类型
C++在C语言的数据类型基础上又增加了一种新的数据类型,即布尔型(bool),为逻辑型变量,取值范围为true/false,存储大小为1字节。
例如:
bool b;
b=true; //区别于
b=“true”if(b) //等价于
if(b==true)
cout<<”OK”;
注意:bool型变量取值不是字符串“true”和“false”。
3.灵活的变量说明
C语言中,局部变量必须集中在可执行语句前声明,而C++可以灵活地声明在程序中的任意位置,允许变量声明与可执行语句在程序中交替出现,但都需要“先定义后使用”。
例如:
int i;
i=100;
int j=90;
j++;
int k=i+j;
4.作用域运算符
在C++或C语言编辑环境中,如果有两个同名变量,即全局变量和局部变量,则局部变量在其作用域内具有优先权。
[例2-4] 作用域运算符实例1。
int T=10;
int main(){
int T;
…
T=5; //此处修改的是局部变量T的值,而不是全局变量T …
return 0;
}
在局部变量作用域内修改全局变量的值,则使用作用域运算符“::”
int T=10;
int main(){
int T;
…
T=5; //修改局部变量T的值
::T=10; //修改全局变量T的值
…
return 0;
}
在C++中,“::”的作用有以下三种:
1、全局作用域运算符(::名称);
2、类作用域运算符(类::类成员名);
3、命名空间作用域运算符(命名空间::名称)。
关于后两种的使用方法将在后续章节讲解。
5.命名空间
命名空间就是一种将程序库名称封装起来的方法。命名空间是C++为解决变量、函数名和类名等标识符的命名冲突服务的,它将变量等标识符定义在一个不同名的命名空间中。
定义格式如下:
namespace 命名空间标识符
{
成员的声明;
}
#include <iostream>
using namespace std; //使用C++标准命名空间
namespace A {
char user_name[]="namespace A";
void showname(){
cout<<user_name<<endl;
}
}
namespace B{
char user_name[]="namespace B";
void showname(){
cout<<user_name<<endl;
}
}
int main(){
A::showname();
//用命名空间限制符访问showname()
B::showname();
//用命名空间限制符访问showname()
//用命名空间限制符访问变量user_name
strcpy(A::user_name,"good");
A::showname();
return 0;
}
使用using namespace指令时就可以不用加命名空间名称。这个指令会告诉编译器,
后续的代码将使用指定的命名空间中的名称。例如,在例2-6中就可以进行如下应用
#include <iostream>
using namespace std;
namespace A {
char user_name[]="namespace A";
void showname(){
cout<<user_name<<endl;
}
}
namespace B{
char user_name[]="namespace B";
void showname(){
cout<<user_name<<endl;
}
}
using namespace A;
int main(){
showname();
//访问A中的showname()
B::showname();
//访问B中的showname()
//用命名空间限制符访问变量user_name
strcpy(user_name,"good");
//访问A中的user_name
showname();
//访问A中的showname()
return 0;
}
namespace A {
int a;
namespace B{
int a;
}
}
int main(){
…
A::a=1;
//为命名空间A中的a赋值1
…
A::B::a=2;
//为命名空间A中的命名空间B的a赋值2
…
return 0;
}
6.新的输入/出
C语言中的输入/输出函数scanf()/printf() 经常因为数据类型和所使用的控制符问题而产生错误,且编译器却检查不出问题。
例如:
int i;
float f;
scanf(“%f %d”, &i,&f);
printf(“%f %d”,i,f);
此时,scanf()和printf()所使用的格式控制符与输入/输出的变量类型不一致,但该错误编译器并没有查出。
因此,C++中使用了更加便捷、安全的I/O(输入/输出)操作。
上面的代码可以改为:
int i;
float f;
cin>>i>>f;
cout<使用I/O操作cin/cout需要包含头文件iostream.h。(后期版本里,C++标准程序库的所有标识符都被定义在一个名为std的namespace中)
#include <iostream>
using namespace std;
int main(){
int x;
float f;
char str[20];
cin>>x>>f;
cin>>str;
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<str;
return 0;
}
7.头文件
C++中,头文件可告诉编译器库中哪些是可用的,头文件是存放接口规范的唯一地方,是库的开发者与用户之间的合约。
在C++中文件分为.h头文件和.cpp文件。
1、把“只声明”的代码放入.h头文件中。
2、把“实现”部分代码放入.cpp文件中。
//MyTest.h //头文件
class A{//类A的声明部分
int x;
…
void test();
…
};
int fun(); //全局函数fun()的声明部分
//MyTest.cpp
//类A的实现部分
void A::test(){
…
}
int fun(){//全局函数fun()的实现部分
…
return 0;
}
int main(){//主函数
A a;
…
return 0;
}
8.引用
1)引用的概念
引用被认为是某个变量或对象的别名
格式为:类型名& 引用名 = 被引用的对象名称;
例如:
int x;
int& y = x;
引用就像给原来的对象起了一个“绰号”,访问引用时,实际访问的就是被引用的那个存储单元。
#include <iostream>
using namespace std;
int main(){
int i=0;
int& j=i;
cout<<"&i="<<&i<<",&j="<<&j<<endl;
cout<<"i="<<i<<",j="<<j<<endl;
i++;
cout<<"i="<<i<<",j="<<j<<endl;
j++;
cout<<"i="<<i<<",j="<<j<<endl;
return 0;
}
运行结果:
&i=004FFB78,&j=004FFB78
i=0,j=0
i=1,j=1
i=2,j=2
引用(&)使用规则如下。
① 当引用被创建时,它必须被初始化(指针则可以在任何时候被初始化)。
② 一旦一个引用被初始化为指向一个对象时,它就不能被改变为对另一个对象的引用(指针则可以在任何时候指向另一个对象)。
③ 没有NULL引用。它必须确保引用是和一个合法的存储单元关联的。当定义一个引用时,必须被初始化指向一个存在的对象,也可以这样写:
int n;
int& m=n;
//int &j; //错误,没有初始化
为引用再提供一个引用也是合法的
例如:
int x=5;
int& y=x;
int& z=y;
【注意】
使用引用时应注意如下问题:
① 不能建立引用数组,例如:
int iData[5];
//int& icData[5]=iData; //错误
② 不能建立引用的引用,例如:
int i;
//int&& j=i; //错误
2)引用与指针
引用与指针有着本质的区别,指针通过变量的地址可间接访问变量,而引用通过变量的别名可直接访问变量。
3)引用与函数 — 引用作为函数参数、引用作为函数返回值
- 采用引用的主要用途之一就是做函数的参数使用
- 当函数的返回值为引用方式时,需要特别注意的是,不要返回一个不存在的或已经销毁的变量的引用
int& tcite2() { int m = 2; //return m; //错误,调用完函数tcite2()后,临时对象m将被释放,返回值为一个空引用 static int x = 5; return x; } int* tpointer(int *p) { (*p)++; return p; } int& tcite(int &c) { c++; return c; } int main() { int i; tpointer(&i); tcite(i); return 0; }