1、以下涉及到内存管理的代码中,有错误的是:
A:
int *a=new int(12);
//......
free(a);
B:
int *ip=static_cast<int *>(malloc(sizeof(int)));
*ip=10;
//......
delete ip;
C;
double *a=new double[1];
//.....
delete a;
D;
int *ip=new int(12);
for(int i=0;i<12;i++)
{
ip[i]=i;
}
delete [] ip;
解析:new和delete搭配,malloc和free搭配,所以A B错误。
关于D,要注意new int[12] 和new int (12)的区别,new int[12]生成一个大小为12 的int数组,而new int(12)是生成一个初始值为12的int变量。所以D错
关于C,乍一看,a是一个数组,应该用delete [ ] a,但是对于基本类型数组来说,delete a和delete [ ] a效果是一样的,如果a是一个用户自己定义的结构类型数组,只能 使用delete [ ] a。
2、如下代码,result变量的输出结果是多少?
#include<iostream>
using namespace std;
int i=1;
class MyCls
{
public:
MyCls():m_nFor(m_nThd),m_nSec(i++),m_nFir(i++),m_nThd(i++)
{
m_nThd=i;
}
void echo()
{
cout<<"result"<<m_nFir+m_nSec+m_nThd+m_nFor<<endl;
}
private:
int m_nFir;
int m_nSec;
int m_nThd;
int &m_nFor;
};
int main()
{
MyCls oCls;
oCls.echo();
return 0;
}
解析:首先要明白,
变量初始化的顺序是其声明的顺序,跟初始化列表中的顺序无关,所以变量的初始化顺序m_nFir(i++),m_nSec(i++),m_nThd(i++),m_nFor(m_nThd),i初始化为1,所以经过初始化列表后的m_nFir=1,m_nSec=2,m_nThd=3,m_nFor是m_nThd的一个引用,并且此时i的值为4,执行构造函数中的赋值语句后,m_nThd=4,此时m_nFor是m_nThd的一个引用,也是4。result=1+2+4+4=11。
3、由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序,下面哪个阶段会发现被调用的函数没有定义?
A:预处理 B:编译 C:链接 D:执行
解析:预处理阶段主要是对各种预处理命令的处理,包括头文件的包含、宏定义的扩展、条件编译的选择等
编译阶段进行c词法和语法的分析,首先编译成纯汇编语句,再汇编程二进制码,再生成各个目标文件
链接阶段,到了链接阶段才会知道各个函数的调用关系,才能出现调用某个函数但是该函数没有声明的情况。
4、下面哪个指针表达式 可以用来引用数组元素a[i][j][k][l]?
A:((((a+i)+j)+k)+l) B:*(*(*((a+i)+j)+k)+l) C:(((a+i)+j)+k+l) D:((a+i)+j+k+l)
解析: 如果a是一个指向四维数组的指针,那么*a就指向的是一个三维数组,**a只想一个二维数组,***a指向一个三维数组,****a指向某个元素。
5、下面的代码会输出:
int main()
{
int a[4]={1,2,3,4};
int *ptr=(int *)(&a+1);
printf("%d",*(ptr-1));
}
解析:最终结果会输出4。考察数组和指针,
指针加一的能力由指针指向的类型决定。&a和a都指的是数组首元素的地址,不同的是,a就是a+0,*(a+0)也就是a[0],而&a+1相当于对a[]类型的数组类型的指针加一,此时指针加到数组的末尾。ptr接受之后,ptr指向最后一个元素后面的那个位置,而ptr的类型是int*,因此,ptr-1之后指向数组最后一个元素4。
5、下面哪个用法是错误的
A:int *a B:extern const int array[256] C:const int &a D:typedef void (*FUN)()
解析:C错误,原因是引用定义的时候必须对其进行初始化。指针不是必须初始化,而引用是在定义的时候必须对其进行初始化。对于D,其实D定义的是一个函数指针数据类型,通过FUN foo就定义一个指向的函数参数列表为空,返回值为空的函数。详见:http://blog.youkuaiyun.com/zhangleo1987/article/details/5707290
6、有下面一段程序,则下列不合法的是
int f1(float);
int f2(char);
int f3(float);
int f4(float);
int (*pf)(float)
A:int (*p)(float)=&f1 B:pf=&f4 C:pf=&f2 D:pf=f3
解析:C错误,原因是函数参数类型不匹配。函数指针声明的方法: 返回值类型 (*指针变量名)([参数列表])
根据定义,则int (*pf)(float) int (*p)(float)=&f1 ,pf和p都是函数指针。对于函数地址的获取,可以是函数名,也可以是函数名前加取地址符&。
7、若有下列定义语句,则以下赋值语句错误的是:
定义
char s[3][10];
char (*k)[3];
char *p;
赋值:
1.p=s;
2.p=k;
3.p=s[0];
4.k=s;
解析:s是一个二维数组,也可以看成是一个一维数组,这个一维数组的每个元素是一个包含10个元素的一维数组,s指向这个包含三个元素的一维数组的第一个元素,也就是s中的第一个一维数组的第一个元素。k是一个指向有三个cha元素的数组指针。p是一个指向char变量的指针。所以1、2、4都是错误的。3是正确的,因为s[0]就指向一个一维数组。
8、math.h中abs返回值()
解析:abs的返回值可能是正数,可能是负数,可能是0。因为负数的范围比正数的范围大一。比如,8位二进制数范围是-128~+127,abs(-128)不可能返回128,只能返回原值,也就是-128,但是其他正数、负数、零都按正常取绝对值返回。
9、以下代码的执行结果是:
int _tmain(int argc, _TCHAR* argv[])
{
int i=-2147483648;
printf("%d %d %d %d",~i,-i,1-i,-1-i);
cin.get();
return 0;
}
解析:-2147483648是32位int所能表示的最小负整数,其用原码表示为1000 0000 0000 0000 0000 0000 0000 0000,,最小负整数原码和补码表示一样。
~i:表示按位取反,为 0111 1111 1111 1111 1111 1111 1111 1111,符号位为0,表示正数,原码补码一样,2147483647
-i:对数值执行单目运算符-表示对该数按位取反(包括符号位)再+1,也就是求补运算。注意求补运算和求补码的不同,求补码是对数值位(不包括符号位)取反再+1,求补运算时按位取反(包括符号位)再+1。对i=1000 0000 0000 0000 0000 0000 0000 0000求补再+1还是得到1000 0000 0000 0000 0000 0000 0000 0000,也就是-2147483648。
1