嵌入式C语言面试题(二)
1.评价下面的代码
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
应该是:
unsigned int compzero = ~0;
2.求c=a+++b;
int a = 5, b = 7, c;
c = a+++b;
c = a+++b = 12;
c = a+++b被编译器理解为a+++b
3.求值
typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat; DATE cow; double dog;} too;
DATE max;
则语句 printf("%d",sizeof(struct data)+sizeof(max));的执行结果是? sizeof(struct date) 分析如下:DATE是一个union,long i可能是4 byte,也可能是8 byte,int k[5]=20 byte,char c1个字节,因此,如果long i是4 byte,则sizeof(DATE)=20.此时struct data的大小为:cat(4byte),cow(20byte),dog(8 byte)合计32个字节.So,总长度为52个字节;
如果long i是8个字节,则DATE是24个字节,则4,24,8=36,合计60个字节.
4.下出下面的输出
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
5.写出输出结果
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
*(a+1)=a[1],因此,第一个输出是int数据2.
ptr = (int*)(&a+1);首先,a是数组的首地址,那么&a+1到底是表示a的地址加1还是其他意思?
我们必须记住一点:指针加减的数字是以指针指向的数据类型为量度的,由于&a是指向a[5]这个整型数组首地址的地址,也就说&a的数据类型为数组指针(int (*)[5]).这个数组指针指向的数据类型是int a[5],长度为20个字节.因此,&a+1(ptr)表示数组首地址+20,int *ptr =&a+1. 因此,ptr-1其实就是指向数组a的第5个元素,也就是5.
6.请问以下代码有什么问题
int main()
{
char a='a';
char *str=&a;
strcpy(str,"hello");
printf(str);
char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);
return 0;
}
7.请问下列表达式哪些会被编译器禁止?为什么?
int a=248;
b=4;
int const c=21;
const int *d=&a;
int *const e=&b;
int const *f =&a;
*c=32;
d=&b;
*d=43;
e=34;
e=&a;
f=0x321f;
8.交换两个变量的值,不使用第三个变量
1.a = a^b;
a = a^b;
b = a^b;
2.a = a+b
b = a-b
a = a-b
9.下面的程序会出现什么结果?
#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world");
}
int main( )
{
char *str=NULL;
getmemory(str);
printf("%s/n",str);
free(str);
return 0;
}
10.分析以下代码的输出是什么?
int _tmain(int argc, _TCHAR* argv[])
{
unsigned short A=10;
printf("~A=%u\n",~A);
printf("~A=%d\n",~A);
printf("~A=%x\n",~A);
char c=128;
printf("c=%d\n",c);
return 0;
}
第一个,将A作为%u,无符号整数,A=0x0A,则~A = 0xFF FF FF F5 ,则其值为2的32次方-11. 第二个,将A作为有符号整数,~A=0xFF FF FF F5,为负数,由于负数在计算机中用补码表示,其补码为0x0B=-11. 第三个,将A作为16进制数,~A = 0xFF FF FF F5, 故其值就是0xFFFFFFF5. 第四个,c=128=0b 1000 0000,如果解析为有符号整数,则输出为负数,其补码=-128.so 输出为-128.
11.绝对地址0x100000赋值且想让程序跳转到绝对地址是0x100000去执行,如何写代码?
void (* p)() =(unsigned int*)0x100000;
p();
12.求下面结构的sizeof(A)大小.
struct A
{
char t::4;
char k:4;
unsigned short i:8;
unsigned long m;
};
分析:假定编译器设置的对齐参数为#pragma pack(4);(4字节对齐),则: 若为32位OS, t,k共占据1个字节,unsigned short 2 byte,unsigned long m 4 byte,则对齐单位为4 byte,故t和k占据1个字节,i偏移量从2开始,占据2个字节,m偏移量从4开始,占据4个字节,合计8个字节. 若为64位OS, t,k共占据1个字节,unsigned short 2 byte, unsigned long m 8个字节,则对齐单位为4 byte,故t和k占据1个字节,i偏移量从2开始,长度为2,m偏移量从4开始,长度为8,共计12个字节.
13.给出下面程序的答案.
typedef struct AA
{
int b1:5;
int b2:2;
}AA;
void main()
{
AA aa;
char cc[100];
strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
memcpy(&aa,cc,sizeof(AA));
cout << aa.b1 <<endl;
cout << aa.b2 <<endl;
}
//sizeof(AA)=4;拷贝4个字符“0123”其16进制内容为0x30,0x31,0x32,0x33即:00110000 00110001 00110010 00110011. //b1和b2占据了这四个字节的前面字节的7位,即b1:0b10000,b2=0b01;int是有符号整数,b1=-16,b2=1
14.给出下面程序的输出.
struct bit
{
int a:3;
int b:2;
int c:3;
};
int main()
{
bit s;
char *c=(char*)&s;
cout<<sizeof(bit)<<endl;
*c=0x99;
cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
int a=-1;
printf("%x",a);
return 0;
}
分析: sizeof(struct bit)=4. *c = 0x99= 0b1001 1001,a是前3位,故a是001,b是11,c是100,由于均为int型,故s.a=1,s.b=-1,s.c=-4 a=-1, 1的原码是-0x00000001,-1的补码是0xFFFFFFFF.故a打印出来0xFFFFFFFF.
15.求以下几个结构的长度
struct name1{
char str;
short x;
int num;
}
struct name2{
char str;
int num;
short x;
}
假设编译器对齐参数设置为# pragma pack(4),则: struct name1: 此结构中长度最大的值为num(4),两者之间的较小值为4,第一个char str从0开始,第二个short的偏移量为其长度与4的较小值,故为2,第三个int num 长度为4,故其偏移量为4,因此,合计长度为8. struct name2: 首先,其单位对齐长度为num的长度与pack(4)两者的最小值(4). char str 1个字节,占据1个字节,num 占据4个字节,偏移量为4的倍数,故从4开始,占据4-7四个 byte,short x是两个字节,故偏移量为2的倍数,偏移量为8,占据2个字节,但总长度应该是4的整数倍,故最终的占据长度为4+4+4=12.
从上面可以看出,为了节约空间,数据类型占据字节长的结构成员,应该放在结构的后面.
struct s1
{
int i: 8;
int j: 4;
int a: 3;
double b;
};
struct s2
{
int i: 8;
int j: 4;
double b;
int a:3;
};
假设为#pragma pack(4),则: struct s1: i,j,a均为int型,合计占据15个字节,由于单位对齐长度为4,故这三个bit位共占据2个字节,double b始终占据8 byte,则其偏移量为4的倍数,本身占据8个字节,故struct s1的长度为12.
struct s2: i,j,为int型,共占据2个字节;double b占据8个字节,故为4-11 8个字节,int a:3占据4个字节,故合计为4+8+4=16个字节.(关于结构体长度的判断,请参见笔者在csdn的相关其他文章)
16.填空
struct BBB
{
long num;
char *name;
short int data;
char ha;
short ba[5];
}*p;
p=0x1000000;
p+0x200=____;
(unsigned long*)p+0x200=____;
(char*)p+0x200=____;
分析如下:
struct BBB
{
long num;
char *name;
short int data;
char ha;
short ba[5]; 12+10(12)
}*p;
p=0x1000000;
p+0x200=____;
(unsigned long*)p+0x200=____;
(char*)p+0x200=____;
由于long在32位OS和64位OS下面有不同的长度,故分开讨论: 假设为32位OS:根据笔者C语言结构体所占空间分析(https://blog.csdn.net/cdma_zte_c/article/details/119943850)可知,struct BBB占据22个字节,但应该为4的倍数,故占据空间为24 Byte. 所以p+0x200 = p+0x20024 = p + 0x2000x18 (unsigned long*)p+0x200= p + 0x200sizeof(unsigned long)=p+ 0x200 * 4 (char)p + 0x200 = p + 0x200*sizeof(char)=p+0x200
假设为64位OS,则分析如下: struct BBB { //单位对齐长度为4 long num;//8个字节 0+8(offset+占据字节,下同) char *name;//8个字节 8+8 short int data;//2个字节 16+2 char ha;//1个字节 18+2 short ba[5]; 20+10(12) }*p; 故合计占据长度为32 byte. 则后面就好计算了.
17.写出程序输出结果
void g(int**);
int main()
{
int line[10],i;
int *p=line;
for (i=0;i<10;i++)
{
*p=i;
g(&p);
}
for(i=0;i<10;i++)
printf("%d\n",line[i]);
return 0;
}
void g(int**p)
{
(**p)++;
(*p)++;
}
分析情况参见源码部分.
18.写出程序输出结果
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(“ %d %d ”, *ptr, *(++ptr));
typedef struct
{
int a:2;
int b:2;
int c:1;
}test;
test t;
t.a = 1;
t.b = 3;
t.c = 1;
printf("%d",t.a);
printf("%d",t.b);
printf("%d",t.c);
解答参见原文代码.
|