第02章 变量和基本类型

C++ primer 5th 第2章    变量和基本类型

=====================================================================

第2章   变量和基本类型   030页

=====================================================================

算术类型(arithmetic type)

        

表2.1:C++:算术类型

bool

布尔类型

未定义

char

字符

8

wchar_t

宽字符

16

char16_t

Unicode字符

16

char32_t

Unicode字符

32

short

短整型

16

int

整形

16

long

长整型

32

long long

长整型

64

float

单精度浮点型

6位有效数字

double

双精度浮点型

10位有效数字

long double

长双精度浮点型

10位有效数字

 

=====================================================================

第2章   变量和基本类型   034-35页      类型

=====================================================================

//QQ108201645编写
#include 
int main()
{
	//大括号采用局部定义,防止变量名冲突
	{
		std::cout << "第1部分" << std::endl;
		unsigned u = 10;
		int i = -42;
		std::cout << i + i << std::endl;//输出-84
		std::cout << u + i << std::endl;//输出4294967264
	}
	{
		std::cout << "第2部分" << std::endl;
		unsigned u1 = 42, u2 = 10;
		std::cout << u1 - u2 << std::endl;//输出32
		std::cout << u2 - u1 << std::endl;//输出4294967264
	}

	{
		std::cout << "第3部分" << std::endl;
		for (int i = 10; i >= 0; --i)
		{
			std::cout << i << std::endl;
		}
	}
	{/*
	 std::cout << "第4部分" << std::endl;
		for (unsigned u = 10; u >= 0; --u)//意味着死循环,变量u永远不会小于0
		{
			std::cout << u << std::endl;
		}
		*/
	}
	{
		std::cout << "第5部分" << std::endl;
		//用while来代替for循环
		unsigned u = 11;
		while (u > 0)
		{
			--u;
			std::cout << u << std::endl;
		}
	}
	{
		std::cout << "第6部分" << std::endl;
		unsigned u = 10, u2 = 42;
		std::cout << u2 - u << std::endl;
		std::cout << u - u2 << std::endl;
		int i = 10, i2 = 42;
		std::cout << i2 - i << std::endl;
		std::cout << i - i2 << std::endl;
		std::cout << i - u << std::endl;
		std::cout << u - i << std::endl;
	}
	getchar();//接收回车关闭
	return 0;
	
}

=====================================================================

第2章   变量和基本类型   037页

换行\n               横向制表符\t    报警\a      

纵向制表符\v   退格\b                        双引号\"

反斜线\\            问号\?                        单引号\'

回车符\r            进纸符\f

换行\12             空格\40                      空字符\0

 

 

表2.2:字符和字符串字面值

前缀

含义

 

类型

u

Unicode16字符

 

char16_t

U

Unicode32字符

 

char32_t

L

宽字符

 

wchar_t

u8

UTF-8(仅用字符串面字符)

 

char

整形字面值

浮点形字面值

后缀

最小匹配类型

后缀

类型

u or U

unsigned

f或F

float

l or L

long

l或L

long double

ll or LL

long long

 

 

 

=====================================================================

第2章   变量和基本类型   040页

2.3C++关键字

alignas

continue

friend

register

true

alignof

decltype

goto

reinterpret_cast

try

asm

default

if

return

typedef

auto

delete

inline

short

typeid

bool

do

int

signed

typename

break

double

long

sizeof

union

case

dynamic_cast

mutable

static

unsigned

catch

else

namespace

static_assert

using

char

enum

new

static_cast

virtual

char16_t

explicit

noexcept

struct

void

char32_t

export

nullptr

switch

volatile

class

extern

operator

template

wchar_t

const

false

private

this

while

constexpr

float

protected

thread_local

 

const_cast

for

public

throw

 

 

=====================================================================

 

第2章   变量和基本类型   044页    全局对象与局部对象

=====================================================================

//QQ108201645编写
#include 
int reused = 42;
int main()
{
	int unique = 0;//unique拥有块作用域
	//输出#1:使用全局变量reused;输出42 0
	std::cout << reused << " " << unique << std::endl;
	int reused = 0;//新建局部变量reused,覆盖了全局变量reused
	//输出#2:使用全局变量reused,输出0 0
	std::cout << reused << " " << unique << std::endl;
	//输出#3:显示的访问全局变量reused;输出42 0
	std::cout << ::reused << " " << unique << std::endl;
	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   045页    引用

=====================================================================

//QQ108201645编写
#include 

int main()
{
	int ival = 1024;
	int &referenceVal = ival;
	std::cout << "referenceVal = "<

=====================================================================

第2章   变量和基本类型   048页    指针

=====================================================================

//QQ108201645编写
#include 

int main()
{
	int *p1 = nullptr;//等价于*p1=0
	int *p2 = 0;//直接初始化为0
	int *p3 = NULL;//等价于*p3=0
	if (p1==p2&&p2==p3&&p3==0)
	{
		std::cout << "p1 and p2 and p3 of Null" << std::endl;
	}

	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   049页-52      指针

=====================================================================

//QQ108201645编写
#include 

int main()
{
	{
		int i = 42;
		int *pi = 0;//pi被初始化,但没有指向任何对象
		int *pi2 = &i;//pi2被初始化,存有i的地址
		int *pi3;//如果pi3定义于块内,则pi3的值是无法确定的
		pi3 = pi2;//pi3和pi2指向同一个对象i
		pi2 = 0;//现在pi2不指向任何对象了

	}
	{
		int ival = 1024;
		int *pi = &ival;//pi的值被改变了指向了ival
		*pi = 0;//ival的值被改变,指针pi并没有改变
		int *pi2 = &ival;//pi2是一个合法的指针,存放着ival的地址
		if (pi)//pi的值是0,因为条件值是false
		{
			;
		}
		if (pi2)//pi2指向ival,因些它的值不是0,条件值为true
		{
			;
		}
		{
			double obj = 3.14, *pd = &obj;
			//void *能存放任意类型对象的地址
			void *pv = &obj;//obj可以是任意类型的对象
			pv = pd;//pv可以存放任意类型的对象
		}
	}
	//练习题2.20
	{
		int i = 42;//
		int * p1 = &i;//p1指针存放i变量的地址
		*p1 = *p1 *= *p1;//*p1存放i的地址里的值相乘
		std::cout << "*p1 = " << *p1 << std::endl;
	}
	//练习题2.21
	{
		int i = 0;
		//double *bp = &i;//int 不能转换为double
		//int *ip = i;//不能将int 初始化给int *
		int *p = &i;//把i的地址存放在p正确,指针p指向i的地址
	}
	//练习题2.22
	//if(p)//p是一个int 型指针,如果!=0表示有存放int类型地址,条件为true
	//否则为false
	//if(*p)//判断p指针所指向地址的值是否为0,不是0,条件为true,否则为false
	{
		int i = 1024;
		int *p = &i;//p指向i的地址
		int &r = i;//r是i地址的引用
		std::cout << "i = " << i << std::endl;
		std::cout << "p = " << p << "\t *p = " << *p << "\t &p = " << &p << std::endl;
		std::cout << " &r = " << &r << " r = " << r << std::endl;
		r = 6;
		std::cout << "r = " << r << "\t i = " << i << "\t *p = " << *p << std::endl;


	}
	{
		//int *p1, p2;//p1是指向int 类型的指针,p2是int
		//int *p1,*p2//p1和p2都是指向int 类型的指针
		//int *p1;
		//int *p2;//同上
	}
	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   052页    指针的指针,指针引用

=====================================================================

//QQ108201645编写
#include 

int main()
{
	int ival = 1024;
	int *pi = &ival;//pi指向一个int 型的地址
	int **ppi = π//ppi是指针的指针。指向一个int 型指针的地址
	std::cout << "The value of ival\n"
		<< "direct value: " << ival << "\n"
		<< "indirect value: " << *pi << "\n"
		<< "doubly indirect value: " << **ppi
		<< std::endl;
	int i = 42;
	int *p;//p是一个int类型指针
	int *&r = p;//r是一个对指针p的引用//*r表示r引用的是一个指针
	r = &i;//r引用了一个指针,因此给r赋值&i就是令p指向i
	*r = 0;//解引用r得到i,也就是p指向的对象,将i的值改为0
	int** &a = ppi;
	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   053页    const限定符

=====================================================================

//QQ108201645编写
//定义一个get_size.h头文件
//extern int j;//其它文件可以声明一下就可以使用j
//输入如下内容
#ifndef _GET_SIZE_
#define _GET_SIZE_ 
extern const int x;//可以在文件间共享,不用单独定义
int get_size()
{
	return x;//返回extren const int x的值
}

#endif

―――――――――――――――――――――――――――――――――――――――

 

#include 
extern const int x = 10;//确保在#include "get_size.h"前,调用文件头能调用到extren const int x
//extern 可以让一个定义在多文件下共享
#include "get_size.h"

int main()
{
	
	
	const int bufSize = 512;
	//bufSize = 512;//非法,常量一经初始化就不能改变里面的值
	const int i = get_size();//正确编译时初始化
	//const int k;//错误;k是一个未经初始化的常量
	{
		int i = 42;
		const int ci = i;//正确: i的值赋值给了ci;
		int j = ci;//正确: ci的值赋值给了j
	}
	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   055页    常量的引用

=====================================================================

//QQ108201645编写
#include 
int main()
{
	int i = 42;
	const int &r1 = i;//允许将const int&绑定到一个普通int 对象上
					//正确:r1是一个常量引用
	const int& r2 = 42;
	const int &r3 = r1 * 2;//r3是一个常量引用
	//int &r4 = r1 * 2;//错误:r4是一个普通的非常量引用
	double dval = 3.14;
	const int &ri = dval;//初始化”: 从“double”转换到“const int”,可能丢失数据

	const int temp = dval;//由双精度浮点数生成的一个临时的整型常量
	//“初始化”: 从“double”转换到“int”,可能丢失数据
	const int &ri1= temp;//让ri1绑定这个临时常量
	//“初始化”: 从“double”转换到“const int”,可能丢失数据
	system("pause");
	return 0;

}

=====================================================================

第2章   变量和基本类型   056页    常量的引用与常量指针

=====================================================================

//QQ108201645编写
#include 
int main()
{
	int i = 42;
	int &r1 = i;//引用ri绑定对象i
	const int &r2 = i;//r2绑定对象i,但不允许通过r2修改i的值
	r1 = 0;//“r1”并非常量: 能给r1赋值
	//r2 = 0;//“r2”: 不能给常量赋值
	const double pi = 3.14;//pi是个常量,它的值不能改变
	//double *ptr = π//错误:ptr是一个普通指针
	const double *cptr = π//正确:cptr可以指向一个double常量
	//*ctr = 42;//错误:不能给常量指针赋值
	double dval = 3.14;//dval是一个双精度浮点数,它的值可以改变
	cptr = &dval;//正确:但不能通过cptr改变dval的值
	int errNumb = 0;
	//原理const在“*”号左边,不能通过常量改变指向对向的值
	//const在“*”号右边,常量指针所指向的值不能再次指向其它地址
	int *const curErr = &errNumb;//curErr将一直指向errNumb
	std::cout << " errNumb = " << errNumb << " curErr = " << *curErr << std::endl;
	*curErr = 6;
	std::cout << " errNumb = " << errNumb << " curErr = " << *curErr << std::endl;
	const double PI = 3.14159;
	const double *const pip = &PI;//pip是一个指向常量对象的常量指针

	//*pip = 2.72;//“pip”: 不能给常量赋值
	
	system("pause");
	return 0;
}

=====================================================================

第2章   变量和基本类型   057页    常量相关练习

=====================================================================

//QQ108201645编写
#include 
int main()
{
	int i2=0;
	//练习a
	{
		int i = -1;
		//int &r = 0;//无法从“int”转换为“int &”
	}
	//b
	{

		int *const p2 = &i2;
	}
	//c
	{
		const int i = -1;
		//int &r = 0; //“初始化”: 无法从“int”转换为“int &”
	}
	//d
	{
	
		const int *const p3 = &i2;
	}
	//e
	{
		const int *p1 = &i2;
	}
	//f
	{
		//const int &const r2;//“r2”: 必须初始化引用
	}
	//g
	{
		int i=0;
		const int i2 = i, &r = i;
	}
	{
		//练习2.28
		//a
		int i=0;
		//int *const cp;//“cp”: 如果不是外部的,则必须初始化常量对象
		//b
		int *p1=0;
		//int *const p2;//p2”: 如果不是外部的,则必须初始化常量对象
		//c
		//const int ic,&r = ic;//“ic”: 如果不是外部的,则必须初始化常量对象
		//d
		//const int *const p3;//p3”: 如果不是外部的,则必须初始化常量对象
		//e
		const int *p=0;
		{
			//练习2.29
			const int ic = 5;
			int i = ic;
			//p1 = p3;//无法从“const int *const ”转换为“int *”
			//p1 = ⁣//无法从“const int *”转换为“int *”
			const int *const p3 = ⁣
			int *const p2 = p1;
			//ic = *p3;//“ic”: 不能给常量ic赋值
		}
	}
	system("pause");
	return 0;
}

=====================================================================

第2章   变量和基本类型   057页    const 底层与顶层

=====================================================================

//QQ108201645编写
#include 
int main()
{
	//在"*"左边的是底层const,右边的是顶层const
	int i = 0;
	int* const p1 = &i;//不能改p1的指向,这是一个顶层const
	const int ci = 42;不能改ci的指向,这是一个顶层const

	const int *p2 = &ci;//不能改变p2的值。这是一个底层const
	const int *const p3 = p2;//靠右的const是顶层const,靠左是底层const
	
	const int &r = ci;//用于声明引用的都是底层const

	/*const */   //int * p = p3;//错误p3包含底层const的定义,而p没有
	p2 = p3;//正确p2和p3都是底层的const
	p2 = &i;//正确int* 能转换成const int*
	//int &r=ci;//错误const的int& 不能绑定到一个普通int 
	const int &r2 = i;//正确cont int&可以绑定在一个普通int上

	system("pause");
	return 0;
}

=====================================================================

第2章   变量和基本类型   058页    const 底层与顶层

=====================================================================

//QQ108201645编写
#include 
int main()
{
	//练习2.30

	//在"*"右边的是顶层const,左边的是底层
	const int v2 = 0;//v2 是顶层const
	int v1 = v2;//v1是普通int  把v2赋值给v1
	int *p1 = &v1, &r1 = v1;//把*p1指向v1,把引用&r1绑定v1
	const int *p2 = &v2, *const p3 = &r1, &r2 = v2;//p2是底层const,p3 是顶层const+底层const
	r1 = v2;//v2是顶层const
	//p1 = p2;//p1没有底层const
	p2 = p1;
	//p1 = p3;//p1没有p3这个底层const
	p2 = p3;
	int x;
	const int* const y = &x;
	const int *const &xx = y; //xx是一个对指针y的引用//*xx表示xx引用的是一个指针
	system("pause");
	return 0;
}

=====================================================================

第2章   变量和基本类型   058页    constexpr与常量

=====================================================================

//QQ108201645编写
//保存为文件头get_size.h
#ifndef _GET_SIZE_
#define _GET_SIZE_ 
//const int num = 10;失败

constexpr int get_size()
{
	return 10;//返回10
}

#endif

―――――――――――――――――――――――――――――――――――――――

#include 
#include "get_size.h"
int main()
{
	{
		const int max_files = 20;//max_files是常量表达式
		const int limit = max_files + 1;//limit是常量
		int staff_size = 27;//staff_size不是常量
		const int sz = get_size();
	}
	{
		//声明为constexpr类型可以由编译器来验证变量是不是常量表达式
		constexpr int mf = 20;//20是常量表达式
		constexpr int limit = mf + 1;//mf+1是常量表达式
		constexpr int sz = get_size();//只有当size是一个constexpr函数时
		//才是一条正确的声明
	}
}

=====================================================================

第2章   变量和基本类型   059页    constexpr常量、指针

=====================================================================

//QQ108201645编写
#include 
int main()
{
	{
		const int *p = nullptr;//p指向整型常量(底层const)
		/*例子
		const int ci = 42;不能改ci的指向,这是一个顶层const
		const int *p2 = &ci;//不能改变p2的值。这是一个底层const
		*/
		constexpr int* q = nullptr;//q是一个指向整数的常量指针(顶层const)
		std::cout << q << std::endl;
	}
	{
		constexpr int* np = nullptr;//np是一个指向整数的常量指针,值为空
		int j = 0;
		constexpr int i = 42;//i的类型是整型常量(顶层const)
		//i和j都必须定义在函数体外
		constexpr const int *p = &i;//p是常量指针指向整型常量这里面的const是底层const
		//constexpr是顶层const

		constexpr int *p1 = &j;//p1是常量指针,指向整数j

	}
}

=====================================================================

第2章   变量和基本类型   060页    typedef类型别名

=====================================================================

//QQ108201645编写
#include 
#include "Sales_item.h"
int main()
{
	typedef double wages;//wages是double的同义词
	typedef wages base, *p;//base是double的同义词,p是double*的同义词
	/*constexpr int i = 42;
	constexpr const int* pp = &i;*/
	using Si = Sales_item;//Si是Sales_item的同义词
	using int_ = unsigned char;//int_ 是char的同义词
	char nstr=0;
	typedef char *pstring;
	const pstring cstr = &nstr;//cstr是指向char的常量指针
	const pstring *ps=&cstr;//ps是一个指针,它的对象是指向char的常量指针
	const char tostr=0;
	const char * ntstr = &tostr;

}

=====================================================================

第2章   变量和基本类型   061页    auto 类型说明符《未用system(“pause”) 请用f11调试

=====================================================================

//QQ108201645编写
#include 
int main()
{
	int val1 = 9;
	int val2 = 2;
	//auto从右到左。处理第一个开始推断类型
	auto item = val1 + val2;//由val1与val2相加推断出itemr相加的结果
	std::cout << item << std::endl;
	auto i = 0, *p = &i;//正确:i是整数,p是整数指针
	//auto sz = 0, pi = 3.14;//错误:sz与pi的类型不一样
	
}

=====================================================================

#include 
int main()
{
	int i = 0, &r = i, number = 3, &variable = number, price = 4;
	auto a = r;//a是一个整数(r是i的别名,而i是一个整数)
	//auto会忽略顶层const
	const int ci = i, &cr = ci;
	auto b = ci;//b 是一个整数(ci的顶层const 被忽略掉了)等同于int类型的 b = ci
	//ci = 8;不能给常量赋值
	b = 8;//顶层const被忽略后可以给b赋值
	std::cout << "ci = " << ci << "\t cr = " << cr << "\t b = " << b << std::endl;
	//---------------------------------
	auto c = cr;//c是一个整数(cr是ci的别名,ci本身是一个顶层const)等同于int类型的 c = cr
	c = variable;
	std::cout << "c = " << c << std::endl;
	c = price;
	std::cout << "c = " << c << std::endl;
	//---------------------------------
	auto d = &i;//d是一个整形指针(整数的地址就是指向整数的指针)等同于int*类型的 d = &i
	std::cout << "d = " << d << std::endl;
	*d = 6;
	std::cout << "d = " << d <<"\t i = "<=====================================================================

//2.33-2.34练习
	auto a = 42;//a是整数
	auto b = 42;//b是整数
	auto c = 42;//c是整数
	auto d = 42;//错误:d是int*
	auto e = 42;//错误:e是const int *
	auto g = 42;//错误:g是一个常量引用,绑定到ci
//练习2.35
#include 
int main()
{
	const int i = 42;//顶层const
	auto j = i;//j是一个int 整型
	std::cout << " i = " << i << "\t j = " << std::endl;
	const auto &k = i;//k是一个常量引用,绑定到i
	std::cout << " k = " << k << std::endl;
	auto *p = &i;//p等同于cosnt int *	(底层const)
	int number = 9;
	p = &number;//可以改变指针的指向,但不能通过指针改变内容
}

=====================================================================

第2章   变量和基本类型   063页    decltype类型指示符

=====================================================================

 

//QQ108201645编写
#include 
int f()
{
	return 0;
}
int main()
{
	int num = 3;
	decltype(f()) sum= num;//f()返回类型定义为int,所以sum类型是int
						//编译器并不实际调用函数f,
	//而是使用当调用发生时f的返回值类型作为sum的类型。
	//换句话说,编译器为sum指定的类型是什么呢?就是假如f被调用的话将会返回的那个类型。
	std::cout << sum << std::endl;
	//decltype使用表达式是一个变量,则包含这个变量的类型(顶层const和引用在内)
	const int ci = 0, &cj = ci;
	decltype(ci) x = 0;//x的类型是const int,初始化为0
	decltype(cj) y = x;//y的类型是const int &,y绑定到x
	//decltype(cj) z;//错误:z是一个引用,必须初始化
	int i = 42, *p = &i, &r = i;
	decltype(r + 0) b;//正确:加法结果是int,因此b是一个未经初始化的int
	//decltype(*p) c;//错误,c是int&,必须初始化
	decltype(p) c=&i;//c是int*,必须初始化
	//-----------------------
	//如果decltype的表达式加上括号的变量,结果将是引用
	//decltype((i)) d;//错误:d是int& ,必须初始化
	decltype((i)) d = num;
	//加上双层括号就永远是引用,如果只有一个括号就只当variable是引用是才是引用
	std::cout << "d = " << d << std::endl;
	decltype(i) e;//正确:e是一个未初始化的int
}

=====================================================================

//练习2.36
#include 

int main()
{
	int a = 3, b = 4;
	decltype(a) c = a;
	decltype((b))d = a;
	std::cout << "a = " << a << "\t b = " << b << "\t c = " 
		<< c << "\t d = " << d << std::endl;
	++c;//c的值++
	++d;//引用++就是++a
	std::cout << "a = " << a << "\t b = " << b << "\t c = "
		<< c << "\t d = " << d << std::endl;
}
/*
输出
a = 3    b = 4   c = 3   d = 3
a = 4    b = 4   c = 4   d = 4
*/

=====================================================================

//练习2.37
#include 

int main()
{
	int a = 3, b = 4;
	decltype(a) c = a;
	decltype(a = b)d = a;//这个是int&引用,其它是int
	std::cout << " a = " << a << "\t b = " << b<< "\t c = "
		<< c << "\t d = " << d << std::endl;
	system("pause");
}

=====================================================================

第2章   变量和基本类型   064页    定义Sales_item类型

=====================================================================

//QQ108201645编写
//保存为Sales_data.h头文件
#ifndef _SALES_DATA_H_
#define _SALES_DATA_H_


struct Sales_data
{
	std::string bookNo;
	unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
	double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号

#endif

―――――――――――――――――――――――――――――――――――――――

#include 
#include //包含string头文件
#include "Sales_data.h"

int main()
{
	Sales_data data1, data2;
	//读入data1与data2的代码
	//检查data1与data2的isbn是否相同
	//如果相同,求两个总和
	double price = 0;//书的单价
	std::cout << "输入第1笔交易:书的编号、销售数量、单价" << std::endl;
	std::cin >> data1.bookNo >> data1.units_sold >> price;
	//调用方法对象名.成员/或者对象名.成员函数
	//计算销售收入
	data1.revenue = data1.units_sold*price;
	std::cout << "输入第2笔交易:书的编号、销售数量、单价" << std::endl;
	std::cin >> data2.bookNo >> data2.units_sold >> price;
	data2.revenue = data2.units_sold*price;//财政收入等于数量乘单价

	if (data1.bookNo == data2.bookNo)
	{
		unsigned totalCnt = data1.units_sold + data2.units_sold;
		double totalRevenue = data1.revenue + data2.revenue;
		std::cout << data1.bookNo << " " << totalCnt
			<< " " << totalRevenue << std::endl;
		if (totalCnt != 0)
		{
			std::cout << totalRevenue / totalCnt << std::endl;
		}
		else
		{
			std::cout << "(no sales)" << std::endl;
		}
		//标示成功
	}
	else
	{
		//两笔交易的ISBN不一样
		std::cerr << " Data must refer to the same ISBN"
			<< std::endl;
		//标示失败
	}


	system("pause");
	return 0;
}

=====================================================================

 

 

你可能感兴趣的:(C++,primer,第5版,代码实例化(可运行)笔记)