C语言面试题中最主要就是考察指针的使用,而指针的确就是C语言的灵魂,指针非常好用,对于指针的使用,可以看出一个程序员的修养。
最常使用来考察指针使用熟练程度的就是memcpy和strcpy。
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ );
return address;
}
看,是不是很简单的代码,越是牛逼的代码就越短不是没有理由的。
这段代码其实是简化过了的,如果是要容易看懂的话,应该把简化的步骤都加上会比较好。
while( (*strDest++ = * strSrc++) != ‘\0’ );
就是while(*strSrc!=’\0’)
{
*strDest++ = * strSrc++;
}
然后就是memcpy
void *memcpy(void *dst, const void *src, size_t len)
{
if(NULL == dst || NULL == src){
return NULL;
}
char *d;
const char *s;
if(dst <= src || (char *)dst >= (char *)src + len){
//没有内存重叠,从低地址开始复制
d=(char *)dest;
s=(char *)src;
while(len--){
*d++=*s++;
}
}else{
//有内存重叠,从高地址开始复制
s = (char *)src + len - 1;
d = (char *)dst + len - 1;
while(len--){
*s--=*d--;
}
}
return dest;
}
需要注意的是(char*)强制转换,因为void指针类型是不能够自加的。另一种说法是不同类型的指针不能直接++赋值。
memcpy比较经典,我一步步来讲解。
void *memcpy(void *dst, const void *src, size_t len)
都是void型指针。
if(NULL == dst || NULL == src){
return NULL;
}
先判断dst和src是不是空的,如果是,就返回空。这是最基本也是最重要的编程思想,算无遗策的判断。
然后是另一个判断,就是内存是否重叠,最后就是开始复制。
复制的语句需要注意的比较多,首先就是强制类型转换,这个很有考究,然后就是一个字节一个字节的复制,这个用的什么方法和语句也是很有玄机的。这些细节就可以看出程序员的素养了。
*d++=*s++;
这个就是指针比较容易混淆的地方,比较容易出错。写成d++=s++;