c面试

试题1:请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1

解答:

 

int checkCPU()
{
    union w
    {
        int a;
        char b;
    }c;
    c.a = 1;
    return (c.b == 1);
}

剖析:

嵌入式系统开发者应该对Little-endianBig-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址

0x4000

0x4001

存放内容

0x34

0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址

0x4000

0x4001

存放内容

0x12

0x34

32bit宽的数0x12345678Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址

0x4000

0x4001

0x4002

0x4003

存放内容

0x78

0x56

0x34

0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址

0x4000

0x4001

0x4002

0x4003

存放内容

0x12

0x34

0x56

0x78

联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。

 

2.

char str[] = “Hello” ;

char *p = str ;

int n = 10;

请计算

sizeof (str ) = 6 (2分)

sizeof ( p ) = 4 (2分)

sizeof ( n ) = 4 (2分)

void Func ( char str[100])

{

请计算

sizeof( str ) = 4 (2分)

}

void *p = malloc( 100 );

请计算

sizeof ( p ) = 4 (2分)

 

3、在C++程序中调用被 C编译器编译后的函数,为什么要加 extern “C”? (5分)

答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);

该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。

C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。

4.有关内存的思考题

void GetMemory(char *p)

{

p = (char *)malloc(100);

}

void Test(void)

{

char *str = NULL;

GetMemory(str);

strcpy(str, "hello world");

printf(str);

}

请问运行Test函数会有什么样的结果?

答:程序崩溃。

因为GetMemory并不能传递动态内存,

Test函数中的 str一直都是 NULL。

strcpy(str, "hello world");将使程序崩溃。

char *GetMemory(void)

{

char p[] = "hello world";

return p;

}

void Test(void)

{

char *str = NULL;

str = GetMemory();

printf(str);

}

请问运行Test函数会有什么样的结果?

答:可能是乱码。

因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。

 

 

 

 

 

void GetMemory2(char **p, int num)

{

*p = (char *)malloc(num);

}

void Test(void)

{

char *str = NULL;

GetMemory(&str, 100);

strcpy(str, "hello");

printf(str);

}

请问运行Test函数会有什么样的结果?

答:

(1)能够输出hello

(2)内存泄漏

 

 

 

 

 

 

void Test(void)

{

char *str = (char *) malloc(100);

strcpy(str, “hello”);

free(str);

if(str != NULL)

{

strcpy(str, “world”);

printf(str);

}

}

请问运行Test函数会有什么样的结果?

答:篡改动态内存区的内容,后果难以预料,非常危险。

因为free(str);之后,str成为野指针,

if(str != NULL)语句不起作用

一、判断题

1、有数组定义int a[2][2]={{1},{2,3}};则a[0][1]的值为0。(正确)

2、int (*ptr) (),则ptr是一维数组的名字。(错误 int (*ptr) ();定义一个指向函数的指针变量 )

3、指针在任何情况下都可进行>,<,>=,<=,==运算。(错误)

4、switch(c) 语句中c可以是int ,long,char ,float ,unsigned int 类型。( 错,不能用实形)

 

二、填空题

1、在windows下,写出运行结果

char str[ ]= "Hello";
char *p=str;
int n=10;

sizeof(str)=( )
sizeof(p)=( )
sizeof(n)=( )
void func(char str[100]){    }
sizeof(str)=( )

答案:6,4,4,4

2、
设int arr[]={6,7,8,9,10};
  int *ptr=arr;
  *(ptr++)+=123;
  printf("%d,%d", *ptr, *(++ptr));

答案:8,8。这道题目的意义不大,因为在不同的编译器里printf的参数的方向是不一样的,在vc6.0下是从有到左,这里先*(++ptr) 后*pt,于是结果为8,8

二、编程题

1、不使用库函数,编写函数int strcmp(char *source, char *dest)

相等返回0,不等返回-1;

答案:一、

复制代码
int strcmp(char *source, char *dest)
{
    assert((source
!=NULL)&&(dest!=NULL));
    
int i,j;
    
for(i=0; source[i]==dest[i]; i++)
    {
   }

   
if(source[i]=='\0' && dest[i]=='\0')
       
return 0;
   
else
       
return -1;
   
}
复制代码

 

posted @ 2012-05-22 15:54  mugua250  阅读(609)  评论(2编辑  收藏  举报