时间: 2019-07-24 文章来源: 洋蜜蜂
C++是计算机课程中的较复杂的一门,很多学生学习起来枯燥且吃力,但若是能学好,对以后出来找工作有很大的帮助。接下来洋蜜蜂的Online Tutor就给各位留学生解析关于C++的一些基础。
(1)union
联合和struct是几乎一样的语法,所不同的就是内存结构上,union的各个元素共享一个空间,union的总体空间以元素的最空间为准。一次只有一个元素有效(最后一个被赋值的元素有效),其他的元素如果在没有被赋值的情况下的值,是一个不确定的值。
union就像是一个对于一段内存空间,向外可以表现出各种类型。
union test
{
int a;
int b;
char c;
short d;
float e;
char * f;
}test1;
由于不管哪种数据在内存空间中都是以0101来存储的,所以这使得,union成为可能。也就是说,不同的数据类型从同一个内存空间读出来的是不通的(解码的规则不同)。
事实上,union用于表达一个事物属性有可能的不同数据类型,所以,同一时刻只应该有一个元素被使用,并且该元素是最近一次被赋值的。
但是其它的元素,在没有被赋值的情况下,也可以读出数据来,但是这个时候由于该内存空间中的0101代码不是为该类数据类型个设定的(但有可能是同类型,或者相容类型)。所以用户读出来的结果是不确定了。
兼容的数据类型之间(int,char,short)这种转换是可以的,但是int和float之间却是不能访问的。
test1.a=97;
则test1.b==97,test1.c=='a' test1=97.因为他们是兼容的。
但是这个时候.
test1.e==0.0000,说明它与int,char这样的不兼容。
后来再输出test1.a发现等于97.
所以对于union改变该内存空间数据的只有赋值,使用哪种元素读(不管能不能正确读出),只是对该内存空间的不同解释罢了,float就无法解释int的内存空间,所以返回的结果是0.000.但是,内存空间并不会因为这次的读而发生改变。
注意,这个结构体的最后一项,也就是指向字符的指针,如果使用%s,基本时出现段错误,因为%s输出的时候,从该地址开始一直到\0结束。
union的一个应用就是拆分数据的字节。一个int内省在C++中有四个字节,我们可以通过如下方式分别得到这是个字节
union test
{
int a;
char b[4];
}testT;
testT.a=0x01202343;
printf("%x,%x,%x,%x",testT.b[0],testT.b[1],testT.b[2],testT[3]);
输出结果为43,23,20,01。分别输出来了,但是顺序有点奇怪,这是为什么呢?
这就是,很多系统存储数据的时候的高地位问题,经常是数的低位字节放在低地址,高位字节放在高位地址。通常我们表达地址时,是从左到右,地址增高(从低地址到高地址)。而我们平时看number的时候是从左到右,字节从高到低,所以恰好相反。这就是我们要注意的。
(2)无符号整数和有符号整数的转换
整数分为无符号和有符号,通常无符号整数用户作为序号,所以也就没有正负的概念,也就可以省出1各位来存放更大的数。但是,同样是我们前面的将的,两者之间的转换并不牵涉内存空间上的0101代码出现变动,只是程序、系统将该部分内存空间怎么读取而已。
int a=-10;
unsigned int b=-10;
的内存空间上的内容是一样的,为什么呢?不管是那个赋值语句,-10这个常量的内容是确定好的,分别拷贝在a和b空间中,所不同的是,系统读取a时认为第一个位是代码符号位;而读取b是,第一个位仍然是数。
所以,当某个变量已经是一个无符号整数的时候,不要用有符号整数的相关语句来操作它(尤其它负数),基本南辕北辙。这里就有一个陷阱题。
int a=6;
unsigned int b=-20;
print("%d",a+b);
print("%d",(a+b)>6);
分别输出的是-14和1.
有人会说这矛盾,但是这只是你写错了。因为a+b已经变成了unsigned int(想大转换原理)。所以第一个输出应该用%u 来输出。(a+b)>6判断的时候,由于我们系统已经制定a+b是一个unsigned int,所以它自然是一个很大的所谓的正数。
其实我们要注意的是,a+b,本来就很有争议,因为运算器,接收a和b,他们虽然会被转换成无符号数,但是,仍然使用那种相加(以有符号模式相加,这也是使用补码的格式保存负数的原因)。所以计算出来的结果使用%d输出自然是-14,你这种输出,更使用%d输出字符元素是一回事,a+b这个变量存储的是一个无符号整数,系统比较它和6时是把它当成一个很大的正数来比较的。
使用补码保存负数,让计算机中的计算器的加法和减法统一,利于设计。对于CPU的运算器(加减法)来说,它只知道接收两个寄存器上的数据(对它来说,没有正负之分),然后进行最简单的二进制加法。结果就是正确的结果。所以a+b在运算器中的运算结果是一致的,不会因为你是无符号还是有符号,关键在于如何去解码运算器的结果。
(3)printf输出格式控制
1.转换说明符
%a(%A) 浮点数、十六进制数字和p-(P-)记数法(C99)
%c 字符
%d 有符号十进制整数
%f 浮点数(包括float和doulbe)
%e(%E) 浮点数指数输出[e-(E-)记数法]
%g(%G) 浮点数不显无意义的零"0"
%i 有符号十进制整数(与%d相同)
%u 无符号十进制整数
%o 八进制整数 e.g. 0123
%x(%X) 十六进制整数0f(0F) e.g. 0x1234
%p 指针
%s 字符串
%% "%"
2.标志
左对齐:"-" e.g. "%-20s"
右对齐:"+" e.g. "%+20s"
空格:若符号为正,则显示空格,负则显示"-" e.g. "% 6.2f"
#:对c,s,d,u类无影响;对o类,在输出时加前缀o;对x类,在输出时加前缀0x;
对e,g,f 类当结果有小数时才给出小数点。
3.格式字符串(格式)
[标志][输出最少宽度][.精度][长度]类型
"%-md" :左对齐,若m比实际少时,按实际输出。
"%m.ns":输出m位,取字符串(左起)n位,左补空格,当n>m or m省略时m=n
e.g. "%7.2s" 输入CHINA
输出" CH"
"%m.nf":输出浮点数,m为宽度,n为小数点右边数位
e.g. "%3.1f" 输入3852.99
输出3853.0
长度:为h短整形量,l为长整形量
C++作为世界上的运用最多的计算机语言,学好之后受益无穷。如果有同学选择了这门专业学习,但总是不得要领的话,可以点击联系洋蜜蜂寻求一对一的在线C++辅导帮助哦。