C语言一些面试题-1

1.请阅读下面的程序,理解程序的意图并找出程序中的错误改正。

main()
{    
    char*src="hello,world";   
    char* dest=NULL;       
    int len=strlen(src);    
    dest=(char*)malloc(len);
    char* d = dest;    
    char* s = src[len];

    while( len-- != 0 )   
        d++=s--;
   
 
    printf("%s",dest);   

    return 0;   
}  


我改了一个版本 大家看看有哪些改动

main()
{    
    char* src = "hello,world";   
    char* dest = NULL;       
    int len = strlen(src);    
    
    char* d = NULL;
    char* s = NULL;

    dest = (char*)malloc(len + 1); 
    d = dest;
    s = src + len - 1;

    while( len-- != 0 )   
        *d++ = *s--;
   
    *d = '\0';
 
    printf("%s",dest);   

    free(dest);

    return 0;   
在这里大家要注意一个很隐蔽的问题

在C语言中 不能在中间声明变量 所有的变量必须在作用域的开始处声明。

2.觉得刚才那个同学提的问题很有意思,我们一起来实现一下。
题目如下:
在32位机器上,用你觉得最高效的方法实现 memcpy 函数。

void* memcpy(void* dest, void* src, unsigned int size);

好了 这个问题 我给同学们说几点 下来大家自己写一下 我会在后面把我的答案贴出来

作为一个面试官,我觉得这个问题会考察应试这 这几个方面的知识点

(1) 函数的链式调用。大家要注意返回值是void*, 那么这个void*是什么呢?其实就是要返回参数的dest,当然这个dest是已经复制好了的内存

(2) 考虑内存重叠的情况。软件中的多数难搞的bug一般都是这些考虑不足的函数造成的,因为假设不重叠时没问题,重叠时就出错,如何出错法,没人能预料。那么我们使用memcpy时, 不会每次考虑是否重叠的问题,所以这个是函数在实现时要考虑的。

(3)题目明确说明32位机上的高效。那么我们就要考虑总线周期的问题。虽然是C语言的程序,但是编译后还是汇编,还是二进制。在32位机器上,int的效率是最高的,因为每个周期读取数据的时候总是32位,所以你要拷贝一个字节,那么其实还是读取了4个字节,只不过机器会去处理而已。因此我们可以每次拷贝4个字节,这样效率就提高了4倍。但是同时问题又有了,size可能不是4的整数倍,比方对于13,那么就会遗留1个字节出来,这个时候我们必须单独处理,还是读取4个字节,通过位运算符得到我们要拷贝的有效字节。

3.下面程序输出什么?
int main()  
{  
    int i = 43;  
    int n = printf("%d\n",i);
    printf("%d\n",n);     
    return 0;
}

在linux 中一切东东都是文件 外设也是文件 也就是说显示器也是文件 那么printf的实现其实就是调用显示器的驱动程序往这种外设写入数据  所以我们来考虑一下  显示器属于什么设备呢 字符型设备 所以printf返回的其实不应该是输出的字符个数 准确的说应该是 向字符设备写入的数据的字节数  因为char就占用一个字节 所以碰巧 “printf返回输出字符的个数” 这个说法正确了
 


4.最后一个也是内涵题 大家看看

#include <stdio.h> 
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) 
int array[] = {23,34,12,17,204,99,16}; 
int main() 
{
    int d;
    for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
        printf("%d\n",array[d+1]);
    return 0; 



我来说这两个内涵

第一个:#define中 用到了array, 但是array在后面才定义的,合法吗?为什么?
其实合法的,在编译之前是预编译,预编译会处理#define之流的东东,在编译时这个define就没了。(详见我的c语言深度剖析相关章节)

第二个:程序输出什么?
程序不会输出任何东西。因为int和unsigned int比较时会被转换为无符号的,因此-1就直接被看成0xFFFFFFFF了,这样d不可能小于条件中的表达式。自然for不会执行。注意一点sizeof是编译的工具,它的计算结果是无符号的。
经过此次经验以后用到sizeof就用无符号来打印,省得出错。
        unsigned int a = sizeof(void);
        printf("%u\n", a);
        printf("%u\n", sizeof(void));

就算是用了int编译时候 warning都没有的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值