cout 输出、cin 输入
-
C++中的输入与输出可以看做是—连串的数据流:
- 输入:可视为从文件或键盘中输入程序中的一串数据流
- 输出:可视为从程序中输出—连串的数据流到显示屏或文件中
-
编写C++程序时如果需要使用输入输出,则需要包含头文件
iostream(lnput Output Stream)//输入输出流
,它包含了用于输入输出的对象:- cin :标准输入对象,支持对多个变量连续输入。
- cout :标准输出对象,能够连续输出
- cerr :标准错误对象
- cout和cin 都是C++的内置对象,而不是关键字。C++库定义了大量的类(Class) ,程序员可以使用它们来创建对象,cout和cin 就分别是ostream和istream类的对象(由标准库的开发者提前创建好,可以直接使用)。这种在C++中提前创建好的对象称为内置对象。
- 使用cout进行输出时要紧跟<<运算符,使用cin进行输入时要紧跟>>运算符,这两个运算符可以自行分析所处理的数据类型,因此无需像使用scanf和printf那样给出格式控制字符串。
-
endl(end of line)
表示换行,与C语言里的\n作用相同。也可以用\n来替代endl :。cout<<"Please input an int number : \n";
C++允许在代码任何地方声明局部变量。
const修饰符
const定义常量的修饰符
const float UI = 3.14;
const 可以与指针一起使用,它们的组合情况复杂,可归纳为3种:指向常量的指针、常指针和指向常量的常指针。
● 指向常量的指针:一个指向常量的指针变量。指针指向的数据不可变
const char* pc = "abcd";
//该方法不允许改变指针的变量,即
pc[3] = 'x'; //是错误的
//但是,由于pc是一个指向常量的普通指针变量,不是常指针,因此可以改变pc所指的地址,例如
pc = "ervfs";
//该语句赋给了指针另一个字符串的地址,改变了pc的值。实际就是通过改变地址修改该常量的值
● 常指针:将指针变量所指的地址声明为常量。指针本身的值不可变
char* const pc = "abcd";
//创建一个常指针,一个不能移动的固定指针,可改变内容,如:
pc[3] = 'x';
//但不能改变地址,如:
pc = 'dbc'; //不合法
可以修改常量的值,但是不能改变常量的指针的值
● 指向常量的常指针:这个指针所指的地址不能改变,它所指的内容也不能改变
const char* const pc = "aaa";
//直接固定,啥也不能变
1. 如果用const定义整型常量,关键字可以省略。const int a 同const a
2. 常量一旦被建立,在程序的任何地方都不能再更改。
3. 与#define不同,const定义的常量可以有自己的数据类型。
4. 函数参数也可以用const说明,用户保证实参在该函数内不被改动。
void型指针
void通常表示无值,但将void作为指针的类型时,它却表示不确定的类型。这种void型指针是一种通用型指针,也就是说任何类型的指针值都可以赋值给void类型的指针变量。
需要指出的是,这里说的void型指针是通用指针,是指它可以接受任何类型的指针的赋值,但对已获值的void型指针,对它进行再处理,如输出或者传输指针值时,则必须再进行显式类型转换,否则会出错。
void* pc;
int i = 123;
char c = 'a';
pc = &i;
cout << pc << endl; //输出指针地址006FF730
cout << *(int*)pc << endl; //输出值123
pc = &c;
cout << *(char*)pc << endl; //输出值a
内联函数
在函数名前冠以关键字inline,该函数就被声明为内联函数。
每当程序中出现对该函数的调用时,C++编译器使用函数体中的代码插入到调用该函数的语句之处,同时使用实参代替形参,以便在程序运行时不再进行函数调用。
引入内联函数主要是为了消除调用函数时的系统开销,以提高运行速度。
说明:
● 内联函数在第一次被调用之前必须进行完整的定义,否则编译器将无法知道应该插入什么代码
● 在内联函数体内一般不能含有复杂的控制语句,如for语句和switch语句等
● 使用内联函数是一种空间换时间的措施,若内联函数较长,较复杂且调用较为频繁时不建议使用
#include <iostream>
using namespace std;
inline double circle(double r)
{
double PI = 3.14;
return PI * r * r;
}
int main(){
for (int i = 1;i <= 3;i++)
cout << "r=" << i << " area = " << circle(i) << endl;
return 0;
}
使用内联函数替代宏定义,能消除宏定义的不安全性
带有默认参数值的函数
当进行函数调用时,编译器按从左到右的顺序将实参与形参结合,若未指定足够的实参,则编译器按顺序用函数原型中的默认值来补足所缺少的实参。
void init(int x = 5,int y = 10);
init(100,19); //100,19
init(25); //25, 10
init(); //5,10
● 在函数原型中,所有取默认值的参数都必须出现在不取默认值的参数的右边。
例如:int fun(int a,int b,int c=111);
● 在函数调用时,若某个参数省略,则其后的参数皆应省略而采取默认值。不允许某个参数省略后,再给其后的参数指定参数值。
函数重载
在C++中,用户可以重载函数。这意味着,在同一作用域内,只要函数参数的类型不同,或者参数的个数不同,或者二者兼而有之,两个或者两个以上的函数可以使用相同的函数名。
#include <iostream>
using namespace std;
int add(int x,int y)
{
return x + y;
}
double add(double x,double y)
{
return x + y;
}
int add(int x,int y,int z)
{
return x + y + z;
}
int main()
{
int a = 3,b = 5,c = 7;
double x = 10.33,y = 3.1415;
cout << add(a,b) << endl;
cout << add(x,y) << end;
cout << add(a, b, c) << endl;
return 0;
}
说明:
● 调用重载函数时,函数返回值类型不在参数匹配检查之列。因此,若两个函数的参数个数和类型都相同,而只有返回值类型不同,则不允许重载。
int mul(int x,int y);
double mul(int x,int y);
● 函数的重载与带默认值的函数一起使用时,有可能引起二义性。
void Draw(int r = 0,int x = 0,int y = 0);
void Draw(int r);
Draw(20);
● 在调用函数时,如果给出的实参和形参类型不相符,C++的编译器会自动地做类型转换工作。如果转换成功,则程序继续执行,在这种情况下,有可能产生不可识别的错误。
void f_a(int x);
void f_a(long x);
f_a(20.85);
作用域标识符"::"
通常情况下,如果有两个同名变量,一个是全局的,另一个是局部的,那么局部变量在其作用域内具有较高的优先权,它将屏蔽全局变量。
如果希望在局部变量的作用域内使用同名的全局变量,可以在该变量前加上"::“,此时::value代表全局变量value,”::"称为作用域标识符。
int value; //全局变量
int main(){
int value;//局部变量
value = 100;
::value = 1000;
}
强制类型转换
可用强制类型转换将不同类型的数据进行转换。
int i = 10;
double x = double(i); //也可以(double)i这样,不过不建议
new和delete运算符
程序运行时,计算机的内存被分为4个区,程序代码区、全局数据区、堆和栈。
其中,堆可由用户分配和释放。
C++提供了运算符new和delete来做动态内存管理。
指针变量名 = new 类型
int *p;
p = new int;
delete 指针变量名
delete p;
说明:
● 用运算符new分配的空间,使用结束后应该用也只能用delete显式释放,否则这部分空间将不能回收而变成死空间。
● 在使用运算符new动态分配内存时,如果没有足够的内存满足分配要求,new将返回空指针(NULL)。
● 使用运算符new可以为数组动态分配内存空间,这时需要在类型后面加上数组大小。
指针变量名 = new 类型名[下标表达式];
int *p = new int[10];
释放动态分配的数组存储时,可使用delete运算符
delete []指针变量名;
delete p;
● new可在位简单变量分配空间的同时,进行初始化
指针变量名 = new 类型名(初值);
int *p;
p = new int(99);
···
delete p;
引用
引用(reference)是C++对C的一个重要扩充。
变量的引用就是变量的别名,因此引用又称别名。
类型 &引用名 = 已定义的变量名
引用与其所代表的变量共享同一内存单元,系统并不为引用另外分配存储空间。
实际上,编译系统使引用和其代表的变量具有相同的地址。
int main(){
int i = 10;
int &j = i;
cout << "i = " << i << "j = " << j << endl;
cout << "i的地址为 " << &i << endl;
cout << "j的地址为 " << &j << endl;
return 0;
}
//上面代码输出i和j的值相同,地址也相同。
说明:
- 引用并不是一种独立的数据类型,它必须与某一种类型的变量相联系。在声明引用时,必须立即对它进行初始化,不能声明完成后再赋值。
- 为引用提供的初始值,可以是一个变量或者另一个引用。
- 指针是通过地址间接访问某个变量,而引用则是通过别名直接访问某个变量。
- 引用可作为函数参数、使用引用返回函数值
- 对引用进一步说明:
- 不允许建立void类型的引用
- 不能建立引用的数组
- 不能建立引用的引用。不能建立指向引用的指针。引用本身不是一种数据类型,所以没有引用的引用,也没有引用的指针。
- 可以将引用的地址赋值给一个指针,此时指针指向的是原来的变量。
- 可以用const对引用加以限定,不允许改变该引用的值,但是它不阻止引用所代表的变量的值。