【ACM】C++入门

目录

引言

C++过渡

1-1 万能头文件

1-2 cin,cout

1-3 &引用

1-4 字符串

1-5 范围for循环

1-6 构造与重载

1-7 模板

练习

2-1

2-2


引言

        C++博大精深,不过对于算法竞赛,我们只需要使用其中很少的特性。本篇仅针对算法竞赛介绍,帮助C到C++过渡。

C++过渡

1-1 万能头文件

#include<bits/stdc++.h>
using namespace std;

        第一行:在程序前敲上这串,就不用再记头文件了。

        第二行:接下来介绍的函数中,如std::cin,std::cout,以及STL中的std::vector等,需要这行代码以省去“std::”的部分。

        总之记住这两行就对了。

        温馨提醒:仅算法竞赛。未来做项目老老实实敲头文件。

1-2 cin,cout

        这是输入与输出,相比C而言最大的优势是不用再记%d、%s等占位符。

int a, b;

scanf("%d%d", &a, &b);//C版本
cin >> a >> b;//C++版本

printf("%d %d\n", a, b);//C版本
cout << a << " " << b << endl;//C++版本

        cin/cout注意箭头方向。endl可以记忆为“endline”缩写。

1-3 &引用

        C语言在函数内对实参的操作通过指针实现,而C++提供了“引用”。(不觉得没有指针的代码更自然吗)

//C版本
void swap2(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

//C++版本
void swap2(int &x, int &y) {
    int temp = x;
    x = y;
    y = temp;
}

        为什么不叫“swap”?因为C++自带的swap函数不仅可以交换int,double等,甚至还可以交换结构体。我们很快就会学到如何编写这样强大的函数。

1-4 字符串

        C++提供一个可被cin/cout直接读写的字符串类型:string类型。当用cin读取时遇空格视为结束。想读取整行可用getline()。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line;
	while(getline(cin, line)){//相当于C的fgets
		int sum = 0, x;
		stringstream ss(line);//创建"字符串流"(类似于cin)
		while(ss >> x){
			sum += x; 
			cout << sum << endl; 
		}
	}
	return 0;
}

1-5 范围for循环

        通过类似for(int a: b)的形式可以从头到尾访问b容器。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line{"abcde"};
	for(char a : line){
		a = toupper(a);//转大写,tolower()转小写
        cout << a;
	}
    cout << endl;
	cout << line << endl;//看看结果?
	return 0;
}

        需要修改容器中的元素,或者你想避免复杂类型对象的不必要拷贝时,应该使用&。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line{"abcde"};
	for(char &a : line){//使用&
		a = toupper(a);
	}
    cout << line << endl;
	return 0;
}

        不需要修改容器中的元素,且元素类型是复杂类型(如std::string或用户定义的类)时,最好使用const &,可以避免不必要的拷贝。

#include<bits/stdc++.h>
using namespace std;

struct Person {
    string name;
    int age;
};

int main() {
    vector<Person> people = {//vector是变长数组
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35}
    };
    for (const auto &person : people) {
        cout << person.name << " is " << person.age << " years old." << endl;
    }
    return 0;
}

        当然,完全可以使用传统形式:

#include<bits/stdc++.h>
using namespace std; 

int main() {
	string line = "Hello, World!";
	for (size_t i = 0; i < line.length(); ++i) {//对于.length(),.begin等其返回值为size_t类型
		line[i] = tolower(line[i]);
	}
	cout << line << endl; 	
	return 0;
}

1-6 构造与重载

#include<bits/stdc++.h>
using namespace std;

struct Point {
	int x, y;
	// 带有默认参数的构造函数
	Point(int x=0, int y=0) : x(x), y(y) {}//觉得难以理解可以试试y(y),  x(x) 以及 x(y), y(x) 会发生什么
};

// 重载+运算符,使其能够处理Point对象的加法
Point operator+(const Point& A, const Point& B) {//不修改地引用传递参数以避免不必要的复制,特别是对于大型对象。
	return Point(A.x + B.x, A.y + B.y);
}

// 重载<<运算符以输出Point对象
ostream& operator<<(ostream& out, const Point& p) {
	out << "(" << p.x << "," << p.y << ")";
	return out;
}

int main() {
	Point a, b(1, 2);//此时a为(0, 0)
	a.x = 3;
	
	cout << a + b << endl;
	return 0;
}

        上段代码展示了构造函数与重载操作符的部分特性(冰山一角)。看不懂没关系,在未来很长的一段时间内,读者完全可以避开这些用法。在一段时间的沉淀后,欢迎深入研究它们的特性。

1-7 模板

        看一个简单点函数:

int add(int a, int b){
	return a+b;
}

        函数没什么问题,但有局限——double怎么办?我们的Point数组(1-6)怎么办?

        我们稍作修改:

template <typename T>
T add(T a, T b){
	return a+b;
}

        这样,我们就造了一个“万能”函数。

练习

2-1

        函数reverse()可以实现反转。现在你不能直接使用,尝试用所学知识编写相同功能:要求对于一行任意输入,输出其反转后的字符串。

2-2

        完成任意数据类型Point数组(1-6)(同类型)相加。

        提示:Point</*此处可定义类型*/>

int main(){
    Point<int> a(1,2), b(3,4);
    Point<double> c(1.1, 2.2), d(3.3, 4.4);
    cout << a+b << " " << c+d << endl;
    return 0;
}//请补充代码

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值