您的位置:首页 > 编程语言 > C语言/C++

C++基础学习系列第一部分——变量和基本类型

2013-11-12 20:33 274 查看
大家好,我是Derek。本应该上周就开始写东西的,上周事情有些多,计划总赶不上变划,只好推迟到现在了。好了话不多说,下面开始了我的C++基础的再学习。这一期主要是回顾了一些C++的变量和基本类型,没有太多的例子,以后的学习中我会慢慢加入代码,结合例子来进行学习。希望大家多多支持!

(一)
基本的数据类型


C++定义了一组表示整数、浮点数、单个字符和布尔值的算术类型和void特殊类型。Void类型没有对应的值,通常用作无返回值函数的返回类型。

C++算术类型 1

类型
含义
最小存储空间
bool
布尔类型
NA
char
字符型
8位
wchar_t
宽字符型
16位
short
短整型
16位
int
整型
16位
long
长整型
32位
float
单精度浮点型
6位有效数字
double
双精度浮点型
10位有效数字
long double
扩展精度浮点型
10位有效数字
1. 整形

表示整数、字符和布尔值的算术类型合称为整型

字符类型有两种:char和wchar_t。char类型保证了有足够的空间存储机器基本字符集中任何字符相应的数值,因此,char类型通常是单个机器字节(byte)。wchar_t类型用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个char表示。

short、int和long类型都表示整型值,但具有不同大小的存储空间。一般,short类型为半个机器字长,int类型为一个机器字长,而long类型为一个或两个机器字长(在32位机器中int类型和long类型通常字长是相同的)。

bool类型表示真值true和false。可以将算术类型的任何值赋给bool对象。0值算术类型代表false,任何非0的值都代表true。

1.1带符号和无符号类型

除bool类型以外,整型可以是带符号的(signed)也可以是无符号的(unsigned)。带符号类型可以表示正数也可以表示负数(包括0),无符号类型只能表示大于或等于0的数。

整形int、short和long都默认为带符号类型。要获得无符号型则必须指定该类型为unsigned,比如unsigned long。Unsigned int 类型可以简写为unsigned,也就是说,unsigned后不加其他类型标识符意味着是unsigned
int。

和其他整数类型不同,char有三种不同的类型:普通char、unsigned
char和signedchar。虽然char有三种不同的类型,但只有两种表示方式。可以使用unsigned
char或signed char表示char类型。


1.2整型值的表示

无符号型中,所有的位都表示数值。如果定义一种类型使用8位表示,那么这种型的unsigned型可以取值0到255。C++标准并未定义signed类型如何用位来表示,而是由每个编译器自由决定如何表示signed类型。这些表示方式会影响signed类型的取值范围。可以确保8位的signed类型取值至少从-127到127,也有许多实现允许取值从-128到127。最常见的表示signed整数类型的策略是用其中一个位作为符号位。符号位为1,值就为负数;符号位为0,值就为0或正数。一个signed整数取值是从-128到127。

1.3整形的赋值

对象的类型决定对象的取值。当我们试着把一个超出其取值范围的值赋给一个指定类型的对象时,结果会怎样呢?答案取决于这种类型是signed还是unsigned。对于unsigned类型来说,编译器必须调整越界值使其满足要求。编译器是通过取该值对unsigned类型可以取的不同值的数目求模后的值来实现的。比如8位的unsigned
char,其取值范围从0到255(包括255)。如果赋给超出这个范围的值,那么编译器将会取该值对256求模后的值。例如,我们可以试着将336赋值给8位的signed
char。如果试图将336存储到8位的unsigned char中,实际赋值为80,因为80是336对256求模后的值。C++中,把负值赋给unsigned对象是完全合法的,其结果是该负数对该类型的取值个数求模后的值。所以,如果把-1赋给8位的unsigned
char,那么结果是255,因为255是-1对256求模后的值。当将超过取值范围的值赋给signed类型时,由编译器决定实际赋的值。在实际操作中,很多的编译器处理signed类型和处理unsigned类型类似。也就是说,赋值时是取该值对该类型的取值个数求模后的值。

2.浮点型

类型float、double和long
double分别表示单精度浮点数双精度浮点数扩展精度浮点数。一般float类型用一个字(32位)来表示,double类型用两个字(64位)来表示,long
double类型用三个或四个字(96或128位)来表示。类型的取值范围决定了浮点数含有的有效数字位数。

(二)字面值常量

像42这样的值,在程序中被当作字面常量。因为只能用它的值称呼它而且它的值不能改变。第个字面值都有相应的类型。只有内置类型存在字面值,没有类类型的字面值,也没有任何标准库类型的字面值。

1. 整型字面值规则

定义字面值整数常量可以使用以下三种进制中的任一种:十进制、八进制和十六进制。以0(零)开头的字面值整数常量表示八进制,以0x或0X开头的表示十六进制。字面值整数常量的类型默认为int或long类型。通过增加后缀,能够强制将字面值整数常量转换为long、unsigned或unsigned long类型。注意:没有short类型的字面值常量。

2. 浮点型字面值规则

通常可以用十进制或科学计数法来表示浮点数字面值常量。默认浮点字面值常量为double类型。在数值的后面加上F或f表示单精度,同样加上L或者l 表示扩展精度。

3. 布尔字面值和字符字面值

单词true和false是布尔型字面值;可打印的字符型字面值通常用一对单引号来定义。

4. 非打印字符的转义字符

有些字符是不可打印的。不可打印的字符实际上是不可显示的字符如退格或控制符,也有一些特殊意义的字符如单引号、双引号、反斜线等,都用转义字符书写。转义字符都以反斜线符号开始。

我们还可以将任何字符表示为以下形式的通用转义字符:\000 这里三个0表示三个八进制数字,这三个数字表示字符的数字值;同样也可以用十六进制转义字符来定义字符\xddd,它是由一个反斜线符、一个x一个或多个十六进制数字组成。

5. 字符串字面值

字符串字面值常量用双引号括起来的零个或者多个字符表示。不可打印字符表示成相应的转义字符。

"Hello World" //simple stringliteral

"" //empty string literal

宽字符串字面值,一样在前面加"L":L"a wide string literal"

6. 字符串字面值的连接

两个相邻的仅由空格、制表符或换行符分开的字符串的字符串字面值(或宽字符串字面值),可连接成一个新的字符串字面值。如果连接字符串字面值和宽字符串字面值,例如:std::cout<<"multi-line"L"literal "<<std::endl;其结果是未定义,也就是说,连接不同类型的行为标准没有定义。

7. 多行字面值

在一行的末尾加一反斜杠符号可将此行和下一行当做同一行处理。特别是有些地方不能插入空格,其中之一就是在单词中间。特别是不能再单词中间断开一行。但可以通过使用反斜杠符号巧妙实现:

std::cou\

t<<"hi"<<st\

d:endl;

等价于std::cout<<"hi"<<std::endl;

注意:反斜线符号必须是该行的尾字符-----不允许其后面有注释或空格。同样,后继行行首的任何空格和制表符都是字符串字面值的一部分。因此,长字符串字面值的后继行才会有正常的缩进。

(三)变量

3.1 变量及变量名

变量提供了可以操作的有名字的存储区。每一个变量都有特定的类型。该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围及可应用在该变量上的操作集。关于左值右值。左值就是变量的地址,可以出现在赋值语句的左右两边;右值就是变量的值,只能出现在赋值语句的右边。在赋值运算的左边需要左值。

变量名,即变量标识符,可以由字母、数字和下划线组成。变量名必须以字母或下划线开头,并且区分大小写。C++中的关键字及保留的各种操作符的替代名不能用作标识符。除了关键字,C++标准还保留了一组标识符用于标准库。标识符不能包含两个连续的下划线,也不能以下划线开头后面紧跟一个大写字母。有些标识符(在函数外定义的标识符)不能以下划线开头。

3.2 变量定义及初始化

变量定义都是以类型说明符开始,后面紧跟着以逗号分开的含有一个或多个说明符的列表,以分号结束定义。

变量定义指定了变量的类型和标识符,也可以为对象提供初始值。定义时指定了初始值的对象被称为是已初始化的。C++支持两种初始化变量的形式:复制初始化(int a=0;)和直接初始化(int a(0);)。使用=来初始化变量使人很容易把初始化当成赋值的一种,C++中初始化和赋值是两种不同的操作。

初始化内置类型的对像只有一种方法:提供一个值,并把这个值复制到新定义的对象中。对于类类型的对象来说,有些初始化仅能用直接初始化完成,有多个初始化式时不能使用复制初始化。

当一个定义中定义了两个以上变量的进修,每个变量都可能有自己的初始化式,对像的名字立即变成可见,所以可以用同一个定义中前面已定义变量的值初始化后面的变量。已初始化变量和末初始化变量可以在同一个定义中定义。

内置类型变量是否能自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化0,在函数体内定义的内置类型变量则不进行自动初始化。如果定义某个类的变量的时候没有提供初始化式,则通过默认构造函数进行初始化。

3.3 声明和定义

变量的定义:用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。声明:用于向程序表明变量的类型和名字。定义也是声明:当定义变量时候我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。

不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern:extern int i(声明但没有定义i);int i(声明并定义i)。extern声明不是定义,也不分配存储空间,它只是说明变量定义在程序的其他地主。

只有当声明也是定义的时候,声明才可以有初始化式,因为只有定义才分配存储空间。如果声明有初始化式,那么它可被当作定义。即使声明标记为extern:extern double pi=3.14159(定义)。只有当extern声明位于函数外部的时候,才可以含有初始化式。

3.4 名字的作用域

定义在所有函数外部的名字具有全部作用域,可以在程序中的任何地方访问;定义在函数内部的名字具有函数内部的局部作用域,可以在函数内部使用;定义在for循环内部的名字具有语句作用域,只能在for循环内部使用。定义在全局变作用域中的名字可以在局部作用域中使用,定义在全局作用域中的名字和定义在函数局部作用域中的名字可以在语句作用域中使用。

变量在使用前必须声明或定义!

3.5 const限定符、引用及typedef名字

const是C语言的一个关键定,它所限定的变量不允许被改变,所以const常量在定义的时候必须初始化。在全局作用域中,非const变量在整个程序中都可以访问,而const变量是定义该对象的文件的局部变量,全局作用域中const变量只存在于定义的那个文件中,而不能被其他文件访问。要使const变量在其他文件中可访问,必须地指定它为extern。

引用是一种复合类型,通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。不能定义引用类型的引用。引用必须与该引用同类型的对象初始化。1)引用只是他绑定的对象的另一个名字,作用在引用上的操作实际上都是作用在该引用绑定的对象上(当引用初始化后,只要该引用存在,它就保持绑定到初始化时指向的对象,不可将引用绑定到另一个对象);2)可以在一个类型定义中定义多个引用,必须在每个引用标识符前添加“&”符号;3)非const引用只能绑定到与该引用同类型的对象,const引用则可以绑定到不同但相关的类型的对象或绑定到右值(const
int&r1=42是合法的,而int &r2=42是不合法的)。

Typedef可以用来定义类型的同义词。typedef定义以关键定typedef开始,后面跟的是数据类型和标识符。标识符或类型名并没有引入新的类型,而只是现在数据类型的同义词,如:typedef double wages;wages是double的一个同义词,并不是一个新的数据类型。typedef常用于以下三种目的:1)为了隐藏特定类型的实现,强调使用类型的目的;2)简化复杂的类型定义,使其更容易理解;3)允许一种类型用于多个目的,同是使得每次使用该类型的目的明确。(第三条不是很理解,哪位有更好的理解,请多多指教)

3.6 枚举类型和类类型

枚举的定义包括关键定enum,其后是一个可选的枚举类型名,和一个用花括号括起来的、用逗号分开的枚举成员列表。默认的第一个枚举成员赋值为0,后面的每个枚举成员赋的值比前面的大1。可以为一个或多个枚举成员提供初始值,用来初始化枚举成员的值必须是一个常量表达式。例如:enum
Porms{shape=1,sphere,cylinder,polygon};//shape是1,sphere是2,cylinder是3,polygon是4。枚举成员的值可以是不唯一的,不能改变枚举成员的值。每个enum都定义了一个新的类型,枚举类型的对象的初始化或赋值只能通过枚举成员或同一枚举类型的其他对象来进行。

类类型,关于类类型这里不再进行多说,后续中将陆续提到关于类类型的一些知识点。这里只提一点,用class和struct关键字定义类的唯一区别在于默认的访问级别,默认情况下,struct的成员是public,class的成员为private。

下一期,我将再复习一些数组和指针方面的东西。希望大家多多支持我,文章中有什么疏漏之处,望大家多多指正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: