首页 > 编程语言 >C++基础篇

C++基础篇

时间:2024-05-15 22:11:25浏览次数:25  
标签:const constexpr int 基础 C++ 对象 引用 指针

输入输出流iostream

向流写入数据<<运算符

<<运算符接受两个运算对象,此运算符将给定的值写到给定的ostream对象中:
左侧:运算对象为ostream对象,如cout、cerr、clog
右侧:运算对象是要打印的值
输出结果:写入给定值的那个ostream对象,即此运算符返回其左侧的运算对象。
表达式等价于:(std::cout << "Enter two numbers:") << std::endl;

写入endl效果

添加一个换行符,然后结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中显示。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。

从流读取数据>>运算符

从给定的istream读入数据,并存入给定的对象中:
左侧:运算对象为istream对象,如cin
右侧:运算对象是一个对象
输出结果:运算符返回其左侧的运算对象。
表达式等价于:(std::cin >> v1) >> v2;

作为条件处理

while(std::cin >> value)
其效果是检测流的状态。
True:流是有效的,即流未遇到错误,那么检测成功。
False:当遇到文件结束符(end-of-file),或遇到一个无效输入时(例如读入的值不是一个整数),istream对象的状态会变为无效。


变量

初始化与赋值

初始化不是赋值,其含义是创建变量是赋予其一个初始值,而赋值的含义是值替换。
注意:

long double id = 3.1415926536;
int a{id},b = {id};  //错误
int c(id),d = id;    //正确

如果使用列表初始化且初始值存在丢失信息的风险,则编译器报错。

变量声明和定义的关系

声明:使得名字为程序所知。一个文件如果想要使用别的地方定义的名字则必须写声明。
定义:负责创建与名字关联的实体。申请了储存空间,赋予初始值。
作用:
如果想要在多个文件中使用同一变量,就必须将声明和定义分离。变量的定义必须出现在且只能出现在一个文件中,而其他用到该变量的文件则对其声明,同时不能有重复定义。

声明关键字extern
extern int i; //声明i
int j;        //定义,默认初始值
extern double pi = 3.1416; //赋值则为定义
使用extern和包含头文件来引用函数有什么区别?

1、extern的引用方式比包含头文件要简洁,extern的使用方法很是直接,想引用哪个函数就用extern声明哪个函数。
2、会加速程序的编译(预处理)的过程,节省时间。在大型C程序编译过程中,这种差异是非常明显的。


引用(reference)与指针(pointer)

引用 &

int ival = 1024;
int &refVal = ival;

含义:为对象起另外一个名字,引用类型引用另外一种类型。
解释:定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。
性质:
1、引用必须初始化:初始值对象绑定。
2、引用初始化完成,则不能修改:已经完成绑定,无法重新绑定。
3、引用即初始化对象起一个别名,不会额外开辟空间:引用不是一个对象,没有开辟空间。

指针 *

int ival = 1024;
int *p = &ival; //&获取地址
*p = 42; //*解引用

含义:指针存放的是某个对象的地址(32位系统通常是4字节,64位系统通常是8字节)。需要获取地址,可以使用取地址符&;需要获取对象,可以使用解引用符*

空指针(null pointer)与野指针

空指针:赋值为0或者NULL,没有指向任何对象。c++11最好使用nullptr。
野指针:指针变量指向非法的内存空间。

void*指针

特殊的指针类型,可以存放任意的对象地址。
限制:
一般拿它和别的指针比较,作为函数输入输出,或者赋值给另一个void*指针。不能直接操作void*指针所指的对象,因为不知道是什么类型,无法确定能做哪些操作。

引用与指针区别

1、指针无需一定初始化,可以为NULL;引用必须初始化,总会指向一个对象。
2、指针定义会开辟一个地址空间;引用不会额外开辟空间。
3、指针本身是个对象,允许赋值和拷贝,生命周期内可以指向不同对象;引用初始化完成后便绑定,无法更换绑定。


const限定符

定义一种变量,它的值无法被修改。编译器在编译的过程中把用到该变量的地方替换成对应的值。

const int bufSize = 512;

指向常量的指针(pointer to const)

内容:不能通过该指针改变对象的值。但没有规定那个对象的值不能通过其他途径改变。

const double pi = 3.14;
const double *cptr = &pi;

double dval = 3.15; 
cptr = &dval; //指针常量可以指向一个非常量对象
dval = 3.14;  //cptr指向对象的值被改变了

常量指针(const pointer)

内容:指针是对象,把*放在const关键字之前,把指针定为一个常量。必须初始化,初始化完成后,则指针不能重新指向新的对象(即存放的那个地址值无法修改)。

int errNumb = 0;
int *const curErr = &errNumb;

constexpr和常量表达式(c++11)

内容:
1、常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。
2、constexpr主要用于那些值在编译时就能确定的场合。它用于强调并利用编译时常量的特性。const则只是表明上只读,运行时一样可以通过其他方式改变。
3、而constexpr函数的返回值也必须是常量并且在编译时必须可以计算出来。

constexpr int mf = 20;
constexpr int limit = mf +1;
constexpr int sz = size();         //size是一个constexpr函数
constexpr int sqr1(int a){
    return a*a;
}
const int sqr2(int a){
    return a*a;
}
int main()
{
    array<int,sqr1(10)> mylist1; //可以
    array<int,sqr2(10)> mylist2; //不可以
    return 0;
}

constexpr和指针

内容:constexpr仅仅对指针有效,与指针所指的对象无关。constexpr会把所定义的对象置为顶层const。

int a = 10;
const int* p = nullptr;     //p是一个指针常量,可以改指向
constexpr int* q = nullptr; //q是一个常量指针,不可改指向
p = &a;
//q = &a;//错误
*q = a;

mutable

用来修饰属性的,表示可变,被mutable修饰的属性,可以在常函数中修改,也可以由常对象修改


处理类型

别名

typedef int *pst;
using Int = int; //c++11

指针、常量和类型别名

注意:

typedef int *pst;
const pst cstr = nullptr;//cstr是指向int的常量指针,不可修改指向
//cstr = &a; //错误
*cstr = 10;

//不等于
const int *cstr = nullptr;

解释:这种理解是错误的。声明语句中用到pst时,其基本数据类型是指针。可是用int*重写了声明语句后,数据类型就变成了int,*成为了声明符的一部分。这样改写的结果是,const int成了基本数据类型。前后两种声明含义截然不同,前者声明了一个指向int的常量指针,改写后的形式则声明了一个指向const int的指针。

auto类型(c++11)

内容:auto让编译器通过初始值来推算变量的类型。一条声明语句只有一个基本类型。

auto i = 0,*p = &a; //int

decltype类型(c++11)

内容:有时候希望从表达式的类型推算出要定义的变量的类型,但是不想用其表达式的值初始化变量。而decltype的作用就是选择并返回操作数的数据类型。
注意:decltype((decl))双层括号的结果永远是引用类型。或者表达式内容是解引用操作,结果也是引用类型。

int decl = 50;
decltype(decl) a1 = 100;    //int
decltype((decl)) a1 = decl; //int&
decltype(*p) a1 = decl;     //int&

友元

类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问,但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数, c++允许这个特权函数访问私有成员。
这一点从现实生活中也可以很好的理解:比如你的家,有客厅,有你的卧室,那么你的客厅是ublic的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。


持续更新中

标签:const,constexpr,int,基础,C++,对象,引用,指针
From: https://www.cnblogs.com/feng-Ling/p/18090493

相关文章

  • Linux基础-文件特殊权限
    #day13今日安排默写昨日作业讲解文件权限篇综合知识脑图特殊权限(了解)linux提供的12个特殊权限默认的9位权限rwxrwxrwx还有三个隐藏的特殊权限,如下suid比如/usr/bin/passwdsgidsbit特殊权限对照表类别suidsgidsticky字符表示......
  • redis基础
    redis介绍Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。Redis与其他key-value缓存产品有以下三个特点:Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据,同时还提供l......
  • 0_刷题中的基础
    目录基础练习题具体题目二叉树排序双指针法类型1:一个头指针,一个尾指针,不断缩小搜索空间类型2:快慢指针法链表动态规划二分搜索排序数组排序基于交换的排序冒泡排序快速排序基于插入的排序插入排序基于选择的排序选择排序二路归并排序链表排序搜索二分搜索二叉树的遍历深度优先遍历......
  • 云原生基础架构介绍
    什么是云原生基础架构?基础架构是指支持应用程序的所有软件和硬件,包括数据中心、操作系统、部署流水线、配置管理以及支持应用程序生命周期所需的任何系统或软件。高效运行的基础架构可以使得迭代更快,缩短投向市场的时间,从而加速业务发展。使用云原生基础架构是有效运行云原生应......
  • msvc 获取c++类内存布局 /d1 reportAllClassLayout
     visualstudio配置获取所有类内存布局/d1reportAllClassLayout或者指定类/d1reportSingleClassLayoutXXXclass  编译时输出:     ps:https://www.openrce.org/articles/full_view/23   【原文地址】https://blog.csdn.net/qq_29542611/article......
  • linux下使用c++模拟下载进度
    #include<iostream>#include<iomanip>#include<chrono>#include<thread>voidshowProgressBar(doubleprogress){constintbarWidth=70;std::cout<<"\r[";intpos=static_cast<int>(barWid......
  • Python基础篇(流程控制)
    流程控制是程序运行的基础,流程控制决定了程序按照什么样的方式执行。条件语句条件语句一般用来判断给定的条件是否成立,根据结果来执行不同的代码,也就是说,有了条件语句,才可以根据不同的情况做不同的事,从而控制程序的流程。ifelseif条件成立,执行if内的命令;否则条件不成立,则......
  • serverless基础应用
    架构的演进物理机时代:单机版的单体架构-数据库,应用代码,HTTP服务器等服务都在一台服务器上虚拟机时代:将一台物体机通过虚拟化技术分割为多台虚拟机,对于硬件设备的管理统一由云厂商负责,开发者不需买硬件,直接在云平台买虚拟机,例如阿里云的ECS为了降低服务器负载,数据库迁移到云厂商......
  • Git基础操作
    #1.安装git请参考之前的步骤#2.配置gitgitconfig--globaluser.name"yourname"gitconfig--globaluser.email"[email protected]"#注册时用的邮箱#创建新仓库gitinit#初始化仓库gitclonehttps://github.com/user/repo#克隆远......
  • C++封装dll(__cdecl和__stdcall)
    【1】使用__stdcall还需要添加def文件编译,使用工具DEPENDS.EXE打开dll文件成功。【2】使用__cdecl直接编译即可,不需要导入def文件......