1.输出结果比较
1)
输出结果:21
2)
输出结果:12。虽然循环只进行了一次,但是对!X++来说,X还是进行了自加运算。
2.指针运算
输出结果8,8.程序运行时,printf语句是从右往左进行读取,此时ptr指向8.因为*和++的优先级相同,结合顺序是从右到左,所以*ptr++等价于*(ptr++)。
3.运算符优先级
4.利用位运算实现两个整数的加法运算,请用代码实现
5.给三个整数a、b、c,函数实现取三个数的中间数,不可以使用sort,整数操作
尽可能少。
6.如何将a、b的值进行交换,并且不使用任何中间变量?
按位异或,不用担心超界。
7.下面的switch语句输出什么。
不考虑break和default,从c开始执行到结束。输出cd。
8.下面代码输出结果是多少?
解析:宏的那句被预处理器替换成了:*&array[5]-4=6;运算结果2=6;
由于减号比赋值优先级高,因此先处理减号;由于减号返回一个数而不是合法的值,所
以编译报错。
答案:程序可以正确编译,但是运行时会崩溃
8.1.在简单宏定义的使用中,当替换文本所表示的字符串为一个表达式时,容易引起误解和误用。如下例:
例1 #define N 2+2
void main()
{
int a=N*N;
printf(“%d”,a);
}
输出为8. a=2+2*2+2=8.
9.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
10.下面哪一个const是多余的?
本题中,选项A修饰函数返回值,表示返回的是指针所指向字节型值是常量;选项B的const这
样的函数是常成员函数。常成员函数可以理解为是一个“只读”函数,它既不能更改数据成员
的值,也不能调用那些能引起数据成员值变化的成员函数,只能调用const成员函数,把不会
修改数据成员的函数GetBuffer声明为const类型。这大大提高了程序的健壮性。D是多余的,因为const修饰的指针在定义时需要初始化。注:(const int*a等价于int const *a).
11.const与#define相比有什么不同?
C++语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更
多的优点:
● const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检
查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到
的错误(边际效应)。
● 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在
C++程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
12.sizeof的用法。
输出结果为4,11,100,400,4,3,4,6,8,4,4,。 size(*q3)的结果为1,a是第一个字母。
ss1是一个字符指针,指针的大小是一个定值,就是4字节,所以sizeof(ss1)是4字节。
ss2是一个字符数组,这个数组最初未定大小,由具体填充值来定。填充值是“0123456789”。1个字符所占空间是1字节,10个就是10字节,再加上隐含的“\0”,所以一共是11字节。
ss3也是一个字符数组,这个数组开始预分配100,所以它的大小一共是100字节。
ss4也是一个整型数组,这个数组开始预分配100,但每个整型变量所占空间是4,所以
它的大小一共是400字节。
q1与ss2类似,所以是4字节。
q2里面有一个“\n”,“\n”算做一位,所以它的空间大小是3字节。
q3是一个字符指针,指针的大小是一个定值,就是4,所以sizeof(q3)是4字节。
A和B是两个结构体。在默认情况下,为了方便对结构体内元素的访问和管理,当结构
体内的元素的长度都小于处理器的位数的时候,便以结构体里面最长的数据元素为对齐单
位,也就是说,结构体的长度一定是最长的数据元素的整数倍。如果结构体内存在长度大于
处理器位数的元素,那么就以处理器的位数为对齐单位。但是结构体内类型相同的连续元素
将在连续的空间内,和数组一样。
结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对
齐,则a1、a2、a3都取2字节对齐,sizeof(A)为6,其也是2的整数倍。B中a1为4字节对齐,a2
为2字节对齐,结构体默认对齐参数为8,则a1取4字节对齐,a2取2字节对齐;结构体大小为
6字节,6不为4的整数倍,补空字节,增到8时,符合所有条件,则sizeof(B)为8。
13.sizeof用法2.
输出结果:答案:4,8,8,12,24。
因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计
算在内的,所以sizeof(A1)是4。
● 为了照顾数据对齐,int大小为4,char大小为1,所以sizeof(A2)是8。
● 为了照顾数据对齐,float大小为4,char大小为1,所以sizeof(A3)是8。
● 为了照顾数据对齐,float大小为4,int大小为4,char大小为1,所以sizeof(A4)是12。
● 为了照顾数据对齐,double大小为8,float大小为4,int大小为4,char大小为1,所以
sizeof(A5)是32。
14.说明sizeof和strlen之间的区别。
sizeof(ss)结果为400,ss表示在内存中的大小,100×4。
strlen(ss)错误,strlen的参数只能是char*,且必须是以“\0”结尾的。
cout<<sizeof(X)<<endl;结果为12,内存补齐。
cout<<sizeof(x)<<endl;结果为12,理由同上。
通过对sizeof与strlen的深入理解,得出两者区别如下:
(1)sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsigned int类型。该类
型保证能容纳实现所建立的最大对象的字节大小。
(2)sizeof是运算符,strlen是函数。
(3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾的。
sizeof还可以用函数做参数,比如:
输出的结果是sizeof(short),即2。
(4)数组做sizeof的参数不退化,传递给strlen就退化为指针。
(5)大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度。
(6)strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型
占内存的大小。
(7)sizeof后如果是类型必须加括号,如果是变量名可以不加括号。这是因为sizeof是
个操作符而不是个函数。
(8)当使用了一个结构类型或变量时,sizeof返回实际的大小。当使用一静态的空间数
组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的
尺寸。
(9)数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如
fun(char [8])、fun(char [])都等价于fun(char *)。
(10)计算结构变量的大小就必须讨论数据对齐问题。为了使CPU存取的速度最快(这
同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时
经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。
这样做可能会浪费一些内存,但在理论上CPU速度快了。当然,这样的设置会在读写一些别
的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof
得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可。或者如果要按字节存
储,而不进行数据对齐,可以在Options对话框中修改Advanced Compiler选项卡中的“Data
Alignment”为按字节对齐。
(11)sizeof操作符不能用于函数类型、不完全类型或位字段。不完全类型指具有未知
存储大小数据的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void
类型等。
(12)对函数使用sizeof,在编译阶段会被函数返回值的类型取代。如:int f1(){return
0;}。
(13)数组的大小是各维数的乘积×数组元素的大小。
15。找出下面程序的错误,并解释它为什么是错的。
sizeof(strArr1)为12,sizeof(string)为4 。sizeof(pStrArr1)为4。为了能完整显示,应改成j<sizeof(*pStrArr1)*2/sizeof(string).
16.写出下面sizeof的答案。
求类base的大小。因为类base只有一个指针,所以类base的大小是4。Derive大小
与base类似,所以也是4。AA。
17.下面输出结果是什么。
因为var[]等价于*var,已经退化成一个指针了,所以大小是4。
float f占4个字节,char p占1字节,int adf[3]占12字节,总共是17字节。根据内
存对齐原则,要选择4的倍数,是20字节。
18.一个空类占多少空间?多重继承的空类呢?
这说明空类所占空间为1,单一继承的空类空间也为1,
多重继承的空类空间还是1。但是虚继承涉及虚表(虚指针),所以sizeof(C)的大小为4。