C过渡C++基础(较详细)

2021/11/6 1:10:07

本文主要是介绍C过渡C++基础(较详细),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

前言

一、C语言和C++的区别

二、输入输出

1.C标准库的移植

2.C++标准输入输出流

三、引用变量

四、函数的区别

五、用户定义类型

六、动态内存分配

七、学生成绩分析

插播一条消息 this 指针

八、class详解

九、默认构造函数

十、运算符重载

十一、string类型和析构函数

十二、派生、继承、虚函数

十三、内联函数

总结


前言

C语言想过渡C++,不想重新学习但又不想囫囵吞枣。这是本人的学习笔记

一、C语言和C++的区别

C++语言是C语言的扩展和增强,由原来的面向过程编程转变成面向对象、通用算法(泛型编程)

由于C++是C语言的扩展,所以C语言程序也是C++程序,原有的.c 程序可以在 .cpp的文件上编译运行。

二、输入输出

1.C标准库的移植

C++标准库中存在着很多C标准库的移植版本:

头文件:

C标准库的头文件xxx.h 基本上变为 cxxx   如下图:

//C语言头文件
#include<stdio.h> /*标准输入输出流函数*/
#include<string.h>
#include<math.h>

//C++头文件
#include<cstdio>
#include<cstring>
#include<cmath>

//例外 malloc 没有变化
#include<malloc.h>

看一下一些简单的实例:

 由此可以看出,适用于C语言的一些函数和操作,在C++中仍然可行。

2.C++标准输入输出流

头文件: iostream  包含C++标准额输入输出流函数

#include<iostream>

输出流函数:cout

输入流函数:cin

输入输出运算符: <<  或  >>  

o<<x,加入o是个对象,x是数据,o<<x的意思是把x的数据输入到对象o中,然后返回的是对象o


看一个实例:

为了防止名字出现冲突,C++语言中设有名字空间,使用某些名字的时候需要标注名字空间,而cout 和 cin 都是在名字空间 std 中,因此,使用的时候必须声明此名字空间,一般来说有三种标注方法。方法如下:


第一种方法:

#include<iostream>
using namespace std;//第一种方法,在使用之前引用此名字空间中的所有
int main()
{
	cout << "hallo world\n";
	cout << 2 + 3 << endl;//endl是换行的意思,作用相当\n
	return 0;
}

第二种方法:

#include<iostream>
using std::cout;    //第二种方法,在使用之前标注:使用std名字空间内的cout
using std::endl:    //第二种方法,使用std名字空间内的endl
int main()
{
	cout << "hallo world\n";
	cout << 2 + 3 << endl;//endl是换行的意思,作用相当\n
	return 0;
}

第三种方法:

#include<iostream>
int main()
{
	std::cout << "hallo world\n";//第三种方法:在使用之前标明出处 格式为std::
	std::cout << 2 + 3 << std::endl;//每次使用都要标注
	return 0;
}

输入输出的实例:


三、引用变量

实际上引用变量就是原来变量的别名,

地址和原变量的地址相同

void SWAP(int a, int b) {
	int c = a;
	a = b;
	b = c;
	cout << &a << endl;
}
void SWAP2(int& x, int& y) {
	int c = x;
	x = y;
	y = c;
	cout<< &x << endl;
}
int main()
{
	int a = 1, b = 5;
	cout << a << '\t' << b << endl;
	cout << &a << endl;

	SWAP(a, b);
	cout << a << '\t' << b << endl;

	SWAP2(a, b);
	cout << a << '\t' << b << '\n';
	return 0;

四、函数的区别

默认形参

函数重载

而下面这种调用方法是错的

 函数模板

五、用户定义类型

string类型

vector 类模板:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
	//vector
	// vector是向量,类似于数组,但可以动态增长
	// vector是类模板,实例化产生一个类
	// 如 vector<int> 产生一个数据类型是 int 的 vector<int> 类(向量)
	// 同样,可以根据 vector<int> 类对象去访问其成员,如成员函数
	// 也可以使用运算符进行运算
	//
	vector<int> k;
	k = { 1,2,3,4,5 };
	
	k.pop_back();//pop_back() 在结尾删除一个元素
	k.push_back(6);//push_back() 在最后添加一个元素
	for (size_t i = 0; i < k.size(); i++)
	{
		cout << k[i] << '-';
	}
	cout << endl;

	//	类似的,还有如下函数
	//	clear()  //清空所有元素
	//	empty() //判断vector是否为空,如果返回true为空
	//	erase() // 删除指定元素

	k.erase(k.begin() + 1);
	for (size_t i = 0; i < k.size(); i++)
	{
		cout << k[i] << '-';
	}
	cout << endl;

	k.resize(3);//resize 重新定义k的大小
	for (size_t i = 0; i < k.size(); i++)
	{
		cout << k[i] << '-';
	}
	cout << endl;

	k.clear();
	if (k.empty())
		return 0;
	for (size_t i = 0; i < k.size(); i++)
	{
		cout << k[i] << '-';
	}
	return 0;
}

iterator 迭代器

int main()
{

	//iterator 是 C++的 迭代器

	vector<int> k = { 1,2,3,4,5, };
	vector<int>::iterator it;//这里创建一个 变量 it 来迭代

	for (it = k.begin(); it != k.end(); it++)
	{
		cout << *it << ' ';
	}
	cout << endl;

	for (it = k.begin(); it != k.end(); )
	{
		if (*it % 2 == 0)
		{
			it = k.erase(it);//删除 2 之后 it 指向 3 了
			//删除之后返回的是下一个元素的位置
		}
		else it++;
	}
	cout << endl;
	

	k = { 0,1,2,3,4,5,6,7,8,9, };

	it = k.begin() + 2;
	vector<int>::iterator it2 = k.end();
	k.erase(it, it2);
	for (it = k.begin(); it != k.end(); it++)
	{
		cout << *it << ' ';
	}

	return 0;
}

六、动态内存分配

int main()
{
	//动态内存分配
	//new用来申请新的内存块,delete用来释放
	//数组的话用delete[]
	int* p = new int[4];
	

	for (size_t i = 0; i < 4; i++)//初始化
		p[i] = i;
	for (size_t i = 0; i < 4; i++)//遍历输出
		cout << p[i] << '\t';
	cout << endl;

	char* s = (char*)p;
	char ch = 'A';
	int n2 = 4 * (sizeof(int) / sizeof(char));

	for (int i = 0; i < n2; i++)//初始化
		s[i] = ch + i;
	for(int i = 0; i < n2; i++)//遍历输出
		cout << s[i] << ' ';
	cout << endl;
	

	delete[] s;

	return 0;
}

七、学生成绩分析

struct student {
	string name;
	double score;
	void print();//函数声明
};
void student::print() //注意,函数实现在结构体外面,应该标注名字空间
{
	cout << name << ' ' << score << endl;
}

int main()
{
	vector<student> st;

	while (1) {
		student stu;
		cout << "请输入姓名  成绩" << endl;
		cin >> stu.name >> stu.score;

		if (stu.score < 0)
			break;

		st.push_back(stu);
	}
	for (size_t n = 0; n < st.size(); n++) {//遍历查看输入的数据
		st[n].print();
	}

	//vector<student>::iterator it;
	//it = st.begin();
	//it->print();

	//下面输出最大,最小,以及平均数
	int max = 0;
	int min = 0;
	double average = 0;

	for (size_t n = 0; n < st.size(); n++) {
		average += st[n].score;
		if (st[max].score < st[n].score)
			max = n;
		if (st[min].score > st[n].score)
			min = n;
	}

	st[max].print();
	st[min].print();
	cout << average / st.size() << endl;

	return 0;
}

插播一条消息 this 指针

struct student {
	string name;
	double score;

	void print() { 
		cout << name << '\t' << score << endl; 
	}

	//this指针
	//成员函数内部隐含一个this指针
	//实际上是
	void print() {
		cout <<this->name << '\t' <<this->score << endl;
	}
};

八、class详解

基本运用

//class 和 struct 的区别
//struct 内部的成员默认是公开的(public)
//class 内部的成员默认的是私有的 (private)

class student {
private:
	string name;
	double score;
	
public:
	void print() { cout << name << '\t' << score << endl; }

	//如何在外部访问?
	string get_name() { return name; }
	double get_score() { return score; }

	//如何在外部修改?
	void set_name(string s) { name = s; }
	void set_score(double s) { score = s; }
};

int main()
{
	student std;
	std.set_name("Li Hua");
	std.set_score(98.7);

	cout << std.get_name() << '\t' << std.get_score() << endl;
	std.print();

	return 0;
}

九、默认构造函数

在class结构类型内部存在一个默认构造函数

class student
{
    string name;
    double score;
public:
    student(){};//默认构造函数是不带任何形参的

    student(string n, double s)//这个就不是默认构造函数
    {
        name = n;
        score = s;
    }
}

int main()
{
    student stu;//在定义变量的时候,调用默认构造函数。

    student stus[4];//定义数组的时候 如果没有默认构造函数会出错
    return 0;
}

十、运算符重载

运算符重载
输入输出 <<  >> 运算符只能在class外部重载
下标运算符 [] 只能内部实现
加减乘除 外部内部都可 只是实现方式不同

// 运算符重载
// 输入输出 <<  >> 运算符只能在class外部重载
// 下标运算符 [] 只能内部实现
// 加减乘除 外部内部都可 只是实现方式不同
class point {
	double x, y;
public:
	point() {};//这个是默认构造函数

	//加法运算符的内部实现
	point operator+(const point q) {
		return point(this->x + q[0], this->y + q[1]);
	}

	//下标运算符重载(只可输出)
	double operator[](int i) const{
		if (i == 1) return y;
		else if (i == 0) return x;
		else throw "下标非法\n";
	}

	//下标运算符重载(可以输出,也可以修改)
	double& operator[](int i) {
		if (i == 1) return y;
		else if (i == 0) return x;
		else throw "下标非法\n";
	}

	//自己的构造函数,用来初始化
	point(double x1, double y1)//这个不是默认构造函数
	{
		x = x1;
		y = y1;
	}

	//友元函数
	friend ostream& operator<<(ostream& o, point s);
	friend istream& operator>>(istream& in, point& s);
};


//运算符 << 重载
ostream& operator<<(ostream& o, point s) {
	cout << s.x << '-' << s.y << endl;
	return o;
}

//运算符 >> 重载
istream& operator>>(istream& in, point& s) {
	cin >> s.x >> s.y;
	return in;
}

#if 0
//加法运算符的外部定义
point operator+(const point p, const point q) {
	return point((p[0] + q[0]), (q[1] + p[1]));
}
#endif

int main() 
{
	//普通下标运算符的使用
	point p(2, 3);
	point pp[3] = { {1,1},{2,2,},{3,3,} };
	cin >> p;
	cout << p << endl;
	cout << pp[0] << endl;

	//下标运算符重载
	point p(2, 10);
	cout << p;
	cout << p[0] << ',' << p[1] << endl;//实际上是p.operator[](0); p.operator[](1); 
	p[0] = 0;
	p[1] = 1;
	cout << p;

	//加法 + 运算符重载
	point p(1, 2), q(5, 6);
	cout << p << q;
	cout << p + q; // 内部 p.operator+(q);  外部 p.operator+(p, q)

	return 0;
}

十一、string类型和析构函数

class String {
	char* date;//C风格的字符串
	int n;//字符的个数

public:
	~String() {//析构函数
		if (date)
			delete[] date;
		cout << n << "析构函数\n";
	}
#if 1
	String(String& s) {//默认拷贝构造函数  硬拷贝
		cout << "拷贝构造函数\n";
		date = new char[s.n + 1];
		n = s.n;
		for (int i = 0; i < n; i++)
			date[i] = s[i];
		date[n] = '\0';
	}
#endif

	String(const char* s=0) {//构造函数
		cout << "构造函数\n";
		if (s == 0) {
			cout << "s==0\n";
			date = 0;
			n = 0;
			return;
		}
		else {
			const char* p = s;
			while (*p != '\0') p++;
			n = p - s;
			date = new char[n+1];

			for (int i = 0; i < n; i++)//初始化 赋值
				date[i] = s[i];
			date[n] = '\0';
		}
	}
	char operator[](int i)const {//用来访问
		if (i < n && i >= 0)
			return date[i];
		else throw"下标非法!\n";
	}
	char& operator[](int i) {//用来修改
		if (i < n && i >= 0)
			return date[i];
		else throw"下标非法!\n";
	}
	int size() { return n; }//返回字符个数

	friend ostream& operator<<(ostream& o, String s);
};

ostream& operator<<(ostream& o, String s) {
	for (int i = 0; i < s.size(); i++) {
		cout << s[i];
	}
	return o;
}

void f()
{
	String str1, str2("hallo world");
	cout << "在拷贝之前\n";
	str2[1] = 'E';
	cout << "在拷贝之后\n";
#if 1
	str2[6] = 'W';
	
	cout << str2 << endl;//拷贝构造函数
	String s3 = str2;//拷贝构造函数
	s3[0] = 'o';
	cout << str2 << endl;//拷贝构造函数
	cout << s3 << endl;//拷贝构造函数
#endif
}

int main() {
	f();
}

十二、派生、继承、虚函数

//继承 Inheritance 和 派生 derivation :一个派生类(derived class)
//从一个或多个父类(parent class)/ 基类(base class)继承,
//即继承父类的属性和行为,但也有自己的专属属性

class Employee {
	string name;
public:
	virtual void print() {//virtual是虚函数的关键字
		cout << name << endl;
	}
	Employee(string s = "no_Name") {
		name = s;
	}
	string get_name() {
		return name;
	}
};

//注意派生的格式  在后面加上:基类
class Manager :public Employee{//manager 是 employee的派生
	//此处继承employee的name
	int level;
public:
	Manager(string n, int l) :Employee(n), level(l) {}
	void print();
};

//外部实现类对象 注意格式
void Manager::print() {
	cout << get_name() << '\t' << level << endl;
}


//也可以从多个类派生出一个类
class One {

};
class Two {

};
//此处注意格式,继承类的后边要加上:public基类 如果继承多个基类 则中间用 ,隔开
class Multiple :public One, public Two {

};

int main()
{
	string name;
	int lev;
	char sss;
	Employee* arr[10];
	int num = 0;
	cout << "请输入命令,m表示经理,e表示雇员\n";
	while (cin >> sss) {
		if (sss == 'm' || sss == 'M') {
			cout << "请输入姓名和级别\n";
			cin >> name >> lev;
			Manager* p = new Manager(name, lev);
			arr[num] = p;
			num++;
		}
		else if (sss == 'e' || sss == 'E') {
			cout << "请输入姓名\n";
			cin >> name;
			Employee* p = new Employee(name);
			arr[num] = p;
			num++;
		}
		else break;
		cout << "请输入命令\n";
	}
	for (int i = 0; i < num; i++) {
		arr[i]->print();
	}
	return 0;
}

十三、内联函数

//内联函数 关键字:inline
// 对于不包含循环的函数,可以使用内联函数,
// 编译时 编译器直接用代码替换 不创建函数展开 可以减少调用开销
inline double distance(double a, double b)
{
	return sqrt(a * a + b * b);
}

int main() {
	cout<<distance(1, 2);
	//实际上是cout<<sqrt(a * a + b * b);

	return 0;
}

总结

C过渡C++看似简单,但其实还是要熟悉从面向过程到面向对象编程的转变,这个作文本人的一个学习笔记,应该有很多不足、不完善的地方,努力学习ing。



这篇关于C过渡C++基础(较详细)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程