C++ primer知识点总结(基础部分——变量和基本类型六千总结)

一、输入与输出

C++语言并没有定义任何输入输出语句,而提供一个全面的标准库来提供IO机制。

iostream包含两个基础类型:istream和ostream分别表示输入和输出。

cin(istream)为标准输入;cout(ostram)为标准输出;cerr和clog(ostream),cerr用来输出警告和错误信息,clog用来输出程序运行时的一般性信息。

 std::cout<<"ostream:"<>i;//输入

cin(>>)和cout(<<)是程序中最常用的。

上面代码段中的endl相当一个换行符 '\n';

上面程序中使用了std::cout而不是cout,前缀std::是指出cout和cin、endl是定义在名为std的命名空间中的,标准库定义的所有名字都在命名空间std中。

全部像这样写太过于烦锁:我们可以使用using namespace std;来声明。

#include "iostream"
using namespace std;
int main(){
    cout<<"ostream:"<>i;//输入

}

就可以直接写cout和cin、endl了。

C++算术类型:

它分为两类:整形和浮点型

C++算术类型
类型 含义 最小尺寸
bool 布尔类型 未定义
char 字符 8位
wchar_t 宽字符 16位
char16_t Unicode字符 16位
char32_t Unicode字符 32位
short 短整形 16位
int  整形  16位
long 长整形 32位
long long 长整形 64位
float 单精度浮点数 6位有效数字
double 双精度浮点数 10位有效数字
long double 扩展精度浮点数 10位有效数字

上表中的Unicode是用于表示所有自然语言中字符的标准。

布尔类型(bool)的取值只能是真(true)或假(false)。

当我们写程序的时候定义的变量,建议对每一个内置的类型都进行初始化。

带符号类型(signed)和无符号类型(unsigned)

除了布尔型和扩展的字符型之外,其他整形都可以划分为带符号的和不带符号的。带符号的可以表示负数,而不带符号只能表示大于或是等于0的值。

类型 int 、short 、long 、long long 都是带符号的,在它们前面加unsigned就可以成为无符号型,主要记住它们本身是有符号的。其他中无符号整形可以缩写为:unsigned 。

变量声明和定义的关系:

    extern int i;//这是声明i而非定义i
    int j;//这是声明并定义j

变量只能被定义一次在同一个作用域下,但是被声明多次。

建议在定义变量的时候,第一次使用的时候现定义它,不要提前定义它。

C++的标识符由字母、数字、下画线组成,必须以字母或下画线开头。标识符长度没有限制,但是对大小写敏感,命名时不能和C++的关键字一样。

这里也说一下变量名的命名规范:

1.标识符尽量要体现实际含义。

2.变量名一般用小写字母。

3.自己定义的类名一般以大写字母开头。

4.标识符由多个单词组成,则单词间应该有明显区分的标志。

名字的作用域:

作用域:C++语言中的大多数作用域都以花括号分隔,名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束。

#include 
int main(){
int sum=0;
for(int i=0;i <=10 ; i++){
sum+=i;//等价于sum = sum +i
}
cout<<"sum=  "<

全局作用域(全局变量):就是在代码执行的全过程中都可以访问;局部作用域(局部变量):就像上面代码中的 i 变量,它定义在for循环里,一但出了循环体,就访问不到它了,但是可以又可以在循环体外面,重新定义它。

嵌套作用域:包含着别的作用域的作用域叫外层作用域;被包含的作用域叫做内层作用域。 

建议一下:如果函数有可能用到某个全局变量,就不要再定义一个同名的局部变量。

引用(别名):

引用就是对象起另外一个名字。

int ival =1024;
int &refval = ival;//这个refval就是变量ival的另一个名字,它们两个操作的是同一个空间

当我们作用引用的时候必须初始化它,必须初始化,否则会报错。引用不是一个对象,它只是已经存在的对象的另一个名字。

指针(基础):

指针是指向另外一种类型的复合类型。指针本身是一个对象,指针无须在定义时赋初值。

int *p1,*p2; //p1和p2都是指向int型对象的指针
double dp , *dp1; //dp是一个正常的double型的对象,*dp1是一个指向double型对象的指针

int ival = 42;
int *p = &ival; //p存放变量ival的地址,或者说p是指向变量ival的指针
//指针指向的类型必须和所指向内容的类型相同。下面的是错误的:
int ival1 =43;
char * p1 =&ival1;//它们的类型不匹配

空指针:就是指针没有指向任何对象。

int *p1 = nullptr;//C++11的新标准引入的一种方法
int *p2 = 0;
int *p3 = NULL;
//以上三种都是空指针,它们不指向任何对象

C++程序员最好使用nullptr去初始化空指针,同时避免使用NULL;

利用指针访问对象:如果指针指向了一个对象,则我们可以使用解引用符(*)来访问指针所指向的对象。

int ival =42;
int *p   =&ival;
cout<<   *P;//能过指针P的解引用就可以输出ival的值42;
*P  =0;//可通过指针改变指针所指对象的值
cout<< *p;//输出0

建议初始化所有指针,使用未经初始化的指针是引发运行时错误的一大原因。

当指针做条件时:

任何非0指针对应的条件都是true。

int ival  = 1024;
int *pi   = 0 ;//是一个空指针,它的值为0
int *pi2  = &ival;
if(pi)//条件为false,因为pi的值是0
//...
if(pi2) //pi2指向对象的值不为0,因些条件为true
//...

void* 是一种特殊的指针类型,它可以存放任意对象的地址。我们不能直接操作它所指向的对象,因为不知道它所指向对象的类型是什么,并且它能做的事比较有限。以void*的视角来看内存空间也就仅仅是内存空间,没办法访问内存空间中所存的对象。(这个作为了解就行了)

double obj =3.14 , *pd = &obj;
void * pv =&obj;//void* 能存放任意类型对象的地址;obj可以是任意类型的对象
pv= pd;  //pv可以存放任意类型的指针

复合类型的声明:

int i =1024 , *p =&i , &r =i ;
//i是一个整形的数,p是一个int型的指针,r是一个 int 型引用

int* p; // p是int型的指针,而不是int*型的

int* p1 , p2;
//p1是指向int 型的指针, p2 是int型的变量

指向指针的指针:**表示指向指针的指针,***表示指向指针的指针的指针。 以此类推

int ival =1024;
int *p =&ival;//p指向一个Int型的数
int **pp=π//pp指向一个Int型的指针

指向指针的引用:

引用本身不是一个对象,所以不能定义指向引用的指针。但是指针是对象,所以存在对指针的引用

int i =42;
int *p; //p是一个int型的指针
int *&r = p ;//r是一个对指针p的引用
r= &i;//r引用了一个指针,给r赋值&i就是令p指向i
*r =0;//解引用r得到i,也就是p所指向的对象,将i的值改为0

我们理解r的类型是什么,最简单的方法是从右向左阅读r的定义。当我们遇到比较复杂的时候

const限定符:

当我们想要定义一种变量的值不能被改变,就可以用const限定符加于限制(整形常量)

const int du = 520;
du = 520; //这是错误的,du的值是不能被改变的。

const对象一旦创建它的值就不能被更改,所以const对象必须初始化。

int i= 42;
cin>>i;
const int ci =i; //i的值被拷贝给了ci
int j = ci; //ci 的值被拷贝给了j

可以使用定义好的对象去初始化一个const对象。当我们输入i的值后,拷贝给了ci,那么ci的值就不可以改变了。

在默认情况下,const对象仅在文件内有效,就是只在声明并定义它的那个文件内有效,其他文件无法使用它,我们可以利用extren来实现:

extern const int i=1100;

要在多个文件之间共享const对象,必须在变量的定义之前添加extren关键字。

const的引用(常量引用):

可以把引用绑定到const对象上(对常量的引用)。与普通引用不同,对常量的引用不能被修改它所绑定的对象:

const int ci = 1024;
const int &ri =ci;//正确的:引用的对象是常量
ri = 42;  // 错误:ri是对常量的引用
int &r2= ci; //不能让一个非常量引用指向一个常量对象

引用的类型必须和所引用对象的类型一致。但是有两个例外:

就是在初始化常量引用时允许用任意表达式作为初始值,只要这个表达式的结果能转换成引用的类型就可以。
double dval = 3.14;
const int &ri1 =dval;
//上面的代码编译器会改变成下面这样:
const int temp = dval;
const int &ri1 =temp;//这样ri1绑定了一个临时量

如果上面的代码中ri1不是一个常量时,就是把引用绑定到临时量上,这种行为在C++中会归为非法,下面的代码是错误的,会报错,不允许像这样写!!!


double dval =3.14;
int &ri=dval;

对const的引用可能引用一个并非const的对象:

//对const的引用可能是一个非const的对象
int i = 42;
int &fi= i; //把引用fi绑定对象i
const int &rh=i;// rh也绑定对象i,但是不允许通过rh去改变i的值
i=0;//i并非一个常量,所以可以更改它的值
rh=0; //错误,rh是一个常量引用,不能直接改变它的值
cout<<"i=   "<const double pi = 3.14;
double *ptr = π//错误,因为Ptr是一个普通的指针
const double *cptr = π //正确的,它们的类型相同
*cptr = 42;//错误,不能给*cptr赋值

允许令一个指向常量的指针指向一个非常量对象。和常量引用一样,指向常量的指针也没有规定其所指的对象必须是一个常量。指向常量的指针仅仅是要求不能通过这个指针去改变对象的值,而没有规定那个对象的值不能通过其他途径改变。

const 指针(常量指针):

指针是一个对象,所以允许将一个指针本身定义为常量。常量指针也必须初始化。一旦初始化后,它的值(它存放的地址)就不能再更改了。

把*放在const关键字之前用以说明指针是一个常量(不变是的指针本身的值而不是指向的那个值)。

int nub= 0;
int *const cur = & nub;//cur将会一直指向nub,不会改变
cosnt double pi = 3.124;
const double *const pip =π//pip是一个指向常量对象的常量指针

遇到复杂的定义用我们前面讲过的方法:从右向左阅读。

上面代码中的cur为例:cur旁边是const(从右向左)说明cur本身是一个常量,然后下一个符号是*,表示是一个指针,最后综合得到cur是一个常量指针。(如果看到这里,请利用这种方法说出pip的类型打在评论区)

顶层const:

顶层const:表示指针本身是个常量。

底层const:表示指针所指的对象是一个常量。

指针可以是顶层const的同时也是底层const。

int i  = 0;
int *const p1 =&i; //不能改变P1的值,这是一个顶层const 
const int ci = 42; //不能改变ci的值,这是一个顶层const
const int *p2 =&ci;//允许改变p2的值,这是一个底层const
const int *const p3 = p2; //靠右的const是顶层const ,靠左的是底层const 
const int &r =ci ; //用于声明引用的const都是底层const

当执行对象的拷贝操作时,常量是顶层const还是底层const区别明显,但是顶层const不受影响:

i =ci ;//正确的:拷贝ci的值,ci是一个顶层const,这个作用无影响
p2 = p3;//正确的:p2和p3指向的对象类型相同,p3顶层const的部分不影响。
//执行拷贝操作并不会改变拷贝对象的值,拷入和拷出的对象是否是常量都没有什么影响。

而底层const的限制不能忽视:

当执行拷贝操作时,拷贝的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说:非常量可以转换成常量,反过来则不行:

int *P = p3;// 错误:p3有底层const的定义,但是P没有
p2 = p3;//正确:p2 和p3都是底层const
p2 = &i; //正确:int*能够转换成const int*
int &r =ci;//错误:普通的int&不能绑定到Int常量上
const int &r2= i;//正确:const int&可以绑定到一个普通Int上

上面的代码中,p3是顶层const同时也是底层const,拷贝p3的时候可以不在乎它是一个顶层const,但是必须清楚它指向的对象是一个常量(要注意它的底层const)。p3的值可以赋给p2,是因为它们两个都具有底层const的性质,虽然p3同时也具有顶层const的性质,就这次赋值不会有什么影响。


 

你可能感兴趣的:(C++ primer知识点总结(基础部分——变量和基本类型六千总结))