C++ | C++ 概览 基础知识 | 01
一、基本概念
1.1 类型、变量和算术运算
基本类型:bool,char,int,double
算术类型: +,++,-,—,*,/,%,=,==,+=,-=,*=,/=
1.2 常量
- const 用于说明接口,不修改值。
- constexpr 用于说明常量,编译时求值。
constexpr double square(double x) {
return x * x;
}
1.3 检验和循环
Check(检查)
if ... else 语句:
cout << "Do you want to proceed(y or n)?\n";
char answer = 0;
cin >> answer;
if (answer == 'y')
cout << "yes";
switch ... case 语句:
cout << "Do you want to proceed(y or n)?\n";
char answer = 0;
cin >> answer;
switch (answer) {
case 'y':
cout << "yes";
break;
case 'n':
cout << "no";
break;
default:
cout << "error";
break;
}
Loop(循环)
for 循环和 while 循环
int i;
for (i = 0; i != 10; i ++) {
cout << i << endl;
}
while(i > 0)
{
cout << i << endl;
i--;
}
1.4 指针,数组和循环
指针与数组声明语句:
T a[n]; // T[n]: n 个 T 组成的数组
T* p; // T*: 指向 T 的指针
T& r; // T&: T的引用
T f(A): // T(A): 是一个函数,接受 A 类型的实参,返回 T 类型的结果
[] 表示 ...的数组
* 表示 指向 ...
& 后置 表示 ... 的引用
赋值语句:
char *p = &v[3]; // p 指向 v 的第四个元素
char x = *p; // *p 是 p 所指的对象
前置的 * 表示 ...的内容
前置的 & 表示 ...的地址
应用:
// 统计在 p[] 中 x 出现的次数
// 0 和 NULL 都可用来替代 nullptr 的功能,使用 nullptr 能够避免在整数和指针之间发生混淆。
int count_x(char *p, char x)
{
if(p == nullstr) return 0; // 输入参数非空判断
int count = 0;
for(; *p != 0; p++)
if(*p == x)
++ count;
return count;
}
二、用户自定义类型
2.1 结构
struct 结构体类型示例:
struct Vector {
int sz; //元素的数量
double *elem; // 指向元素的指针
}
结构体本身作用不大,需令 v 指向某些元素作用才能体现其作用。
void vector_init(Vector &v, int s)
{
v.elem = new double[s];
v.sz = s;
}
访问 Vector 成员的方式有两种 * 通过名字或引用, * 通过指针
void f(Vector v, Vector& rv, Vector* pv)
{
int i1 = v.sz; // 通过名字访问
int i2 = rv.sz; // 通过引用访问
int i3 = pv->sz; // 通过指针访问
}
2.2 类
C++ 类:在开发应用中,开发者常常希望自己构建的类型易于使用和修改,数据的使用具有一致性,并且表示形式最好对用户不可见,此时,最理想的做法就是把类型的接口与实现分离开来,C++ 中实现这个目的的语言机制被成为类。
class Vector{
public:
Vector(int s): elem {new double[s]}, sz{s} {} // 构建一个 Vector
double& operator[](int i) { return elem[i]; } // 通过下标访问元素
int size() { return sz; }
private:
double* elem; // 执行元素的指针
int sz; // 元素的数量
}
调用:Vector v(6) 该对象含有 6个元素
与函数名称 同名的函数称为构造函数,即,它是用来构造类的对象的函数。与普通函数不同,构造函数的作用是初始化类的对象,定义构造函数作用是解决类变量未初始化的问题。
elem {new double[s]}, sz{s}
作用是从自由空间获取 s 个 double 类型的元素,并用一个指针指向这些元素的指针初始化 elem,然后用 s 初始化 sz。
2.3 枚举
枚举代码
enum Color {
Red = 0,
Green = 1,
Blue = 2,
Yellow = 3,
};
enum TColor {
Red = 0,
Green = 1,
Blue = 2,
};
* C 中不允许重复定义相同的枚举值,如果不同的枚举中定义了相同的枚举值
* 会报错误:Redefinition of enumerator 'Red' xxx
使用 class 标记可以表示 enum 后面的 class 指明了枚举是强类型的,且它的枚举值位于不同的作用域中,因此可以在不同的 enum class 中重复使用枚举值而不引起混淆。
Color::red 指的是 Color 的 red,它与 TColor::red 显然不同。
enum class Color {
Red = 0,
Green = 1,
Blue = 2,
Yellow = 3,
};
enum class TColor {
Red = 0,
Green = 1,
Blue = 2,
};
enum class 之定义了赋值、初始化和比较(== 和 <)操作。然而,既然枚举类型是一种用户自定义类型,用户就可以自己为其定义别的运算符。(++ 和 -- 等)
三、模块化
构建 C++ 程序的关键是清晰地定义函数,用户自定义类型,类层次与模板等之间的关系。
3.1 分离编译
C++ 支持一种名为分离编译的概念,用户代码只能看见所用类型和函数的声明,它们的定义则放置在分离的源文件里,并被分别编译。这种机制有助于将一个程序组织成一组半独立的代码片段。
Vector.h
class Vector {
public:
Vector(int s);
int size();
private:
double* elem;
int sz;
}
Vector.cpp
#include "Vector.h"
Vector:: Vector(int s)
:elem{new double[s]}, sz{s}
{
}
int Vector:: size()
{
return sz;
}
User.cpp
#include "Vector.h"
#include <cmath>
using namespace std;
double sqrt_sum(Vector& v)
{
double sum = 0;
for(int i = 0; i!=v.size(); ++i)
sum+=sqrt(v[i]); // 求平方根的和
return sum;
}
User.cpp 与 Vector.cpp 中的代码共享 Vector.h 提供的 Vector 接口信息,但这两个文件是相互独立的,可以被分离编译。
3.2 名字空间
namespace 的机制,一方面表达某些声明是属于一个整体的,另一方面表明它们的名字不会与其他名字空间中的名字冲突。
namespace My_code {
class complex {
int main();
}
}
int My_code::main()
{
complex z{1,2};
auto z2 = sqrt{z};
std::cout << z2 << endl;
}
int main()
{
return My_code::main();
}
将代码放到命名空间 My_code 中,就可以确保名字中的函数不与 命名空间 std 中的标准库名字冲突。要想获取到标准库名字空间中名字的访问权,我们应该使用 using 指示。
using namespace std;
名字空间常用于组织较大规模的程序组件,典型的例子是库。
3.3 错误处理
3.3.1 异常
double& Vector::operator[](int i)
{
if(i < 0 || size() < i) throw out_of_range {"Vector::operator[]"};
return elem[i];
}
void f(Vector& v)
{
try {
v[v.size()] = 7;
}
catch( out_of_range){ // 发生了越界错误
// 处理越界错误
}
}
我们把处理异常的程序放在一个 try 块中,对 v[v.size()] 的赋值操作将出错。程序进入到提供了 out_of_range 错误处理代码的 catch 从句中。 out_of_range 类型定义在标准库 中,也被一些标准库容器访问函数使用。
3.3.2 不变式
使用异常机制通报越界访问错误是函数检查实参的一个示例,此时,因为基本假设,即所谓的前置条件没有得到满足,所以函数将拒绝执行。
无论什么时候只要我们试图定义一个函数,就应该考虑它的前置条件是什么,以及检验该条件的过程是否足够简洁。
Vector::Vector(int s)
{
if(s < 0) throw length_error{};
v.elem = new double[s];
v.sz = s;
}
try {
} catch (std::length_error) {
printf( "length error");
} catch (std::bad_alloc) {
printf("bad alloc error");
}
不变式的概念是设计类的关键,前置条件也在设计函数的过程中起到了同样的作用,不变式帮助我们:
- 帮助我们准确地理解想要什么。
- 强制要求具体而明确地描述设计,有助于确保代码正确。
##### 3.3.3 静态断言
静态断言用于程序在编译时发现错误
void f(double speed)
{
const double local_max = 160 / (60 * 60);
static_assert(speed < C, "can`t go that fast");
static_assert(local_max < C, "can`t go that fase")
}
C++ | C++ 概览 基础知识 | 01的更多相关文章
- AI-图像基础知识-01
目前人工智能Artificial Intelligence主要分为两大分支: 计算机视常见:Computer Vision,简称CV CV主要是研究如何让机器看懂世界的一种技术,通过各种光 ...
- MongoDB基础知识 01
MongoDB基础知识 1. 文档 文档是MongoDB中的数据的基本单元,类似于关系型数据库管理系统的行. 文档是键值对的一个有序集.通常包含一个或者多个键值对. 例如: {”greeting& ...
- CSS基础知识01
一.CSS基础知识介绍 1.css是cascading style sheet层叠式样式表的简写 2.css小用法 加粗:font-weight:bold; 正常用:norma ...
- python基础知识 01
一.计算机基础知识 计算机有硬件+操作系统+软件应用组成 cpu:人的大脑 内存:人的临时记忆 硬盘:人的永久记忆 操作系统 控制计算机硬件工作的流程 应用程序 安装在操作系统上的软件 二.Pytho ...
- Jquery基础知识01
1:$(document).ready()function{}和window.onload()的区别. 1:$(document).ready()function{} 该方法等到Dom结构绘制完毕 ...
- Java基础知识01
1. String,StringBuffer和StringBuilder的区别? String:final修饰,String对象创建后不可修改:StringBuffer和StringBuilder对象 ...
- .NET基础知识(01)-值类型与引用类型
常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还是值类型?enum.int[]和string呢? 4. 堆和栈的区别? 5. 什么情况下会在堆 ...
- C#基础知识01(continue、break 和 return、ref 和 out)
break[跳出循环或者退出一个switch语句]由于它是用来退出循环或者switch语句的,所以只有当它出现在这些语句中时才是合法的. continue 语句和break语句相似,只是它不是退出一个 ...
- 3-14 JS基础知识01
JavaScript的组成: JS特点:JS是一门 脚本语言:不需要编译编译:把代码转化成计算机所认知的二进制语言.JS是一门弱类型语言:声明变量都用varJS是一种动态语言:认知当前的着这个变量到底 ...
随机推荐
- Mysql错误:#1054 - Unknown column 'id' in 'field list' 解决办法
第一次用mysql,在插入数据时,竟然报这样的错误, #1054 - Unknown column 'id' in 'field list'
- title与h1的区别、b与strong的区别、i与em的区别?
title与h1的区别 定义: title是网站标题, h1是文章主题 作用: title概括网站信息,可以直接告诉搜索引擎和用户这 个网站是关于什么主题和内容的,是显示在网页Tab栏里的: h1突出 ...
- log4js的简单配置
js记录日志工具log4js,参数请参考官网文档https://log4js-node.github.io/log4js-node/index.html const log4js = require( ...
- H3C CHAP验证配置示例一
- ThinkPHP URL 路由简介
简单的说,URL 路由就是允许你在一定规则下定制你需要的 URL 样子,以达到美化 URL ,提高用户体验,也有益于搜索引擎收录的目的. 例子 原本的 URL 为: http://www.5idev. ...
- 【u238】暴力摩托
Time Limit: 1 second Memory Limit: 64 MB [问题描述] 晚会上大家在玩一款"暴力摩托"的游戏,它拥有非常逼真的画面和音响效果! 当然了,车子 ...
- python NameError: name 'raw_input' is not defined
错误:NameError: name 'raw_input' is not defined 原因出在raw_input ,python3.0版本后用input替换了raw_input 话说回来,学习p ...
- [转]在ASP.NET WebAPI 中使用缓存【Redis】
初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...
- P1068 压缩技术
题目描述 设某汉字由N × N的0和1的点阵图案组成. 我们依照以下规则生成压缩码.连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下.第一个数表示连续有几个0,第二 ...
- 备战省赛组队训练赛第十七场(UPC)
upc:传送门 A: 题解[1] G: 题解[1] D,G,H,J,L 题解 by 鲁东大学