C++起步(一)

输入

当一次键盘输入结束时(按下回车)会将输入的数据(包括空白字符,换行符)存入输入缓冲区,当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入。

cin

忽略开头的所有空白字符 (空格,换行符,制表符等)
读取直至再次遇到空白字符 (空白字符不会读取)
测试:

    char a[10],b[10];  
    char c,d;
    cin>>a>>b>>c>>d;  
    cout<<a<<"///"<<b<<"///"<<c<<"///"<<d<<endl;

输入:空格空格空格45空格空格空格换行空格空格空格98换行空格空格15
输出:45///98///1///5

cin.get();

可接收单个字符,包括换行 空格等。
对字符数组:

	char c[10],d;
	cin.get(c,n);
	当输入的字符足够长时,
	只会读取n-1个字符,放到 c 里。当n=10,c[10]里是'\0',c是字符串。 当n=11,读取10个字符放到 c 里,此时c[10]不再是'\0'
	当n>11,仍然是读取 n-1 个字符,但只会将前10个字符放到 c里,余下的虽被读取,但不赋给任何变量
	
	当输入的字符长度小于n-1,将其全部读取。回车符不会读取 之后如果再有一条cin.get(d); 会将回车符读到

C++中cin、cin.get()、cin.getline()、getline()、gets()

cin.sync();

清空输入缓冲区
再次使用 cin 去读取 数据时,它就只能等待从键盘输入了,因为此时 输入缓冲区为 空。

简单的格式控制

先包含#include<iomanip>

int main(){
	cout<<setfill('*')<<setw(5)<<setprecision(3)<<3.1415;
}	// setw(n)设置字段的宽度 只对紧接着的输出产生作用。 当 n>要输出的字段长度时,才会起作用,默认以空格填充,可以用setfill来设置其他填充符号
//setprecision()是设置有效数字位数,舍去的时候是四舍五入
// ends 是空格
int main( void ){   
	const double value = 12.3456789;
    cout<<"第一:"<<ends<<12.3456789<<endl; // 默认是最多6位有效数字,有效位不足6位的不受影响,12.30会输出12.3 
    cout<<"第二:"<<ends<<setprecision(4)<<value<<endl; // 4位有效数字 
    cout<<"第三:"<<ends<<setprecision(8)<<value<<endl; // 8位有效数字 
    cout<<"第四:"<<fixed<<setprecision(4)<<value<<endl; // 加上了fixed,意思是小数点后保留4位 
    cout<<"第五:"<<value<<endl; // fixed和setprecision的作用还在,依然显示12.3457
    cout.unsetf( ios::fixed ); // 去掉了fixed,变成4位有效数字
    cout<<"第六:"<<value<<endl;
    cout.precision( 6 ); // 恢复成原来的样子,输出为 12.3457
    cout<<"第七:"<<value<< endl;	
	cout<<"第八:"<<fixed<<value<<endl; // 小数点后六位 
}

动态内存分配

二者等价
	int *p=new int;			// new int 返回 int *类型,动态分配出 sizeof(int)字节的空间,将起始地址 赋给 p。
	int *p=(int*)malloc(sizeof(int));		// int *p=new int(10);  *p 的值初始化为 10
进行释放
	delete p;
二者等价
	int *p=new int[20];   // new int[20] 也是返回 int *类型
	int *p=(int*)malloc(sizeof(int)*20);
进行释放
	delete []p;

内联函数

在函数定义前面 加 inline 关键字
调用函数的语句是有时间开销的,为了减少函数调用的开销,引入内联函数。
在对内联函数进行调用时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的语句,提高运行效率。

inline int max(int a,int b){
	return a>b? a:b;
}
定义在class 内的函数,自动成为 inline候选人,由编译器决定是否最终为 inline

函数重载

几个函数名字一样 , 参数个数/参数类型 不同

函数的缺省参数

定义函数的时候可以让 最右边的连续若干个参数有缺省值。

void func(int x,int y=2;int z=3){
	...
}

类和对象起步

一个类:成员变量 成员函数。
一个类的成员函数在内存里只有一份,被所有对象所共用。对象只包含成员变量,不包含成员函数。

对象所占用的内存空间等于所有成员变量的大小之和。

使用类的成员变量和成员函数

访问范围关键字:
private:私有成员,只可以被 成员函数 友元函数 访问
public:公有成员,可在任何地方访问
protected:保护成员,成员函数 友元函数 子类的成员函数可以访问当前对象的
没加的话,默认是 private

class Employee{
	private:
		char szName[30];
	public:
		int salary;
		void setName(char *name);
		void getName(char *name);
		void averageSalary(Employee e1,Employee e2); 
};
void Employee::setName(char *name){
	strcpy(szName,name);
}
void Employee::getName(char *name){
	strcpy(name,szName);
}
void Employee::averageSalary(Employee e1,Employee e2){
	cout<<e1.szName;		// OK 访问 同类 其他对象的私有成员,因为这是在成员函数里
	salary=(e1.salary+e2.salary)/2;
}
int main(){
	Employee e;
//	strcpy(e.szName,"Tom 1234567");		Error,私有成员只可在成员函数里访问 
//  main 并不是 Employee 类的成员函数
	e.setName("Tom");
	e.salary=5000;
	return 0;
}

构造函数:Complex(double r,double i)

名字与类名相同,没有返回值
作用:对象生成,自动调用构造函数

类里没写构造函数,编译器会生成一个默认的无参数的构造函数(不做任何操作)
类里已经写了构造函数,编译器就不再生成无参的默认构造函数了

一个类可以有多个构造函数。

class Complex{
		Complex(double r,double i=0){
		}
};
//Complex *c1=new Complex; //Error ,没有提供构造函数的参数 
Complex *c1=new Complex(3);  // OK 
//Complex c2;  // Error, 没有提供构造函数的参数 
Complex c2(2); // OK 

构造函数在对象数组里如何起作用:

class Test{
	public:
		Test(int n){
			cout<<"采用了第一种构造函数"<<endl; 
		}
		Test(int n,int m){
			cout<<"采用了第二种构造函数"<<endl; 
		}
		Test(){
			cout<<"采用了第三种构造函数"<<endl; 
		}
};

int main(){
	Test array1[3]={1,Test(1,2)};
// array1[0]的参数是:1, array1[1]的参数是 1和2, array1[2]没有参数 
// 数组里是三个对象
	cout<<"-------------"<<endl; 
	Test *pArray[3]={new Test(4),new Test(1,2)};
// pArray[0] 的参数是 4, pArray[1]的 参数是 1和2 
// 生成了两个对象, pArray[2] 只是一个未经初始化的指针。 
}

运行输出:
采用了第一种构造函数
采用了第二种构造函数
采用了第三种构造函数
-------------
采用了第一种构造函数
采用了第二种构造函数

复制构造函数:Complex(const Complex & c)

用一个已经存在的对象去初始化新对象

class Complex{
	Complex(const Complex &c){				// 只有一个参数, 参数是对同类对象的引用
	}
}; 

如果没有定义复制构造函数,编译器生成默认的复制构造函数。
复制构造函数起作用的三种情况:

1.用一个对象 去初始化同类的另一个对象
Complex c2(c1);
Complex c2=c1;		// 初始化语句
注意 如果是 Complex c1,c2; c1.n=5;
c2=c1; // 赋值语句  并不会调用复制构造函数
2.函数有一个参数是类A的对象时,该函数被调用时,类A的复制构造函数 将被调用
void Func(A a1){
}
int main(){
	A a2;
	Func(a2);
}
3.函数的返回值是类A的对象时,函数返回时,A的复制构造函数被调用

对于参数是对象的函数,调用时会引发调用复制构造函数,时间效率比较大
可以考虑采用常量引用参数,不会引发复制构造函数,如:

void func(Complex obj){
}
改成
void func(const Complex &obj){
	// 函数中 任何 试图改变 obj的值的语句都将是非法的。
}

析构函数:~Complex()

名字与类名相同(前面多一个 ~),无参数,无返回值,一个类只有一个析构函数

class Ctest{
public:
	~Ctest(){
		cout<<"析构函数被调用"<<endl;
	}
};
Ctest array[2];
int main(){	
}
运行输出:
析构函数被调用
析构函数被调用
// 在对象消亡时自动被调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值