1. C++基础上

QT Creator中C++工程创建

在这里插入图片描述
在这里插入图片描述

中文乱码问题:QT是mini gnu for windows,mini gnu用utf8编码,但windows不是,因此会中文乱码。通过 工具 -> 选项开始设置。设置之后需要新建工程,对当前工程无效

在这里插入图片描述

C++基础

基础知识

Hello World程序

# include <iostream> //头文件包含,<>是系统头文件,标准输入输出流

//使用命名空间std
//如果不加这句,无法直接使用cout,需要写成std::cout,表示cout来自std
using namespace std;

int main(int argc, char *argv[])
{
    // cout定向输出,endl换行,可以不换
    cout << "Hello World!" << endl;
    return 0;
}  

变量

以int为例,int a=100,则系统会开辟一个4字节的空间。a是变量名,对变量名的操作等价于对空间等操作

void data; //报错,void不知道类型,系统不知道为data开辟多大的空间
变量的初始化

只有在定义变量的时候,给变量赋值是初始化

int num = 10; //初始化
int num;
num = 10; //不是初始化,而是赋值

普通局部变量,如果不初始化,它的值不确定

全局变量(函数外定义的变量),如果不初始化,值为0

变量的声明 extern

变量的定义:创建变量名,开辟空间

变量的声明:对变量类型和名称事先说明,不会为变量开创空间

变量的使用:对已经存在的变量的读写

extern int data; //提前:变量声明。在需要先使用后定义的变量时,需要用extern关键字提前声明,表示外部可用,表示全局变量
void test{
    cout<<"data="<<data<<endl; //先使用
}
int data = 0;	//后定义;注意这一句应当放在函数外部

这种一般用于跨文件编程

键盘输入cin
/* 键盘获取最大值,并求最大值 */
// cin会跳过其实的空格和回车
int num1 = 0;
int num2 = 0;
cin>>num1>>num2;	//输入两个值
if (num1>num2) cout<<num1<<endl;
else cout<<num2<<endl;

数据类型

整数型

如int

字符型

1. 字符变量

ch = 'x'; //从存储上讲,存储的是ASCII码值,120
cout<<(int)'x'<<endl; //输出ASCII值
//关于字符的初始化,可以初始化为'\0'
char c = '\0';

字符案例——大小写转换

char ch = 'a';
ch = ch-('a'-'A'); //小写转大写,也可以直接写成ch = ch-32

char ch = 'A';
ch = ch+('a'-'A'); //大写转小写,也可以直接写成ch = ch+32

2. 字符串

'a’是字符常量,只占一个字节

"a"是字符串常量,占2个字节,因为字符串会自动添加 ‘\0’ 作为结尾

实数型(浮点数)

浮点数能够表示带小数的类型

计算机将这样的值分为两部分存储,一部分表示值,另一部分用于对值进行放大或缩小。如34.1245可以看成是0.341245(基准值)和100(缩放因子)。

C++内部表示浮点数的方法与此相同,只不过它基于的是二进制,因此缩放因子是2的幂,不是10的幂。

实数型分为:单精度浮点数(float 4字节)双精度浮点数(double 8字节)

1. 实型常量

不以f结尾的实型常量为double类型,如3.14

以f结尾的实型常量为float类型,如3.14f

指数形式:3.14e3表示3140

2. 实型变量

float f = 0.0f;	//末尾必须加f
double d = 0.0; //末尾不用加标识

有符号数和无符号数

有符号数

数据二进制的最高位为符号位,其他位为数据位

​ 最高位为1,表示负数

​ 最高位为0,表示正数

因此对于1字节,有8 bit,也就是有7位可表示数据位,因此

​ 最大值表示为0b01111111,代表127 (首位不计入计算)

​ 最小值表示为0b11111111,代表-127

注意:如果这样算,那么1字节的范围为-127 ~ 127

​ 但是由于0b10000000和0b00000000分别表示将 -0 和 +0,因此将 -0 作为 -128,所以规定的1字节范围为-128~127

cout<<bitset<8>(-128)<<endl; //输出:10000000
无符号数

没有符号位,因此所有二进制位都是数据位,以1字节为例

00000000 ~ 11111111 表示范围为 0~255

int num; //默认为有符号,相当于signed int num;
unsigned int num; //无符号数,不能省略unsigned

进制

二进制、八进制、十六进制
  1. 二进制
//cout需要使用bitset<位数>(数值),位数一般是8,16,32
cout<<0b00001010<<endl; //以十进制输出,C++不直接支持二进制
cout<<bitset<8>(0b00001010)<<endl; //需要引入<bitset>头文件
  1. 八进制
cout<<oct<<0123<<endl; //使用oct输出八进制
  1. 十六进制
cout<<hex<<0xab<<endl; //使用hex输出十六进制
进制转换
  1. 十进制转其他进制

短除法:用十进制依次除以进制n,得到的余数反向排列

  1. 其他进制转十进制

位次幂:……xn2+yn1+zn0

  1. 二进制转八进制

从右往左:每3位二进制对应1位八进制

  1. 二进制转十六进制

从右往左:每4位二进制对应1位十六进制

  1. 八进制转二进制

每1位八进制对应3位二进制

  1. 十六进制转二进制

每1位十六进制对应4位二进制

  1. 八进制和十六进制之间的转换(没有直接方法)

利用二进制作为中间进制,进行八进制和十六进制的转换

原码、反码、补码

概述

原码:计算机中对数字的二进制定点表示方式

123:原码0111 1011

  1. 无符号数:补码 == 反码 == 原码

  2. 有符号数

​ 正数:补码 == 反码 == 原码

​ 负数:反码 == 原码符号位不变,其他位按位取反

​ 补码 == 反码+1

​ -123原码:1111 1011

​ -123反码:1000 0100

​ -123补码:1000 0101

负数在计算机中以补码的方式存储

非负数在计算机中以原码的方式存储

二进制、八进制、十六进制以原码方式存储

补码的意义
  1. 统一了0的编码
+0补码:0000 0000
-0补码:0000 0000	//去掉最高位,仅保留位
  1. 将减法运算变成加法运算

例:没有补码:10-6

10:		0000 1010
-6:		1000 0110
--------------------
		1001 0000		//将10的原码和-6的原码相加,结果为-16,不正确

有补码:10-6

10:		0000 1010
-6:		1111 1010
--------------------
		0000 0100		//将10的原码和-6的补码相加,结果为6,正确
对数据的存
  1. 负数

负数以补码的方式存储在计算机中:查看 -10 在计算机中的存储方式

short data = -10; //short占2字节,即16 bit
cout<<bitset<16>(data)<<endl;
//输出:1111111111110110

-10的原码:1000 0000 0000 1010 (最高位在第16位)

-10的反码:1111 1111 1111 0101

-10的补码:1111 1111 1111 0110

  1. 二进制、八进制、十六进制

以原码存储,不再以最高位表示正负

short data = 0x8080; //以十六进制为例
cout<<data<<endl; //输出:-32640,但实际上Ox8080在十进制下为32896
cout<<bitset<16>(data)<<endl; //输出:1000000010000000,算上最高位转为十进制为32896

输出 -32640 是因为将其最高位作为负数计算了(实际上十六进制不能这样输出)。

-32640的补码:1000000010000000

-32640的反码:1000000001111111

-32640的原码:1111111110000000

对数据的取

无符号变量:输出内存的原样数据

有符号变量:(1)最高位为0,表示正数,内存原样输出

​ (2)最高位为1,表示负数,说明内存中存的是补码,于是倒退得到反码和原码,再输出负号和去掉最高位的原码值

/* 1. 无符号变量的取 */
unsigned short data = -10;
cout<<bitset<16>(data)<<endl; //输出:1111111111110110,为-10的补码形式
cout<<data<<endl;  //输出:65526,将内存的进制原样输出,即计算机没有意识到这是补码,而将-10的补码转成了10进制
/* 2. 有符号变量的取 */
short data = -10;
cout<<bitset<16>(data)<<endl; //输出:1111111111110110,为-10的补码形式
cout<<data<<endl;  //输出:-10,检测最高位,发现为1表示负数,于是执行补码-反码-原码的转换,再输出

有关二、八、十六进制的取,已在上面展示过了

关键字

在这里插入图片描述

const 修饰普通变量

const修饰data为只读变量,使得data只能被初始化,不能被赋值

const int data = 10; //初始化
data = 11; //报错!!

(1)当以常量初始化const修饰的变量时,只读变量data的值将事先存放在符号常量表中,不会立即给data开辟空间

当对data取地址时,才会为其开辟空间

const int data = 10;
int *p = (int *)&data; //此时才会为data开辟空间,data将同时存在于符号常量表中和内存空间中

*p = 200; //修改p指向空间的值
cout<<*p<<endl; //输出:200
cout<<data<<endl; //输出:10
//data和p互不影响

(2)当以变量初始化const修饰的变量时,会立即分配存储空间,而不会放到符号常量表里

int a = 10;
const int data = a; //以变量初始化data
int *p = (int *)&data;

*p = 200; //修改p指向空间的值
cout<<*p<<endl; //输出:200
cout<<data<<endl; //输出:200
//data和p相互影响

两种情况下输出 p 和 &data,都会发现两者相同

(3)当以自定义类型变量(如结构体)初始化const修饰的变量时,也会立即分配存储空间

register修饰寄存器变量

如果变量被高频率使用,会自动将变量存储在寄存器中,目的:提高访问效率

如果想将变量直接放入寄存器中,可以加register修饰

一般的数据放在内存中。CPU处理速度快,但调用内存中的数据比较慢

寄存器在CPU中,放到寄存器中的数据调用起来更快

register int data = 0; //data放在寄存器中,而非内存中

尽量对寄存器变量取地址操作,如&data,放在寄存器中的变量没有地址。但是register修饰的变量只是尽量放在寄存器中,因为大小有限,放置失败的变量将仍被放入内存中

也就是没有register修饰的变量可能放入寄存器中;有register修饰的变量有很大可能放入寄存器中

volatile 关键字

强制访问内存

举例场景:以一氧化碳传感器为例,需要每n分钟收集一次浓度值。以data表示该值,变量存储在内存中

由于data被时常使用,系统会自动将data再复制到寄存器中,于是更新时的顺序是 传感器 -> 内存 -> 寄存器

可能出现内存中的数据被更新,但寄存器中的浓度未被更新。CPU读取寄存器中的变量没有获得及时数据,对于部分敏感数据可能造成严重影响。

volatile强制每次都从内存中读取,而不管该变量是否被复制到了寄存器中

volatile int data = 0; //对data的访问,必须从内存访问
typedef给已有的类型取别名

注意:不能创建新的类型

/* 1. 为int数据类型取别名 */
typedef int INT32; //INT32就是int类型的别名
INT32 data = 10; // 用别名定义变量
/* 2. 为 int arr[5]取别名 */
typedef int MYARRAY[5];
MYARRAY arr = {1,2,3,4,5}; // arr是一个5个数的数组
/* 3. 给int *取别名*/
typedef int *MYP;
MYP p; //p代表int *类型
转义字符
'\0' == ASCII为0
'\n' == 换行
'\t' == tab缩进符
'\r' == 回到行首符号;cout<<"##"<<'\r'<<"##"<<endl,最终只输出一个“##”,因为光标回到行首,被覆盖
'\a' == 发出警报
'\ddd' == 八进制转义,如'\123';每个d的范围为0-7
'\xhh' == 十六进制转义,两个h表示最多识别2位十六进制;如'\xab'

类型转换

自动类型转换

占用内存字节少的类型向占用内存大的内心的转换,可以自动转换。这可以保证精度不降低

由低到高转换:char, short -> signed int -> unsigned int -> long ->double;还有float -> double

(1)无符号和有符号参加运算,有符号转换成无符号

// -10+6,前者有符号,后者无符号,最终结果>0
int data1 = -10;
unsigned int data2 = 6;
if (data1+data2 > 0) cout<<">0"<<endl; //输出:>0
else cout<<"<=0"<<endl;

(2)int和double参加运算,int转为double

(3)char和short只要参加运算,就将自己转为int类型;因为char和short的运算容易越界

强制类型转换

(类型说明符)(表达式)

(int)p+1	对p强制转换成int类型,然后再+1
(int)(p+1)	将p+1强制转换为int类型

无论是自动转换还是强制转换,都是临时的,不影响原变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值