前言:
今天你们对“c++绝对值”大约比较注意,兄弟们都想要知道一些“c++绝对值”的相关资讯。那么小编也在网摘上网罗了一些有关“c++绝对值””的相关知识,希望看官们能喜欢,大家一起来了解一下吧!一段程序的核心有两个方面:一个是要处理的信息,另一个就是处理的计算流程。计算机所处理的信息一般叫做“数据”(data)。
对计算机来说,需要明确地知道把数据存放在哪里、以及需要多大的存储空间。在机器语言和汇编语言中,我们可能需要充分了解计算机底层的存储空间,这非常麻烦;而在C++程序中,我们可以通过“声明变量”的方式来实现这些。
1.1、变量和常量为了区分不同的数据,在程序中一般会给它们起个唯一的名字,这就是所谓的“变量”。在C++中,“变量”其实就是记录了计算机内存中的一个位置标签,可以表示存放的数据对象。
想要使用变量,必须先做“声明”,也就是告诉计算机要用到的数据叫什么名字,同时还要指明保存数据所需要的空间大小。比如:
#include<iostream>using namespace std;int main(){ int a = 1; cout << "a = " << a << endl; cin.get();}
这里包含两个信息:一个是变量的名字,叫做“a”,它对应着计算机内存中的一个位置;另一个是变量占据的空间大小,这是通过前面的“int”来指明的,表示我们需要足够的空间来存放一个“整数类型”(integer)数据。
变量名也可以有多个,用逗号分隔就可以。
在C++中,可以处理各种不同类型的数据,这里的int就是最基本的一种“数据类型”(data type),表示一般的整数。
当然,如果我们直接在代码中声明一个变量,然后打印输出的话就会报错,因为这个变量没有被“初始化”。也就是说,a这个变量现在可以表示内存中一个位置了,但是里面的数据是什么?这就需要让a有一个“初始值”:
int a = 1;
C++是一种静态类型(statically typed)语言,需要在编译阶段做类型检查(type checking)。也就是说所有变量在创建的时候必须指明类型,而且之后不能更改。对于复杂的大型程序来说,这种方式更有助于提前发现问题、提高运行效率。
注意,如果不给初始值,后面再赋值、再使用也是合法的;但一般不能不赋值、直接使用。因为在函数中定义的变量不被初始化,而在函数外部定义的int变量会被默认初始化为0值。
1.3、标识符每个变量都有一个名字,就是所谓的“变量名”。在C++中,变量、函数、类都可以有自己专门的名字,这些名字被叫做“标识符”。标识符由字母、数字和下划线组成;不能以数字开头;标识符是大小写敏感的,长度不限。此外,C++中还对变量命名有一些要求和约定俗成的规范:
不能使用C++关键字;不能用连续两个下划线开头,也不能以下划线加大写字母开头,这些被C++保留给标准库使用;函数体外的标识符,不能以下划线开头;要尽量有实际意义(不要定义a、b,而要定义name、age);变量名一般使用小写字母;自定义类名一般以大写字母开头;如果包含多个单词,一般用下划线分隔,或者将后面的单词首字母大写;所谓的“关键字”,就是C++保留的一些单词,供语言本身的语法使用。包括
变量有了名字,那只要用这个名字就可以指代对应的数据。但是如果出现“重名”怎么办呢?
在C++中,有“作用域”(scope)的概念,就是指程序中的某一段、某一部分。一般作用域都是以花括号{}作为分隔的,就像之前我们看到的函数体那样。
同一个名字在不同的作用域中,可以指代不同的实体(变量、函数、类等等)。
定义在所有花括号外的名字具有“全局作用域”(global scope),而在某个花括号内定义的名字具有“块作用域”。一般把具有全局作用域的变量叫做“全局变量”,具有块作用域的变量叫做“局部变量”。
#include<iostream>using namespace std;// 全局作用域,全局变量int number = 0;int main(){ // 块作用域,局部变量 int number = 1; // 访问局部变量 cout << "number = " << number << endl; // 访问全局变量 cout << "number = " << ::number << endl; cin.get();}运行结果:number = 1number = 0
如果在嵌套作用域里出现重名,一般范围更小的局部变量会覆盖全局变量。如果要特意访问全局变量,需要加上双冒号:: ,指明是默认命名空间。
2、常量用变量可以灵活地保存数据、访问数据。不过有的时候,我们希望保存的数据不能更改,这种特殊的变量就被叫做“常量”。在C++中,有两种方式可以定义常量:
(1)使用符号常量
这种方式是在文件头用 #define 来定义常量,也叫作“宏定义”。
#define zero 0; //不推荐
跟#include一样,井号“#”开头的语句都是“预处理语句”,在编译之前,预处理器会查找程序中所有的“zero”,并把它替换成0。这种宏定义的方式是保留的C语言特性,在C++中一般不推荐。
(2)使用const限定符
这种方式跟定义一个变量是一样的,只需要在变量的数据类型前再加上一个const关键字,这被称为“限定符”。const修饰的对象一旦创建就不能改变,所以必须初始化。跟使用 #define定义宏常量相比,const定义的常量有详细的数据类型,而且会在编译阶段进行安全检查,在运行时才完成替换,所以会更加安全和方便。
// 常量定义const float Pi = 3.1415;3、数据类型
定义变量时,不可或缺的一个要素就是数据类型。本质上讲,这就是为了实现计算需求,我们必须先定义好数据的样式,告诉计算机这些数据占多大空间,这就是所谓“数据类型”的含义。
C++支持丰富的数据类型,它内置了一套基本数据类型,也为我们提供了自定义类型的机制。
接下来我们先介绍基本数据类型,主要包括算术类型和空类型(void)。其中算术类型又包含了整型和浮点型;而空类型不对应具体的值,只用在一些特定的场合,比如一个函数如果不返回任何值,我们可以让void作为它的返回类型。
3.1、整型整型(integral type)本质上来讲就是表示整数的类型。
我们知道在计算机中,所有数据都是以二进制“0”“1”来表示的,每个叫做一位(bit);计算机可寻址的内存最小单元是8位,也就是一个字节(Byte)。所以我们要访问的数据,都是保存在内存的一个个字节里的。
一个字节能表示的最大数是28 = 256,这对于很多应用来讲显然是不够的。
不同的需求可能要表示的数的范围也不一样,所以C++中定义了多个整数类型,它们的区别就在于每种类型占据的内存空间大小不同。
C++定义的基本整型包括char、short、int、long,和C++ 11新增的long long类型,此外特殊的布尔类型bool本质上也是整型。
在C++中对它们占据的长度定义比较灵活,这样不同的计算机平台就可以有自己的实现了(这跟C是一样的)。由于char和bool相对特殊,我们先介绍其它四种。C++标准中对它们有最小长度的要求,比如:
short类型至少为16位(2字节)int至少2字节,而且不能比short短long至少4字节,而且不能比int短long long至少8字节,而且不能比long短现在一般系统中,short和long都选择最小长度,也就是short为16位、long为32位、long long为64位;而int则有不同选择。我们一般使用的电脑操作系统,比如Windows 7、Windows 10、Mac OS等等的实现中,int都是32位的。
所以short能表示的数有2的16次方 = 65536 个,考虑正负,能表示的范围就是-32768 ~ 32767;而int表示的数范围则为 - 231 ~ 231 - 1。(大概是正负20亿,足够用了)
// 整型 short a = -20; cout << "a = " << a << endl; cout << "a的长度为:" << sizeof a << endl; //2 int a2 = 20; cout << "a2 = " << a2 << endl; cout << "a2的长度为:" << sizeof a2 << endl; // 4 long a3 = 20; cout << "a3 = " << a3 << endl; cout << "a3的长度为:" << sizeof a3 << endl; // 4 long long a4 = 20; cout << "a4 = " << a4 << endl; cout << "a4的长度为:" << sizeof a4 << endl; // 8
这里我们用到了sizeof,这是一个运算符,可以返回某个变量占用的字节数。我们可以看到,变量占用的空间大小只跟类型有关,跟变量具体的值无关。
3.2、无符号整型整型默认是可正可负的,如果我们只想表示正数和0,那么所能表示的范围就又会增大一倍。以16位的short为例,本来表示的范围是-32768 ~ 32767,如果不考虑负数,那么就可以表示0 ~ 65535。C++中,short、int、long、long long都有各自的“无符号”版本的类型,只要定义时在类型前加上unsigned就可以。
// 无符号整型 unsigned short s1 = -1; cout << "s1 = " << s1 << endl; // 65535
上面的代码可以测试无符号数表示的范围。需要注意,当数值超出了整型能表示的范围,程序本身并不会报错,而是会让数值回到能表示的最小值;这种情况叫做“数据溢出”(或者“算术溢出”),写程序时一定要避免。
由于类型太多,在实际应用中使用整型可以只考虑三个原则:
一般的整数计算,全部用int;如果数值超过了int的表示范围,用long long;确定数值不可能为负,用无符号类型(比如统计人数、销售额等);3.3、char类型如果我们只需要处理很小的整数,也可以用另外一种特殊的整型类型——char,它通常只占一个字节(8位)。不过char类型一般并不用在整数计算,它更重要的用途是表示字符(character)。
计算机底层的数据都是二进制位表示的,这用来表示一个整数当然没有问题,可怎么表示字母呢?这就需要将常用的字母、以及一些特殊符号对应到一个个的数字上,然后保存下来,这就是“编码”的过程 。
最常用的字符编码集就是ASCII码,它用0~127表示了128个字符,这包括了所有的大小写字母、数字、标点符号、特殊符号以及一些计算机的控制符。比如字母“A”的编码是65,数字字符“0”的编码是48。
在程序中如果使用char类型的变量,我们会发现,打印出来就是一个字符;而它的底层是一个整数,也可以做整数计算。
// 字符类型 char c = 65; cout << "c = " << c << endl; char c2 = c + 1; cout << "c + 1 = " << c2 << endl;
char类型用来表示整数时,到底是有符号还是无符号呢?之前的所有整型,默认都是有符号的,而char并没有默认类型,而是需要C++编译器根据需要自己决定。
所以把char当做小整数时,有两种显式的定义方式:signed char 和 unsigned char;至于char定义出来的到底带不带符号,就看编译器的具体实现了。
另外, C++还对字符类型进行了“扩容”,提供了一种“宽字符”类型wchar_t。wchar_t会在底层对应另一种整型(比如short或者int),具体占几个字节要看系统中的实现。
wchar_t会随着具体实现而变化,不够稳定;所以在C++11新标准中,还为Unicode字符集提供了专门的扩展字符类型:char16_t和char32_t,分别长16位和32位。
3.4、bool类型在程序中,往往需要针对某个条件做判断,结果只有两种:“成立”和“不成立”;如果用逻辑语言来描述,就是“真”和“假”。真值判断是二元的,所以在C语言中,可以很简单地用“1”表示“真”,“0”表示“假”。
C++支持C语言中的这种定义,同时为了让代码更容易理解,引入了一种新的数据类型——布尔类型bool。bool类型只有两个取值:true和false,这样就可以非常明确地表示逻辑真假了。bool类型通常占用8位(1个字节)。
// 布尔类型 bool b1 = true; cout << "b1 = " << b1 << endl; // cout << "b1占据长度为: " << sizeof b1 << endl;// b1占据长度为: 1
我们可以看到,true和false可以直接赋值给bool类型的变量,打印输出的时候,true就是1,false就是0,这跟C语言里的表示其实是一样的。
3.5、浮点类型跟整数对应,浮点数用来表示小数,主要有单精度float和双精度double两种类型,double的长度不会小于float。通常,float会占用4个字节(32位),而double会占用8个字节(64位)。此外,C++还提供了一种扩展的高精度类型long double,一般会占12或16个字节。
除了一般的小数,在C++中,还提供了另外一种浮点数的表示法,那就是科学计数法,也叫作“E表示法”。比如:5.98E24表示5.98×1024;9.11e-31表示9.11×10-31。
// 浮点类型 float f = 2.5; double d = 3.79E-23; cout << "f = " << f << endl; // f = 2.5 cout << "d = " << d << endl;// d = 3.79e-23
这就极大地扩展了我们能表示的数的范围。一般来讲,float至少有6位有效数字,double至少有15位有效数字。所以浮点类型不仅能表示小数,还可以表示(绝对值)非常大的整数。(float和double具体能表示的范围,可以查找float.h这个头文件)
3.6、字面值常量我们在给一个变量赋值的时候,会直接写一个整数或者小数,这个数据就是显式定义的常量值,叫做“字面值常量”。每个字面值常量也需要计算机进行保存和处理,所以也都是有数据类型的。字面值的写法形式和具体值,就决定了它的类型。
(1)整型字面值
整型字面值就是我们直接写的一个整数,比如30。这是一个十进制数。而计算机底层是二进制的,所以还支持我们把一个数写成八进制和十六进制的形式。以0开头的整数表示八进制数;以0x或者0X开头的代表十六进制数。例如:
30 十进制数036 八进制数0x1E 十六进制数这几个数本质上都是十进制的30,在计算机底层都是一样的。
在C++中,一个整型字面值,默认就是int类型,前提是数值在int能表示的范围内。如果超出int范围,那么就需要选择能够表示这个数的、长度最小的那个类型。
具体来说,对于十进制整型字面值,如果int不够那么选择long;还不够,就选择long long(不考虑无符号类型);而八进制和十六进制字面值,则会优先用无符号类型unsigned int,不够的话再选择long,之后依次是unsigned long、long long和unsigned long long。
这看起来非常复杂,很容易出现莫名其妙的错误。所以一般我们在定义整型字面值时,会给它加上一个后缀,明确地告诉计算机这个字面值是什么类型。
默认什么都不加,是int类型;l或者L,表示long类型;ll或者LL,表示long long类型;u或者U,表示unsigned无符号类型;我们一般会用大写L,避免跟数字1混淆;而u可以和L或LL组合使用。例如9527uLL就表示这个数是unsigned long long类型。
(2)浮点型字面值
前面已经提到,可以用一般的小数或者科学计数法表示的数,来给浮点类型赋值,这样的数就都是“浮点型字面值”。浮点型字面值默认的类型是double。如果我们希望明确指定类型,也可以加上相应的后缀:
f或者F,表示float类型l或者L,表示long double类型这里因为本身数值是小数或者科学计数法表示,所以L不会跟long类型混淆。
(3)字符和字符串字面值
字符就是我们所说的字母、单个数字或者符号,字面值用单引号引起来表示。字符字面值默认的类型就是char,底层存储也是整型。
而多个字符组合在一起,就构成了“字符串”。字符串字面值是一串字符,用双引号引起来表示。
‘ A ’ 字符字面值“Hello World!” 字符串字面值字符串是字符的组合,所以字符串字面值的类型,本质上是char类型构成的“数组”(array)。关于数组的介绍,我们会在后面章节详细展开。
转义字符
有一类比较特殊的字符字面值,我们是不能直接使用的。在ASCII码中我们看到,除去字母、数字外还有很多符号,其中有一些本身在C++语法中有特殊的用途,比如单引号和双引号;另外还有一些控制字符。如果我们想要使用它们,就需要进行“转义”,这就是“转义字符”。C++中规定的转义字符有:
其中,经常用到的就是符号中的问号、双引号、单引号、反斜线,还有换行符和制表符。
// 转义字符char tc = '\n';cout << "tc = " << tc << endl;cout << "Hello World!\t\"Hello C++!\"\n \?" << endl;
(4)布尔字面值
布尔字面值非常简单,只有两个:true和false。
4、类型转换我们在使用字面值常量给变量赋值时会有一个问题,如果常量的值超出了变量类型能表示的范围,或者把一个浮点数赋值给整型变量,会发生什么?
这时程序会进行自动类型转换。也就是说,程序会自动将一个常量值,转换成变量的数据类型,然后赋值给变量。
// 赋值时的自动类型转换 // 1. 整数值赋给bool变量 bool btrans = 25; cout << "btrans = " << btrans << endl;// btrans = 1 // 2. 将bool类型的值赋给算数整型 short strans = false; cout << "strans = " << strans << endl; // strans = 0 // 3. 浮点数赋值给整数类型 int itrans = 3.94; cout << "itrans = " << itrans << endl;// itrans = 3 // 4. 整数值赋值给浮点类型 float ftrans = 3; cout << "ftrans = " << ftrans << endl;// ftrans = 3 // 5. 赋值超出了整型范围 unsigned short ustrans = 65536; cout << "ustrans = " << ustrans << endl;// ustrans = 0 strans = 32768; cout << "strans = " << strans << endl;// strans = -32768
转换规则可以总结如下:
非布尔类型的算术值赋给布尔类型,初始值为0则结果为 false , 否则结果为true ;布尔值赋给非布尔类型,初始值为 false 则结果为0,初始值为 true 则结果为1;浮点数赋给整数类型,只保留浮点数中的整数部分,会带来精度丢失;整数值赋给浮点类型,小数部分记为0。如果保存整数需要的空间超过了浮点类型的容量,可能会有精度丢失。给无符号类型赋值,如果超出它表示范围,结果是初始值对无符号类型能表示的数值总数取模后的余数。给有符号类型赋值,如果超出它表示范围,结果是未定义的( undefined )。此时,程序可能继续工作,也可能崩溃。本站所有软件信息均由用户上传发布,版权归原著所有。如有侵权/违规内容,敬请来信告知邮箱:764327034@qq.com,我们将及时撤销! 转载请注明出处:https://www.ssyg068.com/kuaixun/2647.html
发表回复
评论列表(0条)