1.C++语言简介
1.1一个简单的C++程序
#include<iostream>//包含头文件iostream
using namespace std;//使用命名空间std
int main()
{
//cout语句,有cout和插入运算符<<实现的输出语句
cout<<"Hello World!"<<endl;
return 0;
}
2.C++标准头文件
C++标准库中的头文件不再包含后缀.h
为使已有的C程序能继续使用,C++编译系统保留了C的头文件。
例如:cmath头文件,其中第一个字母c表示它是继承标准C的头文件;
#include<math.h>//C形式的头文件
#include<cmath>//C++形式的头文件,二者效果运用
建议:尽量用符合C++标准的形式,即在包含C++头文件时一般不用后缀。用户自己编写头文件,可以用.h作后缀。这样从#include指令中即可看出哪些头文件是属于C++标准库的,哪些头文件是用户自编或别人提供的。
3.命名空间(namespace)
C++标准库中的类和函数是在命名空间std中声明的。程序中若需要使用C++标准库中的有关内容,就需要用“using namespace std;”声明。
命名空间是C++为了开发大型软件的时候,尤其是多团队同时开发不同部分时,避免同名冲突。
//声明
namespace 空间名字
{
//可包含常量、变量、函数、结构体、类、模板、命名空间等
}//此处无;
//格式命名空间名::命名空间的成员名(::为作用域运算符
//例如:std::cin,std::cout等
#include<iostream>
int main()
{
std::cout<<"Hello World!\n";
}
4.C++输入输出简介
4.1输入
通过输入流对象cin和提取符">>"实现标准设备向程序中的变量输入数据。
//语法
cin>>var1>>var2>>...>>varn;
C++已经为基本数据类型重载了提取符“>>”,可以直接使用。
char name[32];
int age;
cin>>name>>age;
//键盘可输入数据
4.2输出
通过输出流对象cout和插入运算符"<<"实现程序标准输出设备中输出数据。
//输出语法
cout<<表达式1或控制符<<表达式2或控制符...<<<<表达式n或控制符
控制符定义输出数据的格式。
例如endl就是一个常用的控制符,它的作用时使输出位置移动到下一行的开始处。
5.逻辑类型——布尔(bool)
C语言没有提供逻辑型数据,关系表达式的值(真或假)用数值1和0代表,
C++增加了逻辑类型bool。逻辑型常量只有两个,即为true(真)和false(假)。
编译系统处理逻辑型数据时,true处理为1,false处理为0,而不是将fals和true这两个字符串存放在内存单元中。
逻辑型变量也称为布尔变量,在内存中占1个字节,用来存放0或1。
bool isOddNumber=false;
cout<<isOddNumBer<<endl;
isOddNumber=7;
cout<<isOddNumber<<endl;
//输出为0 \n 1
6.const
C语言:可以通过指针来间接修改局部const变量的值(不推荐使用指针间接修改const值)
C++:增加了C语言中const的作用,不可以通过指针来间接修改用基础数据类型常量初始化的局部const常量。例如:const int a =5;
C++推荐使用const代替#define:
(1)const定义的常量,有类型检查机制,有作用域;
(2)#define无类型检查,不重视作用域;
当函数的参数或返回值不希望被改变时,可声明为const。
//示例——C语言中的const
#include<stdio.h>
const int M=100;
int main()
{
//局部const
const int a =5; //不可以直接修改
int arr[a]; //error:a不是常量表达式
int* pa=&a; //warning C4090
*pa=10; //输出10,间接修改成功
printf("a=%d\n"'a);
//全局const
int* pM=&M; //warning C4090
*pM=99; //引发异常:写入访问权限冲突。间接修改失败
printf("M=%d\n",M);
return 0;
}
//示例——C++中的const
//局部const
const int a=5; //用整形数值5初始化局部const,直接或间接都不可以修改其值
int arr[a]; //正确
int* pa=(int*)&a; //C++类型检查更加严格,如果不强制类型转换(int*),则会引发error C2440:无法从“const int*”转换为“int*”
*pa=10;
cout<<"a="<<A<<endl;//输出5,间接修改失败
7.struct增强
定义结构体变量时,C++不需要加struct关键字,而C语言中需要;
C++中,可对结构体中的数据做访问控制,可包含该数据类型的函数。
struct student
{
private://指定访问权限
char ID[20];
public:
char name[20];
const char* set_ID(const char* p)
{//结构体内有函数
strcpy_s(ID,p);
return ID;
}
const char* get_ID()
{
return ID;
)
);
int main()
{
student one;//定义结构体变量
strcpy_s(one.name,"zhahngsan");
one.set_ID("001224");
cout<<"ID:"<<one.get_ID()<<endl;
cout<<"name:"<<one.name<<endl;
return 0;
}
8.动态内存空间管理
在C++语言中推荐使用新的运算符new和delete
new用于从内存中分配指定大小的内存,返回值是指针
delete用于释放new分配的堆内存
int* p1=new int; //分配一个能够存放int类型数据的内存区域
int* p2=new int(10); //分配一个int类型大小的内存区域,并将10存入其中
int* p3=new int[10]; //分配能够存放10个整数的数组区域
delete p1; //释放p1指向的内存
delete p2;
delete p3; //只释放了p3指向数组的第一个元素
delete []p3; //释放p3指向的数组
9.引用(reference)
9.1引用基础
引用:是C++语言新增加的概念,主要用作对已定义变量的别名,对引用的任何操作实际上就是对它所代表的数据对象的操作。
引用变量的声明:类型关键字 &引用变量名=已定义的同类型变量名
int x;
//数据类型名后面出现的&是引用声明符,起标识作用不是取地址运算
int &rx=x;//声明rx是变量x的引用,rx和x享用同一块内存单元
//此处&为取地址运算符
int *px=&x;//指针变量px存储x的地址
注意:
(1)必须在声明的同时进行初始化;
(2)引用初始化之后不能重新赋值;
(3)必须确保引用是与一段有效的存储单元相关联。
9.2函数中的引用
引用的本质是指针常量(*const),所有应用的功能都可以由指针实现。
引用是C++对C语言的主要扩充,主要是为了改善函数参数传递时的性能。增加引用机制后,用户可以不必具体去处理地址,而把引用作为变量的“别名”来理解和使用,把地址的细节隐藏起来,这样难道会小一些。
什么时候使用引用?
(1)传递大量数据。引用传递被自动转换为指针传递,只需要传递4个字节,这些能够减少拷贝数据的开销。
(2)返回一个内存空间作为左值。为了能够修改函数返回值,可以使用引用(若采用相应的指针形式,但比较麻烦)。
9.3引用作为函数参数
函数调用时,实参与形参的结合过程相当于声明了一个形参对实参的引用,引用成为本次调用的实参变量在被调函数中的别名。函数体内对形参的运算相当于对实参的运算。
void sqap(int& a,int& b)//形参时“引用”
{
int temp;
temp=a;
a=b;
b=temp;//b处因为在函数体内,参数不用加*
}
int main()
{
int i=3,j=5;
swap(i,j);//实参为整形变量(已具有内存空间)
cout<<"i="<<i<<""<<"j="<<j<<endl;
return 0;
}
与指针相比,引用作为函数参数语法更清楚简单:
(1)函数体的实现比指针简单(参数不用加*)
(2)调用函数语法简单(实参不用加&):指针作为形参,形参需要取变量的地址;引用作为形参,与简单传值调用引用,实参为变量。
9.4引用作为函数返回值
从函数中返回一个引用时,引用关联的内存必须存在,返回引用的函数调用时可以当作左值。
函数原型:类型关键字&函数名(形式参数列表)
int& larger(int& a,int& b)//思考int& b中的标记符&可以去掉吗
{
return a>b ? a:b;
}
int main()
{
int x=2,y=5;
cout<<"x="<<x<<"y="<<y<<endl;
cout<<(larger(x,y)+=5)<<endl;
cout<<"x="<<x<<"y="<<y<<endl;
return 0;
}
函数返回的引用不能是自动局部变量,且内存应当是可以被修改的。
10.有默认参数的函数
C++允许在函数声明或函数定义中为形参指定一个默认值。在调用此类含默认值形参的函数时,如果形参有对应的实参,则将实参传递给形参;如果省略了实参,则将上述默认值传递给形参。
void Myfun(int val=10);//声明函数
Myfun(20);//实参为20,默认值不起作用
Myfun();//实参为默认值10,相当于Myfun(10)
函数有多个默认参数时,默认参数必须时从右向左连续定义(原因:编译器在实参与形参对应时时按从左到有顺序进行的)
//错误示例
void fun(int a=3,int b);
void fun(int a=65,int b,int c=3);
函数声明和函数定义不能同时设置默认参数
11.函数重载(function overloading)
C++允许用同一函数名定义多个函数(即“一名多用”),而这些函数的参数个数或参数类型不同。这就是函数的重载(function overloading)。
函数调用时编译器通过重载函数的参数列表(参数个数、参数类型或参数顺序,三者中必须至少有一种不同)决定调用哪一个函数。
重载函数的使用与普通函数类似,每个函数都要进行声明与定义。
仅函数返回值不同的函数不构成重载。
函数重载和默认参数一起使用,需要额外注意二义性问题的产生。
int f(int a,double b);
void f(int a,double b,int c=0);
//函数调用语句f(8,2.3);具有二义性,编译器不能根据参数的形式确定到底调用哪一个。