变量和基本类型

Posted huangqiang97

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变量和基本类型相关的知识,希望对你有一定的参考价值。

1:基本内置类型:
1:算数类型:整型(int ,char,bool,),浮点型。
2:c++规定int 至少要和short一样大,long至少要和int 一样大,long long 至少要和long一样大。
3:单精度是这样的格式,1位符号,8位指数,23位小数。
双精度是1位符号,11位指数,52位小数。
4:给一个无符号类型赋值超过它的最大值或者小于他的最小值的时候,赋值结果为初始值对应补码,(除以该无符号能表示的数字个数(最大值加一)的余数?)。对有符号数同样操作结果为未定义。
5:int +unsigned int:int 会变为unsigned int ,正数数字不变,负数为其补码。
从一个无符号数中减去一个数值,不管这个值是否是无符号数,结果都不能是负数。
无符号数字无法表示负数,即使是负数,也会变为对应的补码。

6:泛化转义字符:用x后的16进制数,或者后面的8进制数表示相应的意义。如:12表示换行,x4d表示字符M.

八进制数只取前三个,后面的当作另外的字符,16进制数取全部数字。

7:t添加前缀后缀改变默认类型:

3.14159L:long double, 1E-3F:float. 42uLL:unsigned long long . 12L:long 1.2F:float 12U:unsignedd int

8: 对a初始化:int a=1,int a={1},int a(1),int a{1}.{}处理称为:列表初始化,当存在精度丢失时会报错,而()不会。

9:定义于任何函数体外的内置类型默认初始化为0,定义于函数体内的内置类型不会被初始化。未被初始化的内置类型是未定义的,访问会报错。自定义类的默认值由自身性质决定。建议初始化每一个内置类型。

10:声明:规定变量类型与名字(不要显示赋值,否则就变成了定义extern int i=1等价于int i=1,在函数内部这样做还会引发错误) extern int i。 定义:规定变量类型与名字,分配内存空间,还有可能给初始值。 int i,变量只能一次定义,但可以多次声明。

11:若要在多个文件中使用同一个变量,变量的定义必须且只能在一个文件中定义,可以在多个文件中声明。

12:自定义标识符不能连续出现两个下划线,不能以下划线连接大写字母开头,定义于函数外的标识符不能用下划线开头。

13:不同作用域中可以声明同名变量。内外作用域下可以再内作用域下声明与外作用域同名的变量,访问遵循就近原则。Java中内外作用下不能声明同名变量,成员变量与方法的形式参数例外。

14:引用:int a=1;int &b=a;引用对象初始化完成后将一直和被引用的对象初始值绑定,不能更变绑定对象,所以引用必须初始化。(int &b错误)对b 的赋值、读值实际是对a的操作二者数值同步变化。引用并非对象,而是对已有对象起一个别名,所以不能定义引用的引用。int c=2;int &d=c,e=c;int &g=b;d,g为引用,e为int。引用类型要匹配,引用只能绑定对象而不能是某个字面值,或者表达式,int &f=1;错误,静态对象可以绑定字面值:const int &a=1。

15:指针本身为一个对象,可以对指针赋值拷贝,可以先后指向不同对象,指针无需下定义时赋初值。

int a=1,*p1=&a,*p2=p1;指针存放某个对象地址,用&火的某个对象地址。p1为指向一个int 类型的指针,初始化值为a的地址。

引用不是对象,无法为引用创建指针。
*作用:定义时表明这是一个指针,在后续操作中通过*p1解析p1地址获得所指向的对象。对*p1的操作等价于对a操作。
空指针:int *p1=nullptr,*p2=0,*p3=NULL;
不能值为0的变量赋值给指针来获得空指针式是错误的。int a=0,*p4=a;(错误),
p3=&a;p4实际指向变量a.
访问空指针时:指针内存空间的当前值会被作为指针所指对象的地址,依据这个可能不存在的地址值去访问对象。建议初始化所有指针,实在不知道指针该指向何处,就把他设为空指针。
p1=&a:改变p1存储的地址值,*p1=1:改变p1所指向的对对象的值,p1存储的地址没变。
指针->bool :空指针:false,非空:true.
void *:一类特殊指针,可以存放任意类型地址,指向任意类型。void* ptr=p1;
无法操作ptr所指对象,因为类型未知。
类型要统一:无法实现类型自动提升、下降。
16:尽量把修饰符和变量名写在一起,如果修饰符和基本类型写在一起容易产生歧义。
17:指向指针的指针:int a=1,*p1=&a,**p2=&p1;p2存储p1的内存地址,*p2:代表p1,**p2代表a.
18:指针的引用:int i=42,*p,*&r=p;r=&i;(i,*p,*r:42,42,42),
*r=0;(i,*p,*r:0,0,0).面对复杂定义从右往左读,越靠近变量的符号影响越大,int *&r=p;首先r是一个引用,其次是int 指针的引用。
19:常量:const修饰,一旦创建后值不能在改变,创建时必须初始化。const int a=1;
const int b=function();只要不涉及改变常量值的操作都是合法的。int c=a.
const int d=1,e=d;d,e都是常量。
const常量默认只能在本文件中使用,要想多文件共享:定义时:extern const int a=1,在其他要使用他的文件中:extern const int a;声明它。
对常量的引用类型要完全一致:const int &e=a.
允许为一个常量引用绑定一个非常量的对象,字面值,一般表达式,只要表达式结果能转化为所需类型即可,引用类型不一定要与被引用对象类型一致。const int &a=23(正确),int &b=a(错误)。
double d = 2.2; const int &e = d(正确)
常量引用仅对引用所能参加的运算加以限定,未对引用的对象本身是否是常量做出限定。
int d = 2;
int &e = d;
const int &f = d;
d,e,f:2,2,2,
d=3;
3,3,3
e=4;
d,e,f:4,4,4
f=5;(报错)
19:指向常量的指针。类型要完全对应,且不能通过指针改变常量的值。
const int a=1;
const int *p=&a;
*p=2;(错误)

指向常量的指针也可以不指向常量,
int a=1;
const int *p=&a;
不能通过*p来改变a的值,但可以通过其他途径改变a的值(a=2;)
指向常量的指针在定义时可以先不初始化:const int *p;常量指针必须初始化: int *const p=&h;
20:常量指针:必须初始化,int a=1,*const p=&a;p所指向的内存地址不变,即一直指向a,而非a的值不变。指针常量强调该指针是一个常量,对说指向的对象是否是常量没有要求。
const int *const p1 = &a;(a为常量,无法通过*p1修改a.)
int *const p2 = &d;(d为非常量,可以通过改变d来改变*p2,也可以用*p2修改d)
const int *const p3 = &d;(可以通过d改变*p3,无法用*p3改变d)
int *const p4 = &d;(可以用d改变*p4,*p4改变d)
int *const p5 = &a;(错误)
int *p6=&a;(错误)
int *p7=&d;(可以用d改变*p4,*p4改变d)
const int *p8=&a;(不能通过p8改变a,p8可以指向其他对象)
const int *p9=&d(不能通过p8改变a,可通过d改变*p8,p8可以指向其他对象);

21:常量的引用或者指针的类型为必须指向常量:const int *p;const int &y;无法通过*p,或者y改变对象值,p可以修改指向其他对象。
指向常量的指针或者引用所指对象不一定是常量.无法通过*p,或者y改变对象值,对于元对象非常量的,可以通过对象达到修改*p,y的目的。
常量指针强调指针所指向的地址不变,地址中内容可变。
22:顶层const表示自身为常量,底层const表示自身所指的对象是常量。
const int *p1;底层const. int *const p2=&i;顶层const.
const int *const p3=&i;第一个为底层,第二个为顶层。
const int j=2;顶层
执行对象拷贝时顶层const不受影响,考入和考出的对象要有相同的底层const,或者考出的底层可以转变为考入的底层const.一般非常量可以转化为常量,常量无法转化为非常量。
const int *const p1=&g;
int *p2=p1‘(错误,常量无法转变为非常量)
int i=1;
p1=&i;(正确非常量可以转化为常量)
const int ci=2;
int &r=ci;(错误,静态不能到非常量)
const int &r2=i;(正确)
23:常量表达式:在编译阶段就能得到计算结果的表达式
const int a=1;(常量表达式)
const int b=function();(不是常量表达式,要在运行阶段才能得到值)
将变量声明为 constexpr由编译器验证表达式是否是常量表达式。
constexpr int a=1;(20是常量表达式)
constexpr int b=a+1;(a+1是常量表达式)
constexpr int c=function();(只有在function 是constexpr函数式,才是正确的常量表达式,constexor函数编译期间就得到结果)
constexpr用到的类型称为字面值类型:
算数 类型,指针,引用属于字面值类型。
自定义类,IO库,string类不属于。
一个constptr指针要为nullptr或者0,或者存贮于固定的内存地址中的对象。
函数体内的变量一般非存放在固定地址中。定义于函数外的变量内存地址固定。
constptr定义等价于顶层const.
constptr int *p1=nullptr;//p1指向整型的常量指针。
const int *p2=nullptr;//p2指向整型常量。
constptr const int *p3=&i;//常量指针,指向整型常量。i要定义于函数外。
constptr既可以指向常量也可以指向非常量。
24:给类型起别名
typedef double base,*p;//base等价于double,p等价于double *.
using base=double;//base等价于double .
复合类型的类型别名,要视为一个整体,不要拆开理解。
typedef char *pstring ;
const pstring cstr=0;//cstr是指向char的常量指针。
const char* cstr;//cstr是指向char常量的指针。
const pstring *ps;//ps是一个指针,他的对象是指向char的常量指针。
25:auto类型:
自动确定变量类型:
auto i=0,*p=&i;//这里auto确定为int。
auto i=1,j=2.13;//错误,一条声明语句只能有一个类型。
auto一般会忽略到顶层const 保留底层const(对他修饰的变量而言).
对对象取地址是底层const .
const int ci=0,&cr=ci;
auto b=ci;//b为非常量整型。
auto c=cr;//c同b. 对于引用作为中间变量的赋值运算要通过引用找到原来的对象进行const 判断真正参与初始化的是原来的对象,等价于auto b=const int ci ,b为int,而不爱要通过引用变量来判断,如ci为底层const,就认为b也为底层 const int。
auto e=&ci;//e为指向整型常量的指针。
const auto f=ci;//f为const int
引用顶层仍然保留,顶层对象的引用属于底层引用。


auto &g=ci;//g为const int 引用。
const auto &j=32;//可以为常量引用绑定字面值。
auto &h=0;//错误。
auto代指复合类型时类型要统一
auto &n=i,*p=&ci;//错误,i为int ,auto该是int,ci是const int auto该是const int .
26:decltype:
选择并返回类型,但不计算表达式的数值。
如何表达式是一个变量,就返回变量的类型,包括顶层const,引用(引用视为一种类型被返回,而不是返回引用所指向的队形类型)
const int ci=0,&cj=ci;
decltype(ci) x=0;//const int
decltype(cj) y=x;//const int &
引用一直是为元对象的同义词出现,只在这里出现例外。
int i=42,*p=&i,&r=i;
decltype(r+0) b;//int
decltype(*p) c;//int&,解析操作得到int,返回他的引用。
表达式内容是解析引用操作,将得到引用类型操作。
对变量加上括号,结果将是引用。加上括号编译器把他视为赋值表达式,变量是一种可以作为赋值语句左值的特殊表达式,会返回左值的引用类型所以会得到引用。
decltype((i)) d=&i;//int &
decltype(i) e;//int
赋值会产生引用的表达式,返回左值的引用类型。
27:自定义数据结构;
struct 类型名{/* ....*/};数据结构以分好结束。struct{/*...*/} a;类型的定义+变量的定义,不建议。
成员变量可以赋初值,如果不认为赋初值,会自动赋初值,参见变量的赋初值。赋值方式;{}里面,=右边,不能用()赋值。
? 27:头文件与类同名,头文件中经常定义只能定义一次的实体,如类,const,constexpr等
保证头文件多次包含正常工作机制:
1:预处理:预处理器看到:#include 就会用指定的头文件替换#include.
2:头文件保护符:头文件保护符依赖于预处理变量。预处理变量两种状态:已定义,未定义。 #define 把一个名字设为预处理变量。#ifdef仅在变量定义时为真,#ifndef仅在变量未定义时为真,一旦发现未定义就执行到#endif,如果发现已定义就跳过#ifndef 到#endif间内容。
#ifndef SALE_DARA_H
#define SALE_DATA_H


#include<string>
#include<iostream>
struct myStruct {
std::string bookSBN;
int totalMoney = 0;
int soldAmount = 0;
double price;
double avgPrice;
};


#endif
预处理变量名一般用类名_H,全大写。
28:常量指针:顶层const.
常量引用:底层const.
29:全局作用域:位于所有作用域外的区域。
30:作用域:全局,类(定义于类里),命名空间(名字定义在命名空间内部),块。
31:struct 用来定义类。


























































































































































































以上是关于变量和基本类型的主要内容,如果未能解决你的问题,请参考以下文章

Java 数据类型和变量

JS变量作用域和内存问题

基本数据类型和引用数据类型的区别是啥

变量,基本类型,数据类型和运算符

变量,基本类型,数据类型和运算符

变量和基本类型