您现在的位置是:首页 >技术杂谈 >C++笔记网站首页技术杂谈

C++笔记

riversuer 2024-06-17 10:13:36
简介C++笔记

一 基础知识补全

大纲:c++特有语法,指针,基础知识

1 运行原理:

编译代码文件,会对每一个cpp文件生成对应的obj文件,然后编译器会将这些obj文件连接起来,生成可执行文件。
值得一提.obj:汇编程序
link:将obj文件链接生成exe可执行程序


2 基本语法知识

/**/注释不能嵌套,会报错,作用优先与cout中的“ ”

for,初始语句执行一次,判断语句在循环体前,表达式执行在循环体后

读取不定输入,while(cin>>a):当while检测istream对象,效果是检测流的状态,即是否是有效输入,而不是检测是否非0,遇到小数,字母,等异常输入会判定结束,回车不会。

ctrl+z是windows输入结束判定
ctrl+d是unix

类:对象.成员,对象.方法


3 内存知识:

1 可寻址的最小内存块为:字节byte
2 存储的基本单元为:字,(字由32或64位构成,4 or 8字节)
3 计算机将一个地址与一个字节相关联
4 知晓地址,和数据类型的情况下,可以知道数据所占的比特数和含义,即占了多少字,表达什么意思。


4 基本内置类型

c++:整形(含字符型和布尔),浮点型
各平台数据范围一览:(sizeof(int)可测试类型长)

在这里插入图片描述

4.1 类型选择优化:

1 数据不可能为负时,选用unsigned型
2 int 和long都是32位(win64下),若数据超,选取longlong,并且long在跨平台时可能出现丢失精度(linux-windwos)
3 算数表达式中尽量避免char或bool,因为不知道编译器中char是否有符号,容易出现很难发现的问题,明确使用signedchar或unsigned char
4 浮点数选用double,和float几乎同样的代价,且longdouble的精度一般不需要,且有消耗


4.2 负数的存储:

负数原,反,补码
原码:符号位是1,其余位为正数原码
反码:符号位为1,其余位取反(0变1,1变0)
补码:符号位为1,其余位取反,然后+1(即补码是原码取反在+1)
(正数原,反,补皆为本身,求反码时符号位不参与变换)

注意:
1 负数在计算机中并不是以原码形存储的,而是以补码存储的。也可以说,所有二进制数在计算机中都用补码来进行存取。
2 所以有符号整数进行加减运算,实际上是采用数据的补码进行加法运算,得出的结果为补码形式,即:正数代表原码本身,负数减1再取反代表负数原码。


4.3 有无符号1byte范围分析:

1 有符号:
正数可用0 000 0001~0 111 1111 及:1—127
负数可用1 111 1111~1000 0001 及:-1----127
由于0有+0和-0,而-0为:1000 0000 代表-128(有符号类型,若进为到达符号位则舍弃
故,有符号范围:-128~127

2 无符号
范围:0~255


4.4 强制转换

代码要避免依赖实现环境的问题,如因为进制转换而导致的不可移植,非常糟糕。

注意
1 '无符号’和’有符号’算术运算时,'有符号’数据会被强制转换为’无符号’数据,即负数会崩掉,若signed数据为"负数",那就很容易出现bug,因为对unsigned类型赋值 “负数”,数据几乎变得面目全非,unsigned参与的运算中,一定一定一定注意不能出现"负数"!!(最好别用,全用int安全,哈哈)
2 若整形数据 强转为浮点数,若整形数据范围超浮点数范围,则浮点数将会损失精度

在这里插入图片描述


4.5 字面值常量

理解
形如35这种没有名字直接用他们的值来称呼的常量,统称为字面值常量,包括整数小数字符和字符串,一般赋值时使用。

分类
1 十进制:最小匹配int,long,longlong,(默认带符号)
2 八进制十六进制:最小匹配int,u~int,long,u-long,longlong,u-longlong
3 浮点型:字面值为double,表现形式:3. , .3 , 0.3e1(科学计数法,0.3*10)
4 字符型:char
5 字符串:arry,末尾加’‘,故实际长度+1
6 转义字符:不可打印,特殊含义,用‘’+字母,或‘’+八进制(最多3个)或‘x’+16进制(不限)
7 布尔:true,false
8 指针:nullptr
9 指定字面值类型:字符型+前缀u,U,L,u8;整形加后缀u,l,ll,浮点型加后缀f,l


5 变量

变量提供一个可供操作的,有名的存储空间,而数据类型决定了存储空间大小和布局方式;

对象指一块能存储和数据且具有数据类型的内存空间,对象变量一般可互换。

初始化!=赋值,前者是创建对象时并获得一个初始值,后者是移除当前值用新值替代

特别的:定义在函数体内部的内置变量将不被默认初始化

定义变量本质
基本数据类型+一组声明符,类型修饰符不过是声明符的一部分而已。例如int a=5 中,声明符就是变量名a,但还存在复杂的声明符,如引用和指针。int &b=a,*p=&a 上式声明了引用类型变量b和指针类型变量p,其中声明符分别为:&b和 * p,&和 * 不过是各自声明符的一部分。除此之外,对于上述这种一个基本类型数据类型(int)+一组声明符(多个不同类型的变量,引用类型指针类型)的声明方式是完全合法的。

命名规范:
1 用字母或下划线开头
2 不要_+ _ ,不要_+大写字母
3 变量名用小写字母
4 多个单词用下划线连接,不要一团
5 自定义的类名用大写字母开头


5.1 引用

复合类型
声明的定义:数据类型名+声明符,而基本的声明把变量名作为声明符,而复合类型可以用更复杂的类型作声明符。比如引用:把&d作为声明符,如&d=a,将a作为对象和d绑定在一起。

引用
1 必须初始化,即绑定对象,不能与字面值算术表达式绑定
2 引用本身不是对象,故不能引用的引用
3 对引用类型进行的操作,实际上是对其绑定类型所进行的操作
4 一旦初始化完成,引用类型将和绑定对象一直绑定在一起,无法再重新绑定到另一个对象

5.2 指针

请添加图片描述

学习前提:学习指针一定要搞懂变量,地址,内存等基本知识
作用:指向另外一种类型的复合类型,实现了对其它对象的间接访问。

注意
1 指针本身就是一个对象,允许赋值拷贝,虽无需再定义时赋初值,但没有初始化也拥有一个不确定的值,建议初始化
2 引用不是对象没有实际地址,不能定义指向引用的指针
3 除特例,所有指针的类型都要和它所指向的类型一致。不能int *p=a(double型)
4 访问无效指针将引发错误,后果无法估计
5 指针可以指向指针
6 指针可以先后指向几个不同的对象
需要初始化为空时:建议使用字面值常量:nullptr

声明
int *p=&a;p为变量名,指针变量p存放a的地址,或者说p是指向a的指针(简单理解:*p作为一个对象,而p只用来存储对象的地址)

访问对象: 使用解引用符进行操作,如: * p代表p指向的对象a,对 *p操作就是间接对a操作。

赋值方式:
1 初始化指针存放一个变量的地址;int *p=&a;
2 指针之间相互赋值:int *p=&a, *p2=&b; p=p2;-----p和p2指向同一个对象b

int i=42; 
int &t=i;//声明一个引用类型t绑定对象i
int *p=&i;//声明一个指针p,指向i,p存储i的地址
*P=32;//由*得到p指向的对象,即可间接为变量i赋值
int *&t2=p;//声明一个引用对象,绑定指针变量p;

比较时注意:

 int *p = &a, *p2 =&a;
 if (p == p2){}//比较p和p2指向地址是否相同,(相等情形:都是空指针,都指向一个地址,or一个指向对象,一个指向另一个对象的下一个地址也可能相同的。)
 if(*p==*p2){}//比较a和b的值

特殊的:void * 指针,可以存放任意类型对象的地址,但不能直接操作void*指向的对象,因为不知道是什么类型。一般用于同其他指针比较,作为函数的输入输出等,用于特殊的情形下。


指针的指针
注意:不需要纠结声明中的类型修饰符的意义,只是声明符的一部分而已
指针变量存地址,指针变量的地址由更高级的指针变量来存;
地址就是指针,指针就是地址,变量在内存中的地址可以由指针变量来访问
挂* 符号 访问指向变量的内容,若为普通变量,则是值,若为指针变量,则为地址

int a=10;
int *p = &a;//p是指向a的指针
int **q = &p;//q是指向p的指针
cout << "p的内容,a的地址:" << p << endl;
cout << "p指向变量的值,就是a的值:" << *p << endl;
cout << "q的内容,p的地址" << q << endl;
cout << "q指向变量的值,即p的内容,也就是a的地址:" << *q << endl;
cout << "q指向变量的值指向变量的值,就是a的值:" << **q << endl;

指向指针的引用

二 常用知识理解

三 特殊难点笔记

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。