Daya Jin's Blog Python and Machine Leaning

C++ Basic

2019-09-02


Base

关于标准IO的补充。cin使用空白来确定结束位置,这意味着cin每次只能读取单个单位的字串,并且会把空白符留在输入缓冲区。

#include <iostream>    // IO流头文件
#include <string>

using namespace std;    // 标准命名空间

int main()
{
	/*数据类型*/
	int i = 10;
	float f = 3.14f;
	bool flag = true;
	char c = 'A';    // 单引号表字符
	char chs[5] = { 'a','b','c' };    // 字符数组,会被看作是无结束符的字串
	string s = "abc";    // 双引号表字串,隐含'\0'结束符
	int arr[4] = { 0,1,2,3 };    // 数组名作用:统计数组长度,获取数组首地址
	cout << sizeof(arr)/sizeof(arr[0]) << endl;    // 静态数组的长度

	/* 标准IO */
	float r = 0; float pi = 3.14;
	cout << "enter the r:";    // cout: 标准输出
	cin >> r;    // cin: 标准输入
	cout << pi * r * r << endl;    // endl: 插入换行符并刷新缓冲区

	/*判断*/
	if (1 + 1 == 2)
		;
	else
		;

	char tmp = 'b';
	switch (tmp)
	{
	case 'a':
		break;
	case 'b':
		break;
	default:
		break;
	}

	/*三目运算符*/
	int a = 0; int b = 1;
	cout << (a < b ? 'a' : 'b') << endl;
	(a < b ? a : b) = 9;    // 三目运算符左值时,C++会取地址
	cout << a;

	/*循环*/
	int nums[3] = { 0,1,2 };
	for (int i = 0; i < 3; i++)
		cout << nums[i] << ' ';
	cout << endl;

	return 0;
}

其他数据类型

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>

using namespace std;

int main(void)
{
	string s1, s2;
	s1 = "prefix";
	s1.size();
	s1[0] = 'A';     // string类支持直接修改
	getline(cin, s2);
	cout << s1 + s2 << endl;    // 拼接
	if (s1 < s2);    // 基于ASCII的比较

	vector<int> v1 = { 0,1,2 };
	v1.push_back(3);
	int tmp=v1.back();    // 取最后一个元素
	v1.pop_back();    // 删除最后一个元素
	sort(v1.begin(), v1.end());
	for (int i = 0; i < v1.size(); i++)
		cout << v1[i] << endl;

	set<int> s;
	s.insert(1); s.insert(2); s.insert(2);
	s.erase(1);
	if (s.find(2) != s.end());    // 存在性判断

	unordered_map<char, int> m;
	m['a'] = 1;
	m['z'] = 26;
	if (m.find('b') != m.end());    // 存在性判断

	return 0;
}

指针与引用

指针指向内存地址,引用相当于别名,有着类似指针的性质。引用必须初始化,且不可更改。实际上引用本质上就是指针常量。

int i = 1;
int* p = &i;    // 整形指针p指向整形变量i的地址
int& r_i = i;    // 创建i的引用
int* const r = &i;    // 引用的本质,指针常量
*p += 1;    // p指向的地址的值+1
r_i += 1;    // 引用+1,即原始数据+1
cout << i << ' ' << p << endl;

int func(const int& x) {
	// 引用的常见使用场景:使用常量引用实现只读参数
	return x * x;
}

p += 1;    // p值+1,即地址偏移一个单位
cout << i << ' ' << p << endl;

int arr[3] = { 0,1,2 };
int* ap = arr;    // 数组名即数组首元素的地址
cout << arr << ' ' << ap << endl;
cout << *(ap + 1) << ' ' << arr[1] << endl;

类型转换与常量

*用作指针创建时,指针指向的类型永远在其左侧且是完整类型,如int*表示指针指向int型;而const关键字永远限定其右侧的类型或变量名,如const int表示常量整形;当两者混用时,记住修饰规则即可,如const int*表示指向常量整形的指针,int* const p表示指向int的指针,且指针p是常量。

int a = 1;
float b = 0.1;
bool t = true;
bool f = false;
a + b == 1.1;    // int->float自动提升
b + f == 0.1;    // true=1, flase=0

const int m = 0;
const int* p_i = &m;    // 指向const int的指针
m += 1; *p_i += 1;    // error,常量无法被修改
p_i += 1;    // 指针可以修改

int i = 1;
int* const p_c = &i;    // 指向int的指针且p_c为常量
p_c += 1;    // error,指针常量无法被修改
i += 1; *p_c += 1;     // 变量可以修改

const int* const p = &m;    // 指向const int的指针且指针p为常量
p += 1; *p += 1;    // error,常量无法修改,指针常量也无法修改

结构体

#include <iostream>

using namespace std;

struct MyStruct
{
	int i;
	float f;
	char c;
	bool b;
};

int main()
{
	MyStruct s = { 1,0.5,'a',true };
	MyStruct* p = &s;

	/*结构体成员的访问方式*/
	cout << p->i << ' ' << p->f << ' ' << p->c << ' ' << p->b << endl;

	// 结构体数据类型对齐
	cout << sizeof(p->i) << '\t' << sizeof(p->f) << '\t'
		<< sizeof(p->c) << '\t' << sizeof(p->b) << '\t' << sizeof(s) << endl;

	return 0;
}

函数

#include <iostream>

using namespace std;

bool isEven(const int num)
{
	return num % 2 == 0;
}

void plusone(int* p_num)
{
	*p_num += 1;
}

/*函数重载,同名函数支持不同的输入*/
void f(int num)
{
	cout << "f_int" << endl;
}
void f(double num)
{
	cout << "f_double" << endl;
}

/*递归*/
int fact(int num = 1)    // C++支持默认参数
{
	if (num < 2)
		return num;
	else
		return num * fact(num - 1);
}

int main()
{
	int num = 1;
	if (isEven(num))
		cout << "is" << endl;
	else
		cout << "not" << endl;

	plusone(&num);
	cout << num << endl;

	f(1); f(1.0);

	cout << fact(3) << endl;
	return 0;
}

类与对象

访问控制的三种权限:

  • public:公有,外部可访问;
  • protected:保护,外部不可访问,继承可访问;
  • private:私有,外部不可访问,继承不可访问。

下面示例定义一个自定义类C

C.h里声明类:

class C
{
	const double pi=3.14;
	double r;

public:
	C(double r);    // 构造函数
	C(const C& c);    // 拷贝构造函数,复制对象
	~C();    // 析构函数
	void setR(double x);
	double getS(void);
	C& plus(void);    // 半径增加1
};

C.cpp里实现类:

#include "C.h"

/*需要用作用域解析符来标识所属的类*/
C::C(double x) {
	this->r = x;    // this指针指向的是对象自身,相当于Python中的self
}

C::C(const C& c) {
	this->r = c.r;
}

C::~C() {}

void C::setR(double x) {
	this->r = x;
}

double C::getS(void) {
	return this->pi * this->r * this->r;
}

/*类方法可以支持链式调用,需要返回自身的引用*/
C& C::plus(void) {
	this->r += 1;
	return *this;
}

主程序main.cpp

#include<iostream>
#include "C.h"
using namespace std;

int main(void) {
	C c0 = C(0);
	C c1 = C(c0);
	c1.setR(1);
	cout << c1.getS() << endl;
	c1.plus().plus();
	cout << c1.getS() << endl;
	return 0;
}

C++中类与结构体是相似类型,唯一区别在于struct默认public权限而class默认private权限。C++中保留结构体的设计仅仅是为了兼容C语言。

继承

#include<iostream>
#include<string>
using namespace std;

class BasePage {
protected:
	string header = "HTML Header";
	string footer = "HTML Footer";

public:
	void show(void) {
		cout << this->header << "\t" 
			<< this->footer << endl;
	}
};

class DetailPage :public BasePage {
	string info = "Detail Info";

public:
	void show(void) {    // 子类会重写父类的同名函数
		cout << this->header << "\t"
			<< this->info << "\t"
			<< this->footer << endl;
	}
};

int main(void) {
	DetailPage p1;
	p1.show();
	return 0;
}

文件IO

#include<iostream>
#include<fstream>
using namespace std;

int main(void) {
	fstream fd_w("tmp.txt", ios::out | ios::binary);
	if (fd_w.is_open()) {
		char info[] = "hello\n";
		fd_w.write(info, sizeof(info));
	}
	fd_w.close();

	fstream fd_r("tmp.txt", ios::in | ios::binary);
	char buf[512] = { 0 };
	if (fd_r.is_open()) {
		while (!fd_r.eof()) {
			fd_r.read(buf, 512);
			cout << buf;
		}
	}
	fd_r.close();

	return 0;
}

Similar Posts

上一篇 Operating System

下一篇 C++ Advance

Content