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语言中 不能在中间声明变量 所有的变量必须在作用域的开始处声明。
在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));
printf("%u\n", a);
printf("%u\n", sizeof(void));
就算是用了int编译时候 warning都没有的。