01~C++数据类型

1. C++ 数据类型分类

C++数据类型 = {内置类型(built-in C++ types)} + {拓展类型(Eg:C++11’s additions)}

内置类型 (built-in C++ types)类型说明
基本类型(fundamental types)内置整型( built-in integer types),内置浮点型( built-in floating-point)
组合类型( compound types)数组(arrays), 字符串(strings), 指针(pointers)结构体(structures)
拓展类型类型说明
C++ 11 扩展unsigned long long ,long long
  • 内置整型( built-in integer types)
    内置整型( built-in integer types) = { unsigned long, long, unsigned int, int, unsigned short, short, char, unsigned char, signed char, bool}

    整型定义:
    A short integer is at least 16 bits wide.
    An int integer is at least as big as short.
    A long integer is at least 32 bits wide and at least as big as int.
    A long long integer is at least 64 bits wide and at least as big as long.

    注:意味着integer types 不一定包含指定的bits — 待拓展

  • 内置浮点型( built-in floating-point)

    待办

2. C++ 数据类型操作

一般意义上讲,一个字节(byte)包含8位(bits),但现实情况不一定
一般意义上讲,一个整型 (int)包含4个字节,但现实情况不一定如此。
何况,基本类型包含符号数和无符号数,那么每一种基本类型可以表示数的范围是多少呢? 编程计算过程中如何避免计算溢出呢?

2.1 内置整数类型

2.1.1 整数类型与其有效范围

每一个发型的操作系统,数据类型信息被记录到limits.h(老式操作系统)或者 climits 头文件中

#include <iostream>

using namespace std;
#include <climits> 
int main()
{
using namespace std;
int n_int = INT_MAX; // initialize n_int to max int value
short n_short = SHRT_MAX; // symbols defined in climits file
long n_long = LONG_MAX;
long long n_llong = LLONG_MAX;
// sizeof operator yields size of type or of variable
cout << "int is " << sizeof (int) << " bytes." << endl;
cout << "short is " << sizeof n_short << " bytes." << endl;
cout << "long is " << sizeof n_long << " bytes." << endl;
cout << "long long is " << sizeof n_llong << " bytes." << endl;
cout << endl;
cout << "Maximum values:" << endl;
cout << "int: " << n_int << endl;
cout << "short: " << n_short << endl;

cout << "long: " << n_long << endl;
cout << "long long: " << n_llong << endl << endl;
cout << "Minimum int value = " << INT_MIN << endl;
cout << "Bits per byte = " << CHAR_BIT << endl;
return 0;
}

  • climits 说明
CHAR_MAXMaximum char value
CHAR_MINMinimum char value
SCHAR_MAXMaximum signed char value
SCHAR_MINMinimum signed char value
UCHAR_MAXMaximum unsigned char value
SHRT_MAXMaximum short value
SHRT_MINMinimum short value
USHRT_MAXMaximum unsigned short value
INT_MAXMaximum int value
INT_MINMinimum int value
UINT_MAXMaximum unsigned int value
LONG_MAXMaximum long value
LONG_MINMinimum long value
ULONG_MAXMaximum unsigned long value
LLONG_MAXMaximum long long value
LLONG_MINMinimum long long value
ULLONG_MAXMaximum unsigned long long value

2.1.2 整数类型与其常数

#include <iostream>

using namespace std;
#include <climits> 
#define ZERO 0 // makes ZERO symbol for 0 value

int main()
{
int sam = 34;
cout << "Sam has " << sam <<endl;
    sam = -34;
 cout << "Sam has " << sam <<endl;   
    sam = 0x22;
cout << "Sam has " << sam <<endl;
    sam = -0x22;
cout << "Sam has " << sam <<endl;
    sam = 042;
cout << "Sam has " << sam <<endl;
    sam = -042;
cout << "Sam has " << sam <<endl;
    
return 0;
}

可以使用十进制 八进制 或者 十六进制(有符号或者无符号)

2.1.3 整数类型的计算与溢出

#include <iostream>

using namespace std;
#include <climits> 
#define ZERO 0 // makes ZERO symbol for 0 value

int main()
{
short sam = SHRT_MAX; // initialize a variable to max value
unsigned short sue = sam;// okay if variable sam already defined
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl
<< "Add $1 to each account." << endl << "Now ";
sam = sam + 1;
sue = sue + 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.\nPoor Sam!" << endl;
sam = ZERO;
sue = ZERO;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl;
cout << "Take $1 from each account." << endl << "Now ";
sam = sam - 1;
sue = sue - 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
return 0;
}

Sam has 32767 dollars and Sue has 32767 dollars deposited. Add $1 to
each account.
Now Sam has -32768 dollars and Sue has 32768 dollars
deposited.
Poor Sam! Sam has 0 dollars and Sue has 0 dollars deposited.
Take $1 from each account.
Now Sam has -1 dollars and Sue has 65535

2.1.4 整数类型的溢出和规避

  • 无符号数
运算类型溢出类型判断没有溢出注意
s=x+y可能上溢s≥x不能使用s-x==y来判断
s=x-yx<y时会下溢x>=yNA
m=x*y可能上溢 (x0&&m0)(x!=0&&m/x==y) NA
m=x/y不会溢出1==1NA
  • 有符号数
运算类型溢出类型如何判断不溢出注意
s=x+y可能上溢或下溢!((x>=0&&y>=0&&s<0)||(x<0&&y<0&&s>=0))NA
s=x-y可能上溢或下溢!((x<0&&y>0&&s>=0)||(x>0&&y<0&&s<=0))NA
m=x*y可能上溢!x ||m/x==yNA
m=x/y不会溢出NANA

参考资料:
https://blog.csdn.net/EasonDongH/article/details/86572335

2.1.5 特殊的整数类型 char、wchar_t

  • 目的
    char 类型用于对字符进行编码,而字符用于文字编码

  • 类型

    • char 最常见的是我们常说的ASCII码!( United States is the ASCII character set),由8bits构成

    • wchar_t 是国际编码(Unicode), 通常为2个byte,表示字符更多

      #include <iostream>
      
      using namespace std;
      #include <climits> 
      #define ZERO 0 // makes ZERO symbol for 0 value
      
      int main()
      {
      wchar_t bob = L'P'; // a wide-character constant
      wcout << bob << endl;
      wcout << L"tall" << endl; // outputting a wide-character string
      return 0;
      }
      
    • char16_t and char32_t
      同样属于Unicode,不过编码又有所不同。wcout 打印不出来的

2.2 内置浮点类型

2.2.1 浮点数编码

  • 浮点数编码参考
    https://blog.csdn.net/qq_41694201/article/details/83476003

  • 浮点数类型示例

    //float, double,and long double
    #include <iostream>
    
    using namespace std;
    #include <climits> 
    
    
    int main()
    {
    float f = 12.34; //a double constant
        f = 1.234f; // a float constant
        f = 2.45E20F; // a float constant
        f =2.345324E28; // a double constant
        f = 2.2L; // a long double constant
    
        f = 939001.32; // floating-point
        f = 0.00023; // floating-point
        f = 8.0; // still floating-point
    
        f = 2.52e+8; // can use E or e, + is optional
        f = 8.33E-4; // exponent can be negative
        f = 7E5; // same as 7.0E+05
        f = -18.32e1; // can have + or - sign in front
        f = 1.69e12; // 2010 Brazilian public debt in reais
        f = 5.98E24; // mass of earth in kilograms
        f = 9.11e-31; // mass of an electron in kilograms
    return 0;
    }
    
    

2.2.2 浮点数精度

  1. 尾数的位数 决定了浮点数表示精度
  2. 幂数的位数 决定了浮点数表示范围

每一台计算机的浮点数编码格式不一定完全一致,浮点编码信息被写入到cfloat 或者 float.h 的头文件

有效位的位数最小承诺值(转换为10进制后)
// the following are the minimum number of significant digits
#define DBL_DIG 15 // double
#define FLT_DIG 6 // float
#define LDBL_DIG 18 // long double

尾数的编码位数,浮点类型尾数决定了精度(二进制位)
// the following are the number of bits used to represent the mantissa
#define DBL_MANT_DIG 53
#define FLT_MANT_DIG 24
#define LDBL_MANT_DIG 64

指数的范围,数量的量级(十进制)
// the following are the maximum and minimum exponent values
#define DBL_MAX_10_EXP +308
#define FLT_MAX_10_EXP +38
#define LDBL_MAX_10_EXP +4932
#define DBL_MIN_10_EXP -307
#define FLT_MIN_10_EXP -37
#define LDBL_MIN_10_EXP -4931

2.2.3 浮点数的问题

2.2.3.1 浮点打印
#include <iostream>
#include <iomanip>
#include <cfloat>
using namespace std;


int main()
{
    
    cout.setf(ios_base::fixed, ios_base::floatfield); // fixed-point
    
    float fmint = 10.0/3.0;
    double dmint = 10.0/3.0;
    
    
    cout<<setprecision(LDBL_DIG)<<fmint<<endl;  
    cout<<setprecision(LDBL_DIG)<<dmint<<endl; 
    
    cout << endl;
    cout<<setprecision(DBL_DIG)<<fmint<<endl;  
    cout<<setprecision(DBL_DIG)<<dmint<<endl;
    
    cout << endl;
    cout<<setprecision(FLT_DIG)<<fmint<<endl;  
    cout<<setprecision(FLT_DIG)<<dmint<<endl;
return 0;
}
output: 可见,float 只能保证6位精度,double 只能保证15位精度
3.333333253860473633
3.333333333333333481

3.333333253860474
3.333333333333333

3.333333
3.333333

2.2.3.2 精度问题
2.3.3.2.1 加法运算结果无法精确表示
#include <iostream>

using namespace std;
#include <climits> 


int main()
{
using namespace std;
float hats, heads;
cout.setf(ios_base::fixed, ios_base::floatfield); // fixed-point
cout << "Enter a number: ";
cin >> hats;
cout << "Enter another number: ";
cin >> heads;
cout << "hats = " << hats << "; heads = " << heads << endl;
cout << "hats + heads = " << hats + heads << endl;
cout << "hats - heads = " << hats - heads << endl;
cout << "hats * heads = " << hats * heads << endl;
cout << "hats / heads = " << hats / heads << endl;
return 0;
}
outPut: 50.25 + 11.17 = 61.42,但是这里加减法结果却得到了近似数
Enter a number: 50.25
Enter another number: 11.17
hats = 50.250000; heads = 11.170000
hats + heads = 61.419998
hats - heads = 39.080002
hats * heads = 561.292480
hats / heads = 4.498657

2.2.3.2.2 加法运算结果导致部分被舍
#include <iostream>

using namespace std;
#include <climits> 


int main()
{
float a = 2.34E+22f;
float b = a + 1.0f;
cout << "a = " << a << endl;
cout << "b - a = " << b - a << endl;
return 0;
}
a = 2.34e+22 b - a = 0 
?1.0f 

2.2.3.2.3 浮点数的比较运算

参考资料:
http://www.fomalhaut.cn/405

2.3 内置组合类型

参考连接:

2.3.1 数组类型

模板 typeName arrayName[arraySize];

#include <iostream>
int main()
{
	//set vals for members
	using namespace std;
	int yams[3]; // creates array with three elements
	yams[0] = 7; // assign value to first element
	yams[1] = 8;
	yams[2] = 6;
	
	//initialize all
	int yamcosts[3] = {20, 30, 5}; // create, initialize array
	
	//If you partially initialize an array, the compiler sets the remaining elements to zero
	float hotelTips[5] = {5.0, 2.5};
	//if you do this , all members set to 0
	long totals[500] = {0};

	//there are 4 members for this array.
	short things[] = {1, 5, 3, 8};
	//how many things for this array?
	int num_elements = sizeof things / sizeof (short);
	
	
	return 0;
}

2.3.2 字符串类型

	//string end has a '\0'
	char dog[8] = { 'b', 'e', 'a', 'u', 'x', ' ', 'I', 'I'}; // not a string!
	char cat[8] = {'f', 'a', 't', 'e', 's', 's', 'a', '\0'}; // a string!
	
	//better way to make the string
	char bird[11] = "Mr. Cheeps"; // the \0 is understood
	//oh, may best to make string this way
	char fish[] = "Bubbles"; // let the compiler count

2.3.3 结构体类型

// structur.cpp -- a simple structure
#include <iostream>
struct inflatable // structure declaration
{
	char name[20];
	float volume;
	double price;
};

int main()
{
	using namespace std;
	inflatable guest =
	{
	"Glorious Gloria", // name value
	1.88, // volume value
	29.99 // price value
	}; // guest is a structure variable of type inflatable
	// It's initialized to the indicated values
	inflatable pal =
	{
	"Audacious Arthur",
	3.12,
	32.99
	}; // pal is a second variable of type inflatable
	
	// NOTE: some implementations require using
	// static inflatable guest =
	cout << "Expand your guest list with " << guest.name;
	cout << " and " << pal.name << "!\n";
	// pal.name is the name member of the pal variable
	cout << "You can have both for $";
	cout << guest.price + pal.price << "!\n";
	return 0;
}

// arrstruc.cpp -- an array of structures
#include <iostream>
struct inflatable
{
char name[20];
float volume;
double price;
};
int main()
{
148 Chapter 4 Compound Types
using namespace std;
inflatable guests[2] = // initializing an array of structs
{
{"Bambi", 0.5, 21.99}, // first structure in array
{"Godzilla", 2000, 565.99} // next structure in array
};
cout << "The guests " << guests[0].name << " and " << guests[1].name
<< "\nhave a combined volume of "
<< guests[0].volume + guests[1].volume << " cubic feet.\n";
return 0;
}

2.3.4 联合类型

2.3.4.1 一般定义

union 用于表示一个内存块,内存大小为size最大的成员

	union传统用法,用来定义数据类型
	//union_01.cpp
	#include <cstdio>
	union U{
			char c[4];
			int x;
	};
	
	int main (void)
	{	
		union U v;
		v.x =0x11223344;
		printf("%#x %#x %#x %#x",v.c[0],v.c[1],v.c[2],v.c[3]);
		printf(" &int = %p, &array = %p\n",&v.x, v.c);
		return 0;
	}
2.3.4.2 使用价值

结构体tagPacket 描述了一个内存块,这个内存块确切来讲是一个容器。你可以把  STRUCTTYPE1   STRUCTTYPE2   STRUCTTYPE3   STRUCTTYPE4 , 四种类型数据直接拷贝进来,然后根据pktType字段进行区别处理

typedef unsigned char BYTE;
//报文内容联合体
typedef union tagPacketContent
{
  STRUCTTYPE1 pkt1;
  STRUCTTYPE2 pkt2;
  STRUCTTYPE3 pkt1;
  STRUCTTYPE4 pkt2;
}PacketContent;
//统一的报文数据结构
typedef struct tagPacket
{
  BYTE pktType;
  PacketContent pktContent;
}Packet;

2.3.5 枚举类型

枚举类型按照理解 类型的字面值应当限定在我们需要的那么几种,但是C编译器可以对枚举类型变量随意赋值!!!,这一点在C++是禁止的。

附注:enum.c 使用Gcc 编译顺利通过

// enum.c 
enum Items {
	a,b,c,d,e
};
int main (void)
{
	enum Items i;
	i = 10;
	return 0;
}

附注:enum.cpp 使用G++ 编译器编译失败

// enum.cpp
#include <iostream>
using namespace std;
enum Items {
	a,b,c,d,e
};

int main (void)
{
	enum Items i;
	i = 10;
	return 0;
}

C++允许如下语法,因为枚举类型必为整型

// enum.cpp
#include <iostream>
using namespace std;
enum Items {
	a,b,c,d,e
};
enum {UP=0,DOWN=1,LFS=2,RHS=3};
int main (void)
{
	enum Items i;
	int tmp  = i;
	cout << e <<endl;
	cout <<DOWN <<endl;
	return 0;
}

2.3.6 引用类型

C语言指针的使用给编程带来自由的同时,也产生相当的编程风险
C++基于风险考虑,引入了引用类型。引用本质上是C指针

1、 引用 即 变量别名,一但被初始化(和变量绑定),该引用变量就相当于该变量

#include <iostream>
int main()
{
	using namespace std;
	
	int a = 100;
	int& b = a;
	
	cout << a << ' ' << b << endl; //100 100
	b = 99;
	cout << a << ' ' << b << endl; //99 99
	return 0;
}

2、引用和函数
下面的加法有效改变调用者使用的变量,减法对调用者变量没有影响

#include <iostream>
using namespace std;

void inc(int& a)
{
	a++;
}
void dec(int b)
{
	b--;
}

int main(void)
{
	int x  = 99;
	
	inc(x);
	cout << "x after inc : " << x << endl;
	
	dec(x);
	cout << "x after dec: " << x << endl;
 	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值