1.注释行
在C++中,可以用"/*"和"*/"作为注释分界符号。如:
/* This is a test.*/
还可以用//来进行注释,如:
//This is a test.
"/*~~~~~~*/"表示方式不能嵌套,却可以在里面嵌套"//"的方式做注释。
2.输入和输出
用cin表示输入,cout表示输出。如:
cin>>a; //输入a
cout<<a; //输出a
用cin和cout进行I/O操作时,在程序中必须嵌入头文件iostream。
用cout输出时可以输出不同进制的数据。如:
dec把转换基数设置为十进制,hex把转换基数设置为十六进制,oct把转换基数设置为八进制。
3.const修饰符
C++中可以用const修饰符来定义常量。如:
const int S=100;
const作用与#define相似,但他消除了#define的不安全性。
#define的不安全性为:
#include <iostream>
using namespace std;
int main()
{
int a = 1;
#define T1 a + a
#define T2 T1 - T1
cout << "T2 is " << T2 << endl;
return 0;
}
初看程序,似乎应得出结果为:
T2 is 0
但实际输出结果为
T2 is 2
其原因是C++把第7行语句解释为:
cout<<"T2 is "<<a+a-a+a<<endl;
而使用const修饰符则没错误。如:
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int const T1 = a + a;
int const T2 = T1 - T1;
cout << "T2 is " << T2 << endl;
return 0;
}
运行结果为
T2 is 0
const也可以与指针一起使用,有三种方式:指向常量的指针,常指针, 和指向常量的常指针。
(1)指向常量的指针是指一个指向常量的指针变量。如:
const char * name="chen"; //声明指向常量的指针
这个语句的含义为:声明一个名为name的指针变量,它指向一个字符型常量,初始化name为指向字符串“chen”。
const不允许改变指针所指地址中的常量,所以下面的语句是错误的:
name[3]='a'; //错误,不允许改变指针所指的变量
但是,由于name是一个指向常量的普通指针变量,不是常指针,因此可以改变name所指的地址。如:
name="chang"; //合法,可以改变指针所指的地址
该语句就赋给了指针另一个字符串的地址,即改变了name的值。
(2)常指针是指把指针所指的地址,而不是它指向的对象声明为常量。如:
char * const name="chen"; //常指针
这个语句的含义为:声明一个名为name的指针变量,该指针是指向字符型数据的常指针,用“chen”的地址初始化该常指针。
常指针=不能移动的固定指针,即不能改变指针所指的地址,但他所指地址中的数据可以改变。如:
name[3]='a'; //合法,可以改变指针所指的数据
name="chang"; //错误,不能改变指针所指的地址
(3)指向常量的常指针是指这个指针本身不能改变,它所指向的地址中的数据也不能改变。如:
const char * const name="chen";
这个语句的含义是:声明了一个名为name的指针变量,他是一个指向字符型常量的常指针,用“chen”的地址初始化该指针。下面的例子都是错误的:
name[3]='a'; //错误,不能改变指针所指地址中的数据
name="chang"; //错误,不能改变指针所指的地址
注:
①如果用const定义的是整型常量,关键字int可以省略。
②函数的形参也可以用从const声明,用于保证形参在该函数内部不能改动。
4.内联函数
在函数说明之前冠以关键字"inline",该函数就被声明为内联函数,又称内置函数。
目的是为了消除函数调用时的系统开销,以提高运行速度。
本质:代码插入。
说明:
(1)在内联函数中一般不能含有复杂的控制语句,如for语句和switch语句等。
(2)通常只有规模很小(一般为1~5条语句)而使用频繁的函数才定义为内联函数。
5.函数的重载
在C++中,允许两个或两个以上的函数共用一个函数名。
当两个或两个以上的函数共用一个函数名时,称为函数重载。被重载的函数称为重载函数。
重载函数应在函数参数的类型不同,或者参数的个数不同,或者两者兼有之。
代码如下:
#include <iostream>
using namespace std;
int square(int i)
{
return i * i;
}
long square(long l)
{
return l * l;
}
double square(double d)
{
return d * d;
}
int main()
{
int i = 12;
long l = 1234;
double d = 5.67;
cout << i << '*' << i << '=' << square(i) << endl;
cout << l << '*' << l << '=' << square(l) << endl;
cout << d << '*' << d << '=' << square(d) << endl;
return 0;
}
运行结果为:
12*12=144
1234*1234=1522756
5.67*5.67=32.1489
说明:
(1)如果两个函数的参数个数和类型都相同,而只有返回值类型不同,则不允许重载。虽然两个函数的返回值类型不同,但是由于参数类型和个数完全相同,系统无法从函数的调用形式上判断那一个函数与之匹配。
(2)函数的重载与带默认值的函数一起使用时,有可能引起二义性。如:
void Drawcircle(int r=0,int x=0,int y=0);
coid Drawcircle(int r);
当执行以下函数调用时
Drawcircle(20);
无法确定是哪一个函数。
(3)在函数调用时,如果给出的实参和形参的类型不相符,C++编译器会自动地做类型转换工作。若转换成功,则继续执行,否则出现错误。如:
void a(int x);
void a(long x);
如果用下面数据去调用,就会出现不可分辨的错误。
int c=a(5.56);
编译器无法确定将5.56转化为int类型还是long类型。
注:类型转换
C语言类型转换分级别,一般多是:
默认状态:低级向高级转换,级别高低(小到大):int,float,double,(注意char只可以和int之间转换);
若要高级向低级转换:就要用到强制类型转换符!如int(7.7)=7;
6.带有默认参数的函数
C++在说明函数原型时,可为参数指定默认参数值,以后调用此函数时,若省略其中某一参数,C++自动地以默认值作为相应参数的值。
函数原型说明为:
int special(int x=5,float y=5.3);
以下的函数调用都是允许的:
special( ); // x=5, y=5.3
special(25); // x=25, y=5.3
special(100,79.8); // x=100,y=79.8
(1)在声明函数时,所有指定默认值的参数都必须出现在不指定默认值的参数的右边,否则出错。
例如:
int fun(int i, int j=5, int k); ×
可改为:
int fun(int i, int k, int j=5);
2) 在函数调用时,若某个参数省略,则其后的参数皆应省略而采用默认值。不允许某个参数省略后,再给其后的参数指定参数值。
例如不允许出现以下调用:
special( , 21,5); ×
(3)在函数原型中默认参数可以不包含参数的名字
如:
#include<iostream>
using namespace std;
void write( int =5);
void main( )
{
write( );
}
void write(int a)
{ cout<<a; }
7.作用域运算符
如果用两个同名变量,一个是全局的,一个是局部的,那么局部变量在起作用域内具有较高的优先权,他将屏蔽全局变量。
#include<iostream>
using namespace std;
int avar=10; //全局变量avar
int main( )
{ int avar;
avar=25; //局部变量avar
cout<<"local avar ="<<avar<<endl;
cout<<"global avar ="<<::avar<<endl;
return 0;
}
程序运行结果如下:
local avar=25
global avar=10
如果希望在局部变量的作用域内使用同名的全局变量,可以在该变量前加上"::",此时::avar代表全局变量avar,"::"称为作用域运算符。
8.无名联合
无名联合是C++中的一种特殊联合,它在关键字union后面没有给出联合名,它可使一组数据项共享同一内存地址。
9.强制类型转换
C语言中,如果要把一个整型数(int)转换为双精度型数(double),可以使用以下形式:
int i=10;
double x=(double) i;
在C++中,还有提供了另一种格式:
int i=10;
double x=double (i);
10.运算符new和delete
(1)
运算符new用于内存分配的最基本形式为:
指针变量名=new 类型;
如:
int *p;
p=new int;
运算符delete用于释放运算符new分配的空间。基本形式为:
delete 指针变量名;
如:
delete p;
(2)new可在为简单变量分配内存的同时,进行初始化,基本形式为:
指针变量名=new 类型(初值);
如:
int *p;
p=new int(99); //动态分配空间,并将99作为初始值赋给它
使用new可以为数组动态分配内存空间,这时需要在类型名后面缀上数组大小。 如:
char* p=new char[10];
int* op=new int[5][4];
但是,new不能对动态分配的数组存储区进行初始化。
(3)释放动态分配的数组存储区时,可用以下形式:
delete []指针变量名;
(4)使用new动态分配内存时,如果没有足够的内存满足分配要求,则动态分配空间失败,有些编译系统会返回空指针NULL,因此可以对内存的动态分配是否成功进行检查。
代码如下:
#include<iostream>
using namespace std;
int main()
{ int *p;
p=new int;
if (!p)
{
cout <<"allocation failure\n";
return 1;
}
*p=20;
cout<<*p;
delete p;
return 0;
}
若动态分配内存成功,将在屏幕上显示: 20;
若动态分配内存失败,将在屏幕上显示: allocation failure.
11.引用
1.
建立引用的作用是为变量另起一个名字,变量的引用通常被认为是变量的别名。 声明一个引用的格式如下:
类型 &引用名=已定义变量名;
例如:
int i=5;
int &j = i;
这里,声明了一个整数类型的引用j ,用整型变量i对它进行初始化,这时j就可看做是变量i的引用,即是变量i的别名。也就是说,变量i和引用j占用内存的同一位置。当i变化时,j也随之变化,反之亦然。
说明:
(1)对变量声明一个引用,编译系统不给它单独分配存储单元,i和j都代表同一变量单元。
(2)在声明一个引用时,必须立即对它进行初始化,即声明它代表哪一个变量。不能声明完成后再赋值。
例如下述声明是错误的。
int i;
int &j; //错误
j=i;
(3) 为引用提供的初始值,可以是一个变量或另一个引用。如:
int i=5; //定义整型变量
i int &j1=i; //声明j1是整型变量i的引用(别名)
int &j2=j1; //声明j2是整型引用j1的引用(别名)
这样定义后,变量i有两个别名:j1和j2。
(4) 指针是通过地址间接访问某个变量,需要书写间接运算符“*”; 引用是通过别名直接访问某个变量。
每次使用引用时,可以不用书写间接运算符“*”,因而使用引用可以简化程序。
(5) 引用在初始化后不能再被重新声明为另一个变量的引用(别名)。
(6) 尽管引用运算符“&”与地址操作符“&”使用相同的符号,但是它们是不一样的。
引用运算符“&”仅在声明引用时使用。
其他场合使用的“&”都是地址操作符。
例如:
int j=5;
int& i=j; //声明引用i,“&”为引用运算符
i=123; //使用引用i,不带引用运算符
int *pi=&i; // 在此,“&”为地址操作符
cout<<π //在此,“&”为地址操作符
2. 引用作为函数参数
① 用变量做函数参数:传值调用
代码如下:
#include <iostream>
using namespace std;
void swap(int m, int n)
{
int temp;
temp = m;
m = n;
n = temp;
}
int main()
{
int a = 5, b = 10;
cout << "a=" << a << "b=" << b << endl;
swap(a, b);
cout << "a=" << a << "b=" << b << endl;
return 0;
}
② 用指针做函数参数:传址调用
代码如下:
#include <iostream>
using namespace std;
void swap(int *m, int *n)
{
int temp;
temp = *m;
*m = *n;
*n = temp;
}
int main()
{
int a = 5, b = 10;
cout << "a=" << a << "b=" << b << endl;
swap(&a,&b);
cout << "a=" << a << "b=" << b << endl;
return 0;
}
③ 用引用做函数参数:传址调用
代码如下:
#include <iostream>
using namespace std;
void swap(int &m, int &n)
{
int temp;
temp = m;
m = n;
n = temp;
}
int main()
{
int a = 5, b = 10;
cout << "a=" << a << "b=" << b << endl;
swap(a,b);
cout << "a=" << a << "b=" << b << endl;
return 0;
}
注意三者的调用方法
3. 使用引用返回函数值
使用引用可以返回函数的值,采用这种方法可以将该函数调用放在赋值运算符的左边。
代码如下:
#include<iostream>
using namespace std;
int a[ ]={1,3,5,7,9};
int& index(int i) //定义函数返回一个int类型的引用,等价于返回数组元素a[i]
{ return a[i] ;}
int main()
{
cout<<index(2)<<endl;
index(2)=25; //将函数调用放在赋值运算符的左边, 等价于将a[2]赋值为25
cout<<index(2);
return 0;
}
说明:
1.可以建立指针变量的引用,如:
int i=5; //定义整型变量i,初值为5
int *p=&i; //定义指针变量p,指向i
int* &pt=p; //pt是一个指向整型变量的指针变量p的引用
如果输出*pt值,就是*p的值5。
2.可以用const对引用加以限定,不允许改变该引用的值。
例如:
int i=5; const int &a=i; //声明常引用,不允许改变引用a的值
a=3; //错误,企图改变引用a的值
但是这个引用所代表的变量的值可以改变
例如:
i=3; 此时输出的i和a的值都是3。
这一特性在用作函数形参,保护形参值不被改变时很有用的。