摘要:
// 第二十五章补充内容 16 位运算//位运算直接对二进制位进行的运算,C++提供了可以对位进行操作的位运算符// & 按位与(AND)// | 按位或(OR)// ^ 按位异或(XOR)// ~ 按位非(NOT)(取反)// >> 右移动运符// >> 左移动运算符//16.1 按位与"&"运算符//补码的设计目的如下//1 统一正零和负零//2 使减法运算转换为加法运算//3 使负数在计算时与正数一样正确//订算机储存有符号整数时,是用该整数的补码进行储存,0的原码,返码,补码都是0,正数的原码,反码和补码可以简单的理解为相同, 阅读全文
摘要:
// 第二十五章补充内容 17位字段/*#include <iostream>using namespace std;struct Date{ unsigned day: 5; unsigned month:4; unsigned year:14;};//Date类型使用的是位段结构,这里使用的是unsigned,unsigned后面跟的是位字段名,如day//在位字段后面跟一个冒号,后跟一个数字,这个数字告诉编译器为该变量分配了多少个位,如果你写1,那么这人只能表示0或者1int main(){ Date date; date.day = 12; cout<<&quo 阅读全文
摘要:
// 第二十五章补充内容 18区域差异// 1 语言// 2 货币表示// 3 字符// 4 字符集// 5 时间表示的不同//18.1 locale类//为了解决地区差异,C++为我们提供了一个locale类//18.2 默认区域表示或全局区域表示//18.3 时间与地理设置//1 time返回系统当前的日历时间//该函数需要头文件time.h//time_t time(time_t *time)/*#include <time.h>#include <iostream>using namespace std;int main(){ struct tm *ptr; t 阅读全文
摘要:
//C++的关键字/*auto 声明自动变量,一般不使用bool 声明一个布尔型变量break 跳出当前循环asm 插入一个汇编指令case 开关语句分支catch 处理throw产生的异常char 声明一个字符弄变量class const 声明一个常量const_case 从一个const变量中抛出cintinuedefaultdelete 释放内存dodoubledynamic_cast 动态投射elseenumexplicit 仅用在构造器的正确extern 声明变量是在其他文件中声明(也可以看作是引用变量)falsefloatforfriend 允许非函数成... 阅读全文
摘要:
//第二十五章补充内容 13联合数据类型的内存占用//联合数据类型的每个成员共享同一块内存,那么这样做目的是什么呢?//由于所有成员共享一块内存,这样,我们不用为每个成员分配一块内存,因此可以大大节省了内存,/*#include <iostream>using namespace std;union U1{ char c; int i; double d;};struct S1{ char c; int i; double d;};union U2{ char c; int i;};struct S2{ char c; int i;};union U3{ char c;... 阅读全文
摘要:
//第二十五章补充内容 14匿名联合体//C++允许没有名字的联合体/*#include <iostream>using namespace std;int main(){ union{ int a; int b; }; cout<<"请输入a的值:"; cin>>a; cout<<"a:"<<a<<"\t"<<"b:"<<b<<endl; cout<<"请输入b的值:"; c 阅读全文
摘要:
// 第二十五章补充内容 15再谈指针// 15.1 指针与数组/*#include <iostream>using namespace std;int main(){ int ch[2][3] = { {0,1,2}, {10,11,12} }; int *p1 = &ch[1][2]; //指向12的地址 int *p2 = ch[1] + 2; //指向3的地址,也就是第四个元素的地址 //最先的理解是错的,char[1]也就是第个行的数据,然后加1,不就是ch[1][2] 12 int *p3 = ch[0]; //0 int *p4 = ch[1]; //10 c 阅读全文
摘要:
// 第二十五章补充内容 12联合数据类型union//联合体与结构体有什么不同之处//1 初始化,联合类型union只能对它的第一个成员进行初始化/*#include <iostream>#include <string>using namespace std;union people{ char name[10]; short int age; float weight;};void show(people);int main(){ people Jack={"Xlc"}; show(Jack); return 0;}void show(peop 阅读全文
摘要:
//第二十五章补充内容 9 关键字volatile//用volatile关键字声明的变量,是用来告诉编译器每次对此变量的引用都需要从内存地址中读取,即取消编译器对此变量的优化编译//volatile可以保证对特殊地址的稳定访问,不会出错//register寄存器变量/*#include <iostream>using namespace std;int dquare(volatile int *p){ return (*p)*(*p);}int func(int n){ register int i, s=0; for(i=0; i<=n; i++) { s = s+i; } 阅读全文
摘要:
// 第二十五章补充内容 10 关键字const//const int a;//int const a//const int *a//int * const a;//int const * a const;//const int a与int const a的作用是一样的,都表示a是一个常整型数//const int *a意味着a是一个指向常整型号数的指针,换句话说,a指向的整型数是不可修改的//int * const a的意思是a是一个指向整型数的常指针,也就是说,指针a指向的整型数是可以修改的,但指针a是不可修的//int const * a const意味着a是一个指向常整型数的常指针,也 阅读全文
摘要:
//第二十五章补充内容 11 关键字mutable//我们知道修饰为const的成员函数,是不能修改类的数据成员的,但是这并不表示它不可以修改经过mutable修饰后的数据成员,关键字mutable将其后的数据修饰为可供const成员函数进行修改的数据成员/*#include <iostream>#include <string>#include <iomanip>using namespace std;class A{public: A(int i):x(i){} int add()const //注意这里是const { return ++x; } vo 阅读全文
摘要:
// 第二十五章补充内容 5 不能为0的变量/*#define DEBUG#include <iostream>#include <string>using namespace std;#ifndef DEBUG#define ASSCET(x)#else#define ASSCET(x)\ if(!(x))\ {\ cout<<"错误!ASSERT("<<#x<<")宏函数执行失败"<<endl;\ cout<<"错误的代码出现在第"<< 阅读全文
摘要:
// 第二十五章补充内容 6 用宏函数来输出表达式的值/*#define DEBUG#include <iostream>using namespace std;#ifndef DEBUG#define show(x)#else#define show(x)\ cout<<#x<<": \t"<<x<<endl;#endifint main(){ int x = 9; show(x); //9 int *y = &x; show(*y); //9 show(y); //内存地址 char *ch=" 阅读全文
摘要:
// 第二十五章补充内容 7 调试的级别/*#include <iostream>#include <string>using namespace std;#define DEBUG 2#if DEBUG < 2 #define ASSERT(x)#else#define ASSERT(x)\if(!(x))\{\ cout<<"错误!Assert("<<#x<<")宏函数执行失败"<<endl;\ cout<<"错误代码出现在第"<< 阅读全文
摘要:
//第二十五章补充内容 8 C++类型转换及运行时类型信息(RTII)//C++中有四种新风格的类型转换操作符,每一种操作符返回的是一个根据类型转换操作符规则转换后的对像//cast_operator<type>(object)//type代表要转换的类型//object代表要转换的对像//而cast_operator则是执行转换的操作符,它通常有四种形式,分别为动态类型转换,静态类型转换,重新解释类型转换和常类型转换符//8.1 动态类型转换符//动态类型转换符将一个基类的引用或者指针转换为一个派生类的引用或者指针,我们把它叫做向下类型转换//或者将一个派生类的引用或指针转换为基 阅读全文
摘要:
//第二十五章补充内容 3 assert()宏//有的编译器还提供了assert()宏,这个宏在许多书中被翻译为断言,它的作用是当assert()的参数为真时,返回真,假如参数值为假,那么它将执行某种操作/*#include <iostream>#include <assert.h>using namespace std;void main(){ float a, b; cout<<"请输入除数:"<<endl; cin>>a; cout<<"请输入被除数:"<<endl 阅读全文
摘要:
//第二十五章补充内容 4 尝试编写一个简单的assert()宏/*#include <iostream>using namespace std;//结尾处的正斜杠"\"将本行语句与后面的语句连为一句#define ASSERT(x)\ if(!(x))\ {\ cout<<"错误!ASSERT("<<#x<<")宏函数执行失败"<<endl; \ cout<<"错误代码出现在第"<<__LINE__<<"行& 阅读全文
摘要:
//第二十五章补充内容 2 预定义的宏/*__DATE__ 进行预处理的日期("Mmm dd yyyy"形式的字符串方字)__FILE__ 代表当前源代码文件名的字符串文字__LINE__ 代表当前源代码中的行号的整数常量__TIME__ 源文件编译时间,格式是"hh: mm: ss"__FUNCDNAME__ 当前所有函数名*//*#include <iostream>using namespace std;void show(){ cout<<"该语句所在函数名为:"<<__FUNCDNAME_ 阅读全文
摘要:
//第二十五章补充内容 1 预处理过程//1.1 预处理指令/*# 空指令,没有任何效果#include 从该提令位置处包含一个源代码文件#define 定义一个宏#undef 取消已定义的宏#ifdef 如果给定的宏已经定义,则编译下面的代码#if 如果给定的条件成立,就编译下面的代码#elif 如果前面#if给定的条件不成立,而当前给定的条件成立,那么编译下面的代码#endif 结束一个#if...#else条件编译块#error 停止编译并显示错误信息*///1.2 #include 指令//1.3 #d... 阅读全文