c++ 小知识点记录

2023-05-16

数据类型 

 

数据类型类型说明符位数取值范围
整型int32-2147483648~+2147483647
短整型short int16-32767~+32768
长整型long int32-2147483648~+2147483647
单精度浮点型float32-3.4E-38~+3.4E+38
双精度浮点型double641.7E-308~1.7E308
字符型char8-128~+127

cout 

cout <<fixed        fixed 强制以小数形式显示,现实所有小数

cout<<setprecision(2)   控制显示的精度   2代表两位小数  头文件 <iomanip>

cout<<setw(8) 设定宽度 只管后面一个数字

cout<<setfill('_') 设定下划线填充

cout<<left 左对齐

cout<<boolalpha  打印true false

getchar()         cin.get()

 

 

SetConsoleTile(""); 更改cmd的名字

/**       */ 文档注释

 

位运算

 

算术运算符优先级

! ~ ++ -- sizeof

算数运算符

关系运算符

&&

||

赋值运算符

单目运算符 包括!~ ++ -- sizeof,优先级别高

赋值运算符优先级别最低

()优先级最高

从右向左结合性的只有赋值运算符、三目运算符和单目运算符

算术运算符 > 关系运算符 > 逻辑运算符

 

switch注意:

    switch后的表达式只能是整型或字符型
    case后常量表达式的值不能相同
    case后允许多条语句,不需要大括号
    如果不添加break语句,需要特别注意执行顺序
    case和default子句的先后顺序可以自行变动
    default子句可以省略

 

sizeof()特例 不执行num++

#include <iostream>
using namespace std;

int main()
{
	int num=5;
	cout << sizeof(num++)<<endl;
	cout << num << endl;	
	return 0;
}
输出:4  5

数组和指针 

数组名就是这块连续内存单元的首地址
    int num[5];//num是数组名,也可以理解成数组的首地址
    num的值与&num[0]的值是相同的
    数组第i+1个元素可表示为:
        第i+1个元素的地址:&num[i+1]或num+i
        第i+1个元素的值:num[i+1]或*(num+i+1)同样尝试*++ptr_num
    为指向数组的指针赋值:
        int*ptr_num = num;或int *ptr_num =&num[0];
    指针变量可以指向数组元素
        int *ptr_num = &num[4]或int*ptr_num = num+4;

vector常用函数

 

常用操作
clear()移除容器中的所有数据
empty()判断容器是否为空
size()返回容器中元素的个数
[index]、at(index)返回索引为index的元素
erase(pos)删除pos位置处的数据
erase(beg,end)删除[beg,end)区间的数据
front()返回第一个元素
insert(pos,elem)在pos位置处插入一个元素
pop_back()删除最后一个元素
push_back(elem)在容器末尾插入一个元素
resizer(num)重新设置容器大小
begin()、end()返回容器首尾元素的迭代器

https://blog.csdn.net/weixin_41743247/article/details/90635931

#include<algorithm>
 //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
 sort(a.begin(),a.end());
 //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
 reverse(a.begin(),a.end());
  //把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
 copy(a.begin(),a.end(),b.begin()+1);
 //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
  find(a.begin(),a.end(),10);
#include<vector>
vector<int> a,b;
//b为向量,将b的0-2个元素赋值给向量a
a.assign(b.begin(),b.begin()+3);
//a含有4个值为2的元素
a.assign(4,2);
//返回a的最后一个元素
a.back();
//返回a的第一个元素
a.front();
//返回a的第i元素,当且仅当a存在
a[i];
//清空a中的元素
a.clear();
//判断a是否为空,空则返回true,非空则返回false
a.empty();
//删除a向量的最后一个元素
a.pop_back();
//删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束
a.erase(a.begin()+1,a.begin()+3);
//在a的最后一个向量后插入一个元素,其值为5
a.push_back(5);
//在a的第一个元素(从第0个算起)位置插入数值5,
a.insert(a.begin()+1,5);
//在a的第一个元素(从第0个算起)位置插入3个数,其值都为5
a.insert(a.begin()+1,3,5);
//b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6)
a.insert(a.begin()+1,b+3,b+6);
//返回a中元素的个数
a.size();
//返回a在内存中总共可以容纳的元素个数
a.capacity();
//将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10);
//将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.resize(10,2);
//将a的容量扩充至100,
a.reserve(100);
//b为向量,将a中的元素和b中的元素整体交换
a.swap(b);
//b为向量,向量的比较操作还有 != >= > <= <
a==b;

指针  char*

   char ch = 'a';
   char *ptr_ch = &ch;
   cout<< (void *)ptr_ch<<endl;

在c语言中char *是默认当成字符串 输出ptr_ch会当作字符串输出,但是没有'\0'结束符会打印别的不知道什么东西,强制转换成(void *)说明是指字符指针就可以打印地址了

    char ch = 'z';
    char *ptr_ch = (char*) malloc(1 * sizeof(char));
    *ptr_ch = ch;
    //*(ptr_ch+1) = '\0';
    cout<< ptr_ch<<"  "<<*ptr_ch<<endl;
    return 0;

int *ptr1 = nullptr; //等价于int *ptr1=0;

int*ptr2 = 0; //直接将ptr2初始化为字面常量0 

引用

引用对指针进行了简单封装,底层仍然是指针

获取引用地址时,编译器会进行内部转换

引用的本质在c++内部实现是一个指针常量

//发现是引用,转换为 int* const ref = &a;
void func(int& ref){
	ref = 100; // ref是引用,转换为*ref = 100
}
int main(){
	int a = 10;
	//自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改
	int& ref = a;
	ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20;
	cout << "a:" << a << endl;
	cout << "ref:" << ref << endl;
	func(a);
	return 0;
}

地址占四个字节,指针就是占四个字节

常量引用

    常量引用主要用了修饰形参,防止误操作

//引用使用的场景,通常用来修饰形参
void showValue(const int& v) {
	//v += 10;
	cout << v << endl;
} 

int main() {
	//int& ref = 10; 引用本身需要一个合法的内存空间,因此这行错误
	//加入const就可以了,编译器优化代码,int temp = 10; const int& ref = temp;
	const int& ref = 10;
	//ref = 100; //加入const后不可以修改变量
	cout << ref << endl;
	//函数中利用常量引用防止误操作修改实参
	int a = 10;
	showValue(a);
	system("pause");
	return 0;
}

 

c++函数

内置函数 Boost C++

C++中返回值类型不能是数组,但可以是其他任何类型(可以将数组作为结构或对象组成部分返回

注意:1、数组作为函数实参时,只传递数组的地址(首地址),并不传递整个数组的空间 2、当用数组名作为实参调用函数时,数组首地址指针就被传递到函数中

void show(double (*)[5],int);

int main()
{
	double powers[3][5] = {
		{45.5,55.6,88.9,66.6,78},
		{98.2,60.1,33.7,49.3,59},
		{78.2,58.5,12.8,37.8,43}
	}
	
	show(powers,3);
	return 0;
}

void show(double (*arr)[5],int len)
{
	for(int i=0;i<len;i++){
		for(int j=0;j<4;j++){
			cout<<*(*(arr+i)+j)<<",";
		}
		cout<<endl;
	}
}

 

 也可以是 void show(double [][5],int len);

               void show(double arr[][5],int len){...}

 

函数默认参数

int func(int a, int b = 10, int c = 10) {
	return a + b + c;
} 
//1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值
//2. 如果函数声明有默认值,函数实现的时候就不能有默认参数
int func2(int a = 10, int b = 10);
int func2(int a, int b) {
	return a + b;
} 
int main() {
	cout << "ret = " << func(20, 20) << endl;
	cout << "ret = " << func(100) << endl;
	system("pause");
	return 0;
}

函数占位参数

  C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置


//函数占位参数 ,占位参数也可以有默认参数
void func(int a, int) {
    cout << "this is func" << endl;
} 
int main() {
    func(10,10); //占位参数必须填补
    system("pause");
    return 0;
}

 

函数指针

函数也有地址

函数的地址是存储其及机器语言代码的内存开始地址

可以在不同的时间使用不同的函数

//函数原型:
double sum(double,double);
//函数指针声明:
double(*ptrSum)(double,double)

 注意:
    1、该语句声明了一个指针ptrSum,指向一个函数
    2、double *ptrSum(double,double) 不是函数指针,而是声明了一个函数ptrSum,返回double*类型
    
重点:
    1、c++11中可以使用auto ptrFunc=addition;自动推断类型(自动类型推断需要确保变量的类型与初值类型一致)
    2、可以使用typedef简化声明:
        typedef double (*ptrCalc)(double,double);

        ptrCalc ptrFunc;

 

内联函数 inline

内联函数  是c++为提高程序运行速度所做的一项改进

与常规函数的区别不在于编写方式,而在于被调用时的运行机制不同

使用建议:
如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分;如果代码执行时间很短,内联调用就可以节省大部分时间

内联的使用(二选一)
    在函数声明前加关键字inline
    在函数定义前加关键字inline

 

引用做参数和返回值

注意:
1、引用并非对象,只是为一个已经存在的对象起的别名
2、引用更接近const指针,一旦与某个变量关联起来,就将一致效忠于它
3、将引用变量用做参数时,函数将使用原始数据,而非副本
4、当数据所占内存比较大时,建议使用引用参数

函数返回引用类型

1、不要返回局部变量的引用
2、函数可以不返回值,默认返回传入的引用对象本身
3、返回引用时,要求函数参数中包含被返回的引用对象

int & sum(int &num)
{
	num++;
	return num;
}
int main()
{
	int num=10;
	int &result = sum(num);
	sum(num)=55;
	cout <<"result="<<result<<endl;
	return 0;
}
输出为:55

使用引用参数的一些指导规则
    1、能够修改调用函数中的数据对象
    2、数据对象较大时传递引用可以提高程序的运行效率
        函数中不需要修改传递的参数
            如果数据对象很小,建议按值传递
            传递数组只能使用指针,并使用const关键字
            较大的对象则使用const指针或引用,以提高程序的效率
        函数中需要修改传递的参数
            数据对象是基本类型或结构时,可以使用指针或引用(基本类型建议使用指针)
            数据对象是数组时只能使用指针
            数据对象是类对象时,要求使用引用

 

默认参数

 

函数重载

同一个作用域下 ,函数名相同,参数列表不同 类型不同或者个数不同或者顺序不同

函数返回值不可以作为函数重载的条件

特征标 重载-编译器在编译时,根据参数列表对函数进行重命名(void Swap(int a, int b) Swap int int)

编译器把类型引用和类型本身视为同一个特征标

const能不能区分重载要看参数是值传递还是引用传递

 int test(int  &i)
{
	cout<<"test01  "<<i<<endl;
	return i;
}

int test( const int &i)
{
	cout<<"test02  "<<i<<endl;
	return i;
}

上面的test函数是重载的,如果没有使用引用或者指针,会报错 函数重定义。

 

模板函数

  函数模本就是建立一个通用函数:
    函数定义时不指定具体的数据类型(使用虚拟类型代替)
    函数被调用时编译器根据实参反推数据类型-类型的参数化
    
//模板头与函数声明/定义永远是不可分割的整体
template <typename 类型参数1,typename 类型参数2,...>
返回值类型 函数名(形参列表){
    //在函数体中可以使用类型参数
}

//函数声明
typename<typename T> void Swap(T&,T&);
/**
 *使用模板技术实现变量交换值
  */
template<typename T>//模板头与函数声明/定义永远是不可分割的整体
void Swap(T &a,T &B)
{
    T temp = a;
    a=b;
    b=temp;
}

 

 

 

类和对象

 1、class方式声明的类型与struct声明的类型仅仅是形式上不同。
 2、其唯一的区别在于使用class声明的类型默认成员是私有的(private),而struct声明的类型默认成员是公有的(public)

访问权限有三种:
1. public 公共权限
2. protected 保护权限
3. private 私有权限
示例:
//三种权限
//公共权限 public       类内可以访问 类外可以访问
//保护权限 protected 类内可以访问 类外不可以访问
//私有权限 private     类内可以访问 类外不可以访问

构造函数

    以类名作为函数名
    无返回值类型
作用
    初始化对象的数据成员
    类对象被创建时,编译器为对象分配内存空间并自动调用构造函数以完成成员的初始化
构造函数的种类
    无参构造
    一般构造(重载构造)
    拷贝构造
注意:
    1、如果创建的类中没有写任何构造函数,系统会自动生成默认的无参构造函数(函数为空,什么都不做)
    2、如果书写了构造函数,系统就不会再自动生成默认构造;如果希望有一个这样的无参构造函数,需要自己显示的书写出来
    

带参构造

类名::构造(类型1 参数1,类型2 参数2,...){
    //代码
}
Student::Student(string name,string desc){
    _name = name;
    _desc=desc;

 

构造函数重载 和普通函数重载相同

Student();
Student(int);
Student(string,string);

//初始化参数列表

Student::Student(string name,string desc):m_Name(name),m_desc(desc){}

 

析构函数

析构函数
    当对象过期时自动调用的特殊成员函数
    析构函数一般用来完成清理工作
    析构函数的名称是在类名前加上~
        析构函数没有参数,只能有一个
        
注意:
    析构函数用来释放对象使用的资源,并销毁对象的非static数据成员
    无论何时一个对象被销毁,都会自动调用其析构函数(隐式析构)
    

class Student{
private:
    double *scores;
public:
    Student(int len)
    {
        //使用new
        scores = new double[len];
    }
    ~Student()
    {
        delete scores;//释放资源
    }

}

 

析构函数 不能释放 堆 要用delete

实例化

this指针
    每个成员函数(包括构造和析构)都有一个this指针
    this指针指向调用对象,即可以通过this关键字访问当前对象的成员
        访问成员变量  this->成员名;
        访问成员函数  this->函数名()
注意:
1、this指针的类型为类类型*const(类名*const),为右值
2、this指针本身不占用大小,它不是对象的一部分,因此不会影响sizeof的结果
3、this的作用域在类成员函数的内部
4、this指针是类成员函数的第一个默认隐含参数,编译器自动维护传递,类编写者不能显示传递
5、只有在类的非静态成员函数中才可以使用this指针,其他任何函数都不可以

函数最后加const 说明不能修改this

 Student &GetSuperScolar(Student&) const;
//函数的结尾声明为const;函数内部不允许修改对象本身,调用本对象非const方法就会报错

this返回对象指针

 

运算符重载 operator

运算符重载格式
返回类型 operator被重载的运算符(参数列表)
 

class Integer
{
    public:
        Integer():m_num(0){}
        Integer(int num):m_num(num){}
        const Integer operator+(const Integer &other)const{
            cout<<"重载运算符+,一遍实现两个整型对象相加"<<endl;
            return Integer(this->m_num+other.m_num);
        }
    private:
        int m_num;
}
Integer num1(1024);
Integer num2(2048);
Iteger num3 =num1 + num2;
//实际调用
//num3 = num1.operator+(num2);

const

const 修饰变量    

    1、只有一个const时,如果const位于*的左侧,表示指针所指的数据是常量,不能通过该指针修改实际数据;指针本身是变量,可以指向其他内存单元
    2、只有一个const时,如果const位于*的右侧,表示指针本身是个常量,不能指向其他内存单元;所指向的数据可以修改
    3、如果有两个const位于*左右两侧,表示指针和指针所指向的数据都不能修改

const成员函数不能调用非const成员函数
const修饰引用时,不能修改引用对象的任何成员,好处是可以保护传递参数,不需要一个新的参数副本

 

 

 

Integer num1(1024),Integer num2(24);
Integer num3 = num1+num2;//正常执行
Integer num4 = 1024 +num1;//编译错误

Integer Integer::operator+(const Integer &other);
是作为成员函数重载的, num1.operator+(num2)合法
但是1024.operator+(num1)中,int类型并没有重载+号

使用友元函数

friend const Integer operator+(const Integer&,const Integer &);
friend ostream &operator <<(ostream &,const Integer &);

const Integer operator+(const Integer &leftNum,const Integer & rightNum){
    return Integer(leftNum.m_num + rightNum.m_num);
}

ostream &operator<<(ostream &out,const Integer &num){
    out <<num.m_num;
    return out;
}

 

运算符声明成类成员还是声明独立友元函数建议准则:
    C++规定,复制运算符=、数组下标运算符[]、函数调用运算符()、成员访问运算符->在重载时必须声明为类的成员函数
    流运算符<<、>>、类型转换运算符不能定义为类的成员函数,只能是友元函数
    一元运算符和复合复制运算符重载时,一般声明类的成员函数
    二元运算符在运算符重载时,一般声明为友元函数

注意:
 1、对于很多运算符来说,可以选择使用成员函数或非成员函数来实现运算符重载,一般来说,非成员函数应该是友元函数,这样才能直接访问类的私有数据
 2、在定义运算符是,必须选择其中的一种格式,而不能同时选择这两种格式,同时定义这两种格式将被视为二义性错误,导致编译错误
 3、那么哪种格式最好呢?对于某些运算符来说,成员函数时唯一合法的解释。在其他情况下,这两种格式没有太大的区别。有时,根据类的设计,使用非成员函数版本可能更好(尤其是为类定义类型转换时)

//流运算符 一般只能使用友元的方式重载
friend ostream &operator<<(ostream &out,const Integer &num);

ostream &operator<<(ostream &out,const Integer &num)
{
	out << num.m_mvalue;
	return out;
}

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 小知识点记录 的相关文章

随机推荐

  • 手把手教你,从零开始搭建Spring Cloud Alibaba!这份笔记太牛了

    Spring Cloud Alibaba 是阿里巴巴提供的微服务开发一站式解决方案 xff0c 是阿里巴巴开源中间件与 Spring Cloud 体系的融合 Springcloud 和 Srpingcloud Alibaba 区别 xff1
  • 兵棋推演系统软件开发方法有哪些呢

    兵棋推演系统软件开发方法有哪些呢 兵棋推演系统北京软件开发公司针对 B S 架构及先进的多想定 多进程以及多方推演技术进行研究 xff0c 实现了基于 B S 架构的兵棋推演系统 该系统使用便捷 xff0c 只需通过浏览器访问系统即可 兵棋
  • 工厂生产设备全生命周期管理系统软件

    工厂生产设备全生命周期管理系统软件 设备全生命周期管理系统是解决当下设备管理问题 xff0c 实现设备效能利用最优化的重要举措 设备全生命周期管理系统传统意义上的设备管理系统或软件 xff0c 往往局限在业务层面和主数据层面 然而 xff0
  • 2万字系统总结,带你实现 Linux 命令自由?还不赶紧进来学习

    2万字系统总结 xff0c 带你实现 Linux 命令自由 还不赶紧进来学习 前言 Linux 的学习对于一个程序员的重要性是不言而喻的 前端开发相比后端开发 xff0c 接触 Linux 机会相对较少 xff0c 因此往往容易忽视它 但是
  • ENVI 5.3遥感(无人机)影像的镶嵌(拼接)

    图像镶嵌 xff0c 对一幅或若干幅图像通过预处理 几何镶嵌 色调调整 去重叠等处理 xff0c 镶嵌到一起生成一幅大的图像的影像处理方法 要求是尽量是镶嵌后的影像没有镶嵌缝 图像质量不下降 色彩均衡等 ENVI5 3的图像镶嵌功能可提供交
  • NotePad++ XMLTools 插件离线安装

    在使用NotePad 43 43 时 xff0c 在某些情形下 xff0c 需要格式化Xml格式内容 xff0c 可以使用Xml Tools插件 xff0c 注意下载安装包时 xff0c 需下载与NotePad 43 43 像匹配版本的插件
  • errors_impl.AlreadyExistsError: Another metric with the same name already exists.

    errors impl AlreadyExistsError Another metric with the same name already exists 今天在导包keras包时 xff0c 总是报上面这个错误 xff0c 说已经ke
  • docker-compose 中 volumes、environment、privileged、network_mode的使用

    privileged xff1a 用来给容器root权限 xff0c 不安全的environment xff1a 设置容器中的环境变量volumes xff1a 用来存储docker持久化的数据 xff0c 启动tomcat容器后 xff0
  • 普通程序员如何逆袭,达到财富自由?

    这两天闲逛知乎 xff0c 发现了一个有趣的问题 xff1a 大部分人的回答大概率无非这两种模式 xff1a 1 去大厂 混到管理层或者高P xff0c 拿大量股权 xff0c 财务自由 这个模式还挺常见的 xff0c 基本上阿里P8能到年
  • intel realsense SR300 深度图像和彩色图像对齐

    深度图像和彩色图像对齐 原因 xff1a 由于RGB图像数据与深度图像数据的空间坐标系是不同的 xff0c 前者的原点是RGB摄像头 xff0c 后者的原点是红外摄像头 xff0c 因此两者会有相应的误差 没对齐之前的结果如下图所示 xff
  • CMakeLIsts.txt与Makefile的区别

    CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 他能够输出各种各样的makefile或者project文件 能测试编译器所支持的C 43 43 特性 类似UNIX下的automake CMake 使
  • linux socket编程

    1 网络中进程之间如何通信 进程通信的概念最初来源于单机系统 由于每个进程都在自己的地址范围内运行 xff0c 为保证两个相互通信的进程之间既互不干扰又协调一致工作 xff0c 操作系统为进程通信提供了相应设施 xff0c 如 UNIX B
  • linux环境下如何卸载一路赚钱(yilu/mservice)

    一 删除定时任务 xff1a sudo crontab l u root 2 gt dev null grep v mservice sudo crontab u root 二 停止服务 对于ubuntu以及centos 7的用户 serv
  • 【图像处理】多帧降噪算法

    本文参考论文 xff1a Denoising image sequences does not require motion estimation http citeseerx ist psu edu viewdoc download do
  • VINS-Fusion初始化------IMU与Camera外参旋转标定,IMU角速度偏置标定,重力向量、单目尺度标定

    本文基于VINS Fusion解释VIO系统的初始化 xff0c 包括在线标定IMU Camera的外参旋转 xff0c IMU角速度偏置 xff0c 重力方向 xff0c 单目尺度 单目初始化相比于双目 xff0c 多一个构建SFM问题优
  • 视觉惯性里程计Visual–Inertial Odometry(VIO)概述

    本文主要来自于博客园关于知乎的讨论 链接如下 xff1a Visual Inertial Odometry VIO
  • IBM Was 打补丁记录

    0 拷贝解压ifph52925升级包 通过FTP工具 xff0c 把压缩包传到服务器 xff0c unzip d test01 9 0 0 0 ws was ifph52925 zip 1 停掉was 服务 ps ef grep was k
  • 阿里云服务器远程桌面安装

    阿里云服务器远程桌面安装 环境说明 xff1a CentOS 8 3 一 安装桌面环境 root用户下执行命令 yum grouplist yum groupinstall y span class token string 34 Serv
  • STM32与Futaba遥控器进行S.Bus的通讯程序

    Futaba xff08 日本双叶电子工业 xff0c 戏称 扶他爸 xff09 的遥控器用航模中使用较为广泛的遥控器 S Bus则是Futaba公司提出的舵机控制总线 本篇博文主要以T6K为对象 xff0c 介绍STM32与S Bus协议
  • c++ 小知识点记录

    数据类型 数据类型类型说明符位数取值范围整型int32 2147483648 43 2147483647短整型short int16 32767 43 32768长整型long int32 2147483648 43 2147483647单