复习一些自己不常用的术语
缓冲区(buffer)IO设施通常将输入(或者输出)数据保存在一个缓冲区里,读写缓冲区数据和程序中动作无关。我们可以显示刷新输出缓冲,强制将缓冲区数据写入输出设备。
变量与基本类型(如有错误感谢指正)
C++是静态数据类型语言,类型检查发生在编译时,不同于Python等在运行时检查数据类型,编译器必须知道每一个变量的数据类型。
C++定义了一套算术类型和空类型,其中算数类型包含了字符、整型数、布尔值和浮点数,空类型不对应具体的值,用于一些特殊的场合,当函数不返回任何类型时就用空类型作为返回。
算术型:整型(包含字符和布尔类型在内)和浮点
char是8位,short和int是十六位 float有6位有效数字 double是10位
*:计算机以比特序列存储数据,每个比特非0即1,大多以2的幂次方来处理内存,可寻址的最小内存块叫byte,大多数字节由8比特组成,字又由几个字节组成
为了赋予内存某个地址明确的含义,我们要知道代表的类型是什么(不同类型要的位置多少不一样)
带符号类型和无符号类型:带符号的可以表示负数,但是无符号不行。
unsigned char(无符号类型)所有比特都用来存储值,表示0~255 ,而signed char表示-128~127.
类型转换
bool b=12;//b为真
int i=b;//i=1
i=3.14;//i=1
double pi=i;//pi=3.0
unsigned char c=-1;//负数取余 结果c%256=255
signed char c1=256;//c2此时无定义
*:含有无符号类型的表达式:一个算术表达式里面既有int又有无符号数值,int就会自动转化,而且由于无符号要确定结果不是赋值,就会自动取模。所以最好不要混用
字符型:‘’被单引号括起来,“”双引号括字符串
转义序列:有些字符没有可视图符,就不能打印,有一些是转义序列 就比如\n \v \t等
指定字面值的类型:在实际中,我们常会默认一些字面值的类型,比如“19”是int,“3.123323”是double,有的时候加字符,就会显示不一样类型,“3.123323L”是long double。
变量
对象在被创建时,要注意初始化,即创建时赋予它一个特定的值。但是初始化和赋值意义不同,赋值是擦除当前值然后用新值代替。
如果内置类型没有指定初值,就会被默认初始化,一般为0.而定义在函数体内部的内置类型变量不被初始化。
变量声明与编译:C++支持分离式编译,所以声明和定义区区分开来。
extern int j;//声明却不定义
int j;//声明并定义j
//变量只能被定义一次,但是可以声明很多次,如果初始化extern标记变量会报错
声明是让程序知道你的名字,一个其他地方的文件如果想用你就要包含对那个名字的声明,而定义要创建一个实体。
#include<iostream>
int i=40;
int main()
{
int u=0;
std::cout<<i<<" "<<u<<endl;
int i=0;
std::cout<<i<<" "<<u<<endl;
std::cout<<::i<<" "<<u<<endl;
}
这里面的输出结果
40 0
0 0
40 0
第一次的时候全局变量i占据主导
但是第二次局部变量在作用域内,把全局覆盖了
第三次显示调用全局变量,所以是40
引用:给对象再起一个名字。引用必须初始化。
int val1=1024;
int &val2=val1;//val2指向val1 引用是无法重新绑定的 而且后面val2变换val1也会变
int &val3;//报错 引用要初始化
指针: 指针是对象,但是引用不是;允许对指针赋值和拷贝,而且指针声明周期里可以指向不同的对象。2.指针不用在定义时赋初值,如果没有初始化,就会被分配一个不确定的值。
指针的值:指向一个对象/对象下一个位置/空指针/无效指针
野指针:int*p =(int*)0x1100;
只是指向这个16进制的地址,但是没有跟系统申请我要操作。所以是错的。
访问指针的话用*解引用
int *p=0;cout<<*p<<endl;
const限定符:定义以后不能改变。
如果程序包含多个文件,则每个都用到const对象的文件都必须能访问它的初始值,要在每一个用得到的文件进行声明,默认情况是只在当前文件有效。
但有的时候const变量初始值不是常量表达式,但是需要在文件间共享,又不希望编译器给每个文件生成不同的变量,那就在生命和定义时都加extern
extern const int bufsize=fcn();
const int c1=1024;
const int &c2=c1;//正确 常量引用才能用
int &c3=c1;//错误
你常量引用不改就行,其他方式可以改
int i=10;
int &rl=i;//
const int &r2=i;
rl=0;
r2=0;//错误
常量指针和指针常量
常量指针:就是一个除了他自己不能改。
int i=10;
const int *p=&i;
*p=20;//错误
int b=10;
p=&b;//正确
i=20;//正确
指针常量:
int const* p=i;
p=&b;//错误
*:constexpr变量表示常量,或者是你认定是常量的变量。constexpr int sz=size();
处理类型
类型别名:typedef.
typedef double wages
,给double起一个wages的名字
新标准里面可以用 using SI=Sales_Item;
给自定义类型起别名。
auto类型说明符:让编译器替我们去分析表达式所属类型,
auto item=val1+val2;//只能用于类型一样的
但有的时候auto并推不出来正确的类型。
int i=0, &r=i;
auto a=r;//a是一个整数而不是引用
//而且会忽略顶层const,保留底层const;
const int ci=i,&cr=ci;
auto b=ci;//b是一个整数,忽略了顶层const
auto e=&ci;//e是一个指向整数常量的指针
decltype类型指示符:想知道变量的类型,但是又不想用这个表达式初始化变量。
decltype(f()) sum=x;//sum类型是 f()的返回类型
decltype((i)) d;//错误:d是指针需要初始化 双层永远是引用
decltype(i) e;//e是一个没有初始化的int
预处理器概述:确保头文件多次包含仍能安全工作,还有头文件保护符。#define把指令一个名字设定为预处理变量,另外两个指令分别检查某个指定的预处理变量是否已经定义;#ifdef当且仅当变量定义为真 #ifndef 仅当未定义为真。一旦为真,执行后续操作直到遇到#endif为止。
#define定义宏 在预编译阶段把相应字段替换掉
#ifndef 如果宏没被定义,就编译 #ifdef 如果宏被编译 就编译#endif 决定谁被编译谁不被编译