曲径通幽论坛

 找回密码
 立即注册
搜索
12
返回列表 发新帖
楼主: beyes
打印 上一主题 下一主题

常见 C 语言面试题目

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
11#
 楼主| 发表于 2009-6-10 18:50:01 | 只看该作者
例题十一:下面的程序编译时会报错,请指出错误并改正
#include <stdio.h>

int main(void)
{
    int **p;
    int array[ 100 ];
   
    p = &array;
   
    return 0;
}
gcc 编译提示
beyes@linux-beyes:~/C> gcc -c temp.c
temp.c: In function ‘main’:
temp.c:8: warning: assignment from incompatible pointer type
由报告信息可知,这是指针类型不兼容的警告。
两个指针只有在指向的数据的类型一致时才可以互相赋值。

&array 是一个指向长度为 100 的数组的指针,而  p 是一个指向 “整型指针” 的指针,所以两者不匹配。主函数可以修正如下:
#include <stdio.h>

int main(void)
{
    int **p, *q;
    int array[ 100 ];
   
    q = array;

    p = &q;
   
    return 0;
}
这里,用指针 q 进行了过渡。array 是数组首地址,而数组中的内容又是整型数,那么当然可以把这个数组首地址赋给整型指针 q 。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
12#
 楼主| 发表于 2009-6-10 21:29:07 | 只看该作者
例题十二:写一个程序,以递归方式反序输出一个字符串。如给定字符串 "abc" 输出 "cba".

测试程序
 #include <stdio.h>
#include <string.h>
void reverse(char *p)
{
    if(*p == '\\0' )
        return;
       
    reverse(p + 1);
   
    printf("%c", *p);
}
int main()
{
    char str[100];
    int len;
    char *p;
    printf("请输入字符串:");
    fgets(str, 100, stdin);
    len = strlen(str);
    if(str[len - 1] == '\
'
)
        str[len-1] = '\\0';
    p = str;
    reverse(p);
    printf("\
");
    return 0;
}
      
说明
程序中,之所以用 fgets() 而不用 gets() 是因为前者是个安全的函数,而后者因为不检查边界,所以很危险,不使用。
    if(str[len - 1] == '\\n')
        str[len-1] = '\\0';
上面两行语句是因为用 fgets() 会读取进一个回车符 '\\n',这里将其吃掉。
      

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
13#
 楼主| 发表于 2009-6-10 22:59:17 | 只看该作者
例题十三:下面这个程序是否有问题?
#include <stdio.h>
#define MAX 255

int main()
{
    unsigned char a[MAX], i;
   
   for(i=0; i<=MAX; i++)
              printf("%d ", a[i]);

   printf("\\n");
   return 0;
}
程序分析
使用 gcc 编译,可以编译通过。但如果运行程序会导致数组越界死循环。这个看似简单的程序,实则“暗藏杀机”。程序里存在两个问题:
1、数组越界
上面的 i<=MAX 应该写成 i<MAX

2、死循环
这点比较隐蔽。注意到,a 和 i 变量也是无符号字符型,这种类型的数据占据一个字节内存即 8 位,所表示的数组的范围 ( 以二进制表示):00000000~11111111,也就是 0 ~255。
数组 a 的元素范围为 a[0] 到 a[254] 。当 i = 255 时,这是可以的,因为数组并不检查对数组元素的访问是否越界。然而,当 i 执行 i++ 操作时,i 的值班不会变成 256,而是变为 0 了!这是因为无符号字符型的存储空间只有 8 位的缘故: 11111111 + 1 = 100000000,最高位 1 舍去。所以,在执行判断语句 i<=MAX 时,条件又成立了, i 又从 0 开始循环。如此周而复始,导致死循环。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
14#
 楼主| 发表于 2009-6-11 16:13:43 | 只看该作者
例题十四
写一个实现字符串拷贝的函数。给定字符串拷贝函数 strcpy 的原型:
char *strcpy(char *dest, char *src)

程序如下
char *strcpy(char *dest, char *src)
{
    char *ret_string;
   
    if ( ( dest == NULL ) || ( src == NULL ) )   {
         printf("arg wrong");
         return NULL;
    }
    ret_string = dest;
    while( ( *dest++  =  *src++) ) != '\\0' );
    return ret_string;
}
说明
(1) 一开始如果不检查指针 dest 和 src 是否为 NULL ,那说明不注重代码的健壮性。

(2) 检查指针是否有效时,使用 if ( ( !dest) || (!src) ) 或者 if ( ( dest == 0 ) || ( src == 0 ) ) ,则表现为书写代码不规范,说明答题者不知道使用 NULL 常量的好处,因为使用 0 而没有用 NULL ,会降低程序的可维护性。

(3) 字符拷贝时,不要忘记了拷贝最后的 '\\0'。上面程序中 while 语句是最精简的写法,但为了提高程序的可读性和可维护性,最好还是尽量写得容易让别人看懂:
while ( *src != '\\0' )
{
    *dest = *src;
     dest++;
     src++;
}
*dest = '\\0'
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-13 10:00 , Processed in 0.082457 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表