类型
问题引入:使用面向对象方法编写一个程序计算机圆的周长和面积。
所有的“圆”都是这样的图形:有圆心,有半径。所以可以把“圆”抽象成一种类型,这个类型具有圆心、半径属性。这种类型称为“类”或者“类类型”,被称为属性的东西是该类类型的数据成员。
数据成员有了具体的值之后,就可以计算周长和面积了。对每个圆,都可以求得它的周长和面积,因此可以把求圆的周长和面积的方法封装在圆这个类类型中,这种方法称为该类的“成员函数”。
对于数值,可分为整数、实数【在C++里称为浮点数,有单精度和双精度,最主要是它们的存储值的长度不同,可理解为有效数字长度不同吧】等等,也可以根据逻辑学里布尔值分为true、false,也即1、0【不过在C++里非0值为true,0值为false】。所以想要用变量来存储数值,以表示圆的圆心、半径,就要定义变量,同时应该说明它的类型,以便编译器对该变量的值进行解析,然后进行计算。
先看代码:
<span style="font-family:Microsoft YaHei;">#include <IOSTREAM>
#include <cstring>
using namespace std;
class circle
{
public:
//设置、获取圆心坐标、半径
void set_center(double _x, double _y) { x = _x; y = _y;}
void get_center(double &_x, double &_y) { _x = x; _y = y;}
void set_radius(double _r) { radius = _r;}
void get_radius(double &_r) { _r = radius;}
//设置、获取圆的名字
void set_circle_name(char *p) { strcpy(name, p);}
void get_circle_name(char *p) { strcpy(p, name);}
//计算圆的周长、面积
double get_girth() { return 2 * 3.14 * radius;}
double get_area() { return 3.14 * radius * radius;}
private:
double x, y;
double radius;
char name[20];
};
int main()
{
circle A;
double radius;
char name[20];
cin >> name;
A.set_circle_name(name);
cin >> radius;
A.set_radius(radius);
double girth = A.get_girth();
double area = A.get_area();
cout<<"圆 : "<<name<<endl;
cout<<"周长 : "<<girth<<endl;
cout<<"面积 : "<<area<<endl;
return 0;
}</span>
以上代码写义了类circle,数据成员有圆心和半径以及圆的名字,成员函数有设置和获取圆心以及半径,求周长和面积,还有设置、获取圆的名字。
C++语言的数据类型可以分为:基本类型、类型、指针类型(*)、空类型(void),其中基本类型又可以分为整形(int, bool, enum)、浮点型(float, doulbe),字符型(char);结构类型可以分为数组([])、结构(struct)、联合(union)、类(class)。
在上面的程序中,使用了int, class, void, double, char *, char []六种数据类型。
C++基本内置类型有表示算术运算的类型有:整数、浮点数、单个字符和布尔值。此外还有一个特殊的类型是void,它称为空类型,也即无类型,但可以转换成其他类型。
整形:表示整数、字符、布尔值的算术类型合称为整形。
short, int, long类型都表示整形值,存储空间的大小不同,一般short为半个字长,int为一个字长,long为一个或两个字长。
bool类型表示真值false和true,可以将算术类型的任何值赋给bool对象,0值算术类型代表false,任何非0值代表true。
带符号和无符号类型。除bool类型外,整数可以是带符号的也可以是无符号的。int, short, long默认是带符号型,可以表示正数和负数,而无符号型只能表示大于或等于0的数。
和其他整形不同,char有三种不同的类型:char, unsigned char, signed char。虽然char有三种不同的类型,但只有两种表示方式,使用unsigned char还是使用signed char来表示char,得由编译器来实现。
字符类型有四种:char16_t, char32_t, char和wchart_t。char和wchar_t,也是一般只专用于表示字符的整数类型,且设计上用于表示Unicode字符。char16_t和char32_t是C++11新增的,以克服wchar_t在不同平台上无法保证确定宽度的缺点。
浮点型:类型float, double, long double分别表示单精度、双精度和扩展精度浮点数,一般flaot是一字节,double是两字节,long double是四字节。
表示值范围:
signed char : C++标准中并未定义,由编译器实现表示-128~127,还是-127~127
类型名 | 说明 | 字节数 | 示数范围 |
char | 字符型 | 1 | -128~127 |
signed char | 有符号字长型 | 1 | -128~127[有些编译器为:-127~127] |
unsigned char | 无符号字符型 | 1 | 0~255 |
short [int] | 短整形 | 2 | -32768~32767 |
signed short [int] | 有符号短整形 | 2 | -32768~32767 |
unsigned short [int] | 无符号短整形 | 2 | 0~65535 |
int | 整形 | 4 | -2147483648~2147483647 |
signed [int] | 有符号短整形 | 4 | -2147483648~2147483647 |
unsigned [int] | 无符号短整形 | 4 | 0~4294967295 |
long [int] | 长整形 | 4 | -2147483648~2147483647 |
signed long [int] | 无符号长整形 | 4 | -2147483648~2147483647 |
unsigned long [int] | 无符号长整形 | 4 | 0~4294967295 |
float | 单精度浮点型 | 4 | -3.4x10^38~3.4x10^38,约6位有效数字 |
double | 双精度浮点型 | 8 | -1.7x10^308~1.7x10^308,约15位有效数字 |
long double | 长双精度浮点型 | 8 | -1.7x10^308~1.7x10^308,约15位有效数字 |
变量
C++中的每个变量都有特定的类型,该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集,C++里常常把变量称为“对象”。
左值:可以出现在赋值语句的左边或右边。
右值:只能出现在赋值的右边,不能出现在赋值语句的左边。
<span style="font-family:Microsoft YaHei;font-size:14px;">void set_center(double _x, double _y) { x = _x; y = _y;}</span>
*表达式:表达式由数据和运算符组成,按求值规则,表达一个值的式子,比如:x+10
*语句:一般是以‘;’所分隔的一段代码就称为一个语句,比如:x+10;
*赋值语句,上函数(也称方法)体中x=_x;就是一个赋值语句,把_x的值赋给x。
变量名
变量名由字母、数字、下划线或者$组成,并且不能以数字开头,C++里区分英文字母的大小写。
不能再定义为普通变量名的有:C++关键字(第一篇:C++关键字 http://blog.csdn.net/fyl_csdn/article/details/44905211),C++操作符替代名(and, bitand, compl, not_eq, or_eq, xor_eq, and_eq, bitor, not, or, xor)以及STL中保留的一组标识符。C++标识符不能包含两个连续下划线,也不能以下划线开头后面紧跟一个大写字母,有些标识符不能以下划线开头,但具体得看编译器的实现。
访问变量的方式:名访问、地址访问、间址访问、引用
名访问:就是通过对象名,也即变量名,对对象的内容进行读或写,名访问又称为直接访问。比如赋值操作的名访问形式:变量=表达式, a=10。
地址访问:就是通过对象所在内存地址上进行读写操作。对象的地址用于指示对象的存储位置,称为对象的“指针”,指针所指向的物理存储空间称为“指针所指对象”,因些地址访问又称为指针访问。比如,a是一个整形变量,可以这样赋值:*(&a)=10【在这里&是取址操作符,*是解引用操作符,表示取对象a的地址,再解析该地址,然后把10写入该地址上】。
间址访问:能够存放地址值的变量称为指针(类型)变量,该变量的值存储的是一个对象的地址值。例如有一个整形变量a和一个整形指针*p,p指向a对象的存储空间,则a的值可表示为:a, *(&a), *p。
引用:C++里允许对对象定义别名,称为引用。如:
<span style="font-family:Microsoft YaHei;font-size:14px;">int a, &b=a;</span>
这里表示定义一个int对象a,以及引用类型b,b解析为a的引用,即别名。所以对b的操作也就是对a的操作,对a的操作也就是对b的操作,这个时候a只是多了一个别名b。
常量
常量,说白了就是值不能修改的变量,因为经它用const关键字进行了约束。
C++中const约束基本类型为只读,不能修改。定义形式:const 类型 常量标识符 = 常量表达式;
运算符
算术运算符 + - * / % ++ --
关系运算符 > < == >= <= !=
逻辑运算符 ! && ||
位运算符 << >> ~ | & ^
赋值运算符 = 以及符合运算符,如:+= -= *= /=......
条件运算符 ? : 三目运算符,如 a > b ? c : d;如果a>b,运算结果是c,否则是d
逗号运算符 ,
指针运算符 * &
求字节运算符 sizeof 要记得sizeof()经常用到,但它只是一个运算符,不是函数
分量运算符 . ->
下标运算符 []
其他运算符 () :: new delete,()是函数调用运算符,用于函数调用;::是作用域运算符,用于说明变量、函数所属域;new & delete是申请、释放堆空间的运算符
运算符的优先级入结合性
优先级 | 操作符 | 描述 | 例子 | 结合性 | |
1 | () | 调节优先级的括号操作符 | (a + b) / 4; | 从左到右 | |
2 | ! | 逻辑取反操作符 | if( !done ) ... | 从右到左 | |
3 | ->* | 在指针上通过指向成员的指针访问成员的操作符 | ptr->*var = 24; | 从左到右 | |
4 | * | 乘法操作符 | int i = 2 * 4; | 从左到右 | |
5 | + | 加法操作符 | int i = 2 + 3; | 从左到右 | |
6 | << | 按位左移操作符 | int flags = 33 << 1; | 从左到右 | |
7 | < | 小于比较操作符 | if( i < 42 ) ... | 从左到右 | |
8 | == | 等于比较操作符 | if( i == 42 ) ... | 从左到右 | |
9 | & | 按位与操作符 | flags = flags & 42; | 从左到右 | |
10 | ^ | 按位异或操作符 | flags = flags ^ 42; | 从左到右 | |
11 | | | 按位或操作符 | flags = flags | 42; | 从左到右 | |
12 | && | 逻辑与操作符 | if( conditionA && conditionB ) ... | 从左到右 | |
13 | || | 逻辑或操作符 | if( conditionA || conditionB ) ... | 从左到右 | |
14 | ? : | 三元条件操作符 | int i = (a > b) ? a : b; | 从右到左 | |
15 | = | 赋值操作符 | int a = b; | 从右到左 | |
16 | , | 逗号操作符 | for( i = 0, j = 0; i < 10; i++, j++ ) ... | 从左到右 |
再说类型
typedef/enum/union/struct/class
typedef 定义以关键字typedef开始,后接数据类型和标识符,使用typedef定义名字,并没有引入新的数据类型,而给现有的类型起一个别名,与引用不同。如:typedef unsigned int u_int32_t;上typedef定义,并没有创建新类型,而是把unsigned int 起了另一个名字叫u_int32_t,此后用u_int32_t定义变量,该变量的实质便是unsigned int类型的。
enum是枚举类型,HTTP协议中请求方法有GET/POST/PUT/DELETE/HEAD.....,并不需要每个方法都定义一个变量,可以使用整形变量method表示,如何表示呢?0表示GET,1表示POST....。这个时候就应用到enum类型的。定义方式:enum obj_name { mem1, mem2, mem3,...};也可以在{}里对memn进行赋值,但只能是整形值。默认的,第1个成员值为0,后面每个成员是前一个成员的值加1。每个enum都定义了一种唯一的类型,当定义和初始化该类型对象时作,只能用同类型对象初始化,或者通过enum类型进行类型转换,否则出错。枚举成员本身就是常量,不能对其进行赋值操作。
union是联合体类型,把各种不同的数据类型集于一体,并且共用同一内存,是一种特殊的struct类型。
在C++里,struct/class只有三个不同,其他方面一样,与C里的struct区别还是比较大的。后面再说这两种类型。