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是一种动态语言:认知当前的着这个变量到底 ...
随机推荐
- CSS的固定定位
将元素放置在浏览器窗口的固定位置,拖拽窗口时元素位置不变. 类似语法: div{ position:fixed; top:0px; left:0px; right:0px; bottom:0px; }
- supersockets服务器配置热更新
Keywords: 配置,热更新 此功能能够允许你在不重启服务器的前提下更新服务器实例的配置. (仅限1.6.5及其以上版本)
- NGINX比Apache的性能高是因为NGINX由C语言开发,而Apache由C++开发
事实上,NGINX比Apache的性能高是因为NGINX由C语言开发,而Apache由C++开发.因此,NGINX效率大概是Apache的10倍左右
- sdk uncaught third Error Cannot assign to read only property 'constructor' of object '#<V>' (小程序)
sdk uncaught third Error Cannot assign to read only property 'constructor' of object '#<V>' 在a ...
- linux下svn清除非版本控制文件的方法
使用svn status命令,文件名前面显示问好的就是非版本控制的文件
- python基础十一之迭代器和生成器
可迭代 内置方法中含有__iter__的数据类型都是可迭代的,只要是可迭代的就可以使用for循环,反之亦然. print(dir('')) # dir()函数可以获取当前数据类型的所有内置方法 返回值 ...
- Python--day37--进程锁
进程锁的示意图: 锁.py: #锁 #火车票 import json import time from multiprocessing import Process from multiprocess ...
- 开源项目使用 appveyor 自动构建
我写了几个开源项目,我想要有小伙伴提交的时候自动运行单元测试,自动运行编译,这样可以保证小伙伴提交清真的代码 本文将会告诉大家如何接入 appveyor 自动构建方案,在 Github 上给自己的开源 ...
- H3C TFTP协议介绍
- vue 使用webpack打包后路径报错以及 alias 的使用
一.vue 使用webpack打包后路径报错(两步解决) 1. config文件夹 ==> index.js ==> 把assetsPublicPath的 '/ '改为 './' 2. b ...