00初始化/赋值
初始化:
1.在内存中开辟空间,保存相应的值
2.编译器构造符号表,将标识符与相关内存关联起来.
初始化和赋值都会涉及到类型转换
int x=3;
int y=3.0;
3 3.0 为字面值 x y 是变量也是标识符
01类型
C++是强类型的语言,类型是一个编译期的概念,编译完成后没有类型的概念.
引入类型是为了跟好的描述程序,防止误用,C++是一个注重性能的语言.
类型描述了:
1.储存所需尺寸的 大小,不同的编译器大小 可能不一样
eg: sizeof(int)=4 -----4字节 32位 (86位机)
2.取值空间的大小 (超出范围会下溢或者上溢)
eg: int [-2^32,2^32] insigned int [0,2*2^32]
3.对齐信息
4.可以执行的操作 + - * /
类型可以划分为:
內建类型 :
数值类型:
字符类型(char char16_t)
整数类型:有符号short int long 和无符号 unsigned int
浮点类型: float double
复杂类型:
由基本类型组合,变种产生.
标准未定义类型部分:
char 是否有符号
unsigned char signed char char---未知
整数在内存中保存的方式:大端 小端.
(大小端一般和底层硬件有关,做通信时,一般统一转化为大端或者小端再通信)
每种类型的大小
C++11引入固定尺寸的类型 int32_t int64_t
02变量
变量:对应了一段储存空间,可以改变其中的内容.
变量的声明与定义:
main.cpp
extern int g_x; 用extern 表示已经申明 否则报错 重复定义
int main()
{
cout<<g_x<<endl;
}
souce.cpp
int g_x;申明
变量的初始化: 在构造变量时赋予的初始值.
1.缺省初始化 int x;
2.拷贝初始化 int x=10; 全局变量初始化默认是0 局部变量初始化随机
3.直接初始化 int x(10);
4.其他初始化
变量的赋值: 修改变量所保存的值.
变量类型的转化(隐式)
变量赋值时的转换:
int x=9.0 float x=3.9
bool与整数的转换: bool x=1 (0 ----false 非0-------true)
(false ----0 true ------1)
if判断 数值比较也会发生类型转换
eg: 有符号和无符号比较 默认将有符号转化为无符号 再比较
03指针
指针:一种间接的类型.(储存的是地址)
特点:
1.可以指向不同的对象
2.具有相同的尺寸 64位机:sizeof(int *)=8 sizeof(char *)=8
相关操作:
& -----------取地址符号
*-------------解引用
Note:
指针是一种间接的类型 ,因为指针存的是首地址,若进行指针的加减操作,则需要知道移动几个地址,这就由指针的类型来决定了.
eg: int *p =&val; p存储的是0x1234
int val=69; val是int类型 占4个字节 存储地址是:0x1234 0x1235 0x1236 0x1237
int x=9;
int *p=&x;
*是声明一个指针 int确定指针的类型
int* p 声明p是一个int类型的指针
cout<<*p<<endl;
*-----在指针p前面 代表解引用 *p代表指针p所存地址的值
指针的定义:
int *p=&val;
int *p=nullptr;
int *p=0 ;涉及到int转化为int* 是一种不安全的行为
nullptr-------C++中的空指针 也代表任意类型的指针
指针与bool转化:
空指针--------false 非空指针--------------true
指针的主要操作:
解引用 增加 减少 (移动) 判等
int x=89;
int *p=&x;
p=p+1; 一次移动一个int大小
p=p-1;
void*指针 ------没有记录对象尺寸信息 但是可以保存任意的地址 也可以转化为任意指针 但是不能移动 因为没有指定大小.
指针和对象区别:
因为任意类型指针大小是固定的 ,所以指针传递时,复制成本低,但是需要两次访问内存,所以读写成本高.
传指针与传值
#include<iostream>
using namespce std;
void func1(int *param) 定义param是int的指针
{
*param=*param+1; paran解引用
}
void func2(int param)
{
param=param+1;
}
int main()
{
int x=9;
fun1(&x); 传入x的地址 &---取址符号
fun2(x); 传值 若x的类型大 或者为结构体 会将x复制给param 增加消耗
}
指针的问题:
指针可以为空
地址信息可能非法
引用------就可以解决指针问题
04引用
int &ref=val 引用是对象的别名 不能绑定字面值 必须在构造时绑定对象,并且在生命周期内不能绑定其他值 解决了指针为空的问题
不存在空引用 但是可能存在非法的引用 总之 比指针安全
引用底层是通过指针来实现的 和指针一样 也是编译期的概念
指针是对象 因此可以定义引用
int *p=&val
int * &ref=p; --------从右往左解读 优先是一个引用 类型是int *
#include<iostream>
using namespace std;
void func(int ¶m) -------int ¶m=x
{
param++;
}
int main()
{
int x=0;
func(x);
return 0
}
06常量
使用const声明常量 是一个编译期的概念
优点: 防止非法操作 优化程序逻辑
常量指针:
const int * p 等价于 int const *p *p不能更改(值不能改) p=&y 指向可以更改
指针常量:
int * const p p不更更改(指向不能改) *p=8值可以修改
const int * const p 都不能改
常量指针可以指向变量 -----------增加了限制 int x=9; const int *p=&x;
普通指针不能指向常量 const int x=9; int *p=&x(报错)
常量引用: const int &
可读但是不可写
主要用于函数形参 (防止函数误操作,改变了传入的形参)
可以绑定字面值 const int &ref=3(合法)
#include<iostream>
using namespace std;
void func(const int ¶m) -------const int ¶m=x param不能写
{
cout<<param<<endl;
}
int main()
{
int x=0;
func(x); 底层将地址传递到了param
return 0
}
07类型的自动推导
类型别名:
typedef int Myint
using Myint =int (C++11引入) 推荐使用
类型的自动推导:
C++11开始 ,可以通过表达式自动推导对象的类型 int x=3.5+15 auto x=3.5+15
自动推导的常见形式:
auto 常用形式 但会产生类型的退化
eg: int x1=3; int &ref=x1 ;int y=ref (ref是int类型引用作为右值时,退化为int ) auto nn=ref -------nn是int 而不是int & ----------引用作右值时退化为相应类型
const auto 推导出是常量
auto & :推导出引用类型不退化 const int x=9; auto& y=x; y是const int &
decltype(exp) --------略
08 域---生命周期
域:代表程序中的一部分
全局域 块域 类域等
域的嵌套:嵌套域中定义的名称隐藏了外部域定义的名称
全局对象: 生命周期-----------整个程序运行期间
局部对象: 生命周期------------对象创建开始,在域被执行完成自动销毁 栈区:生命周期自动管理 堆区:手动管理