曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 8184|回复: 13
打印 上一主题 下一主题

常见 C 语言面试题目

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2009-6-9 16:24:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
试题一:请解释关键字 static,并说明至少两种 static 的用途

解答
静态变量( 以 static 作为修饰符的变量 ) 分为两种:全局静态变量和局部静态变量。全局静态变量是在所有函数之外定义的静态变量,局部静态变量是在某个函数内( 如 main 函数 )定义的变量。

静态变量存储在内存的静态存储区,静态存储区在程序的整个运行期间都存在。未经初始化的静态变量会被程序自动初始化为 0 ( 自动对象的值是任意的,除非被显式初始化 )。

全局静态变量的作用域是从定义之处开始到文件结尾,全局静态变量对其它文件是不可见的。而局部静态变量只是在定义它的函数内有效。

static 的用途为

(1)限制变量的作用域
(2)设置变量的的存储域

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2009-6-9 17:06:20 | 只看该作者
例题二:请分析程序是否正确,如果错误指出原因,如果正确写出程序运行结果并说明原因
#include <stdio.h>

int a = 3;

void f()
{
    int a = 1, i;
    printf("%d\\n",a);

    for(i=0; i<1; i++)
    {
        int a = 2;
        printf("%d\\n", a);
    }

}

int main()
{
    f();
    printf("%d\\n",a);
}
说明
程序正确。这里注意一点的是,在 f() 函数里边的 a 是局部变量,在 main() 之外的是全局变量。局部变量和全局变量同名无所谓,各自输出各自的值。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
板凳
 楼主| 发表于 2009-6-9 18:04:41 | 只看该作者
例题三:static 全局变量与普通的全局变量有什么区别? static 局部变量和普通局部变量有什么区别?static 函数与普通函数有什么区别

解答
在定义变量时,全局变量之前再冠以 static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。两者在存储方式上并无不同。两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的 函数使用,因此可以避免其他源文件使用该变量。把普通的全局变量改变为静态全局变量是改变了它的作用域,限制了它的使用范围。

普通全局变量所在的函数每次被调用都会被重新等一并分配存储空间,而 static 局部变量不会,它的值始终保存着。static 局部变量只被初始化一次,下一次使用时依旧是上次的值。

static 函数( 即静态函数,在函数定义时加上了 static 关键字 )与普通函数作用域不同,它仅存在于本文件中。只在当前源文件中使用的函数应该说明为内部函数( 即加上 static 关键字 )。内部函数应该在当前源文件中声明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这个函数的源文件要包含这个头文件。

程序的普通局部变量存在于堆栈中,全局变量、static 局部变量存在于静态存储区中。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
地板
 楼主| 发表于 2009-6-9 19:02:39 | 只看该作者
例题四:写出下面程序的运行结果
#include <stdio.h>

int inc(int a)
{
    return (++a);
}

int multi(int *a, int *b, int *c)
{
    return ( *c = *a * *b );
}

int (*p)(int);

void show( int(*fun)(int*, int*, int*), int arg1, int *arg2)
{
    p = inc;
    int temp = p(arg1);
    fun(&temp, &arg1, arg2);
    printf("%d\\n", *arg2);
}

int main()
{
    int a;
    show(multi, 10, &a);
    return 0;
}
      
说明
首先,函数输出结果为 110 。
这里,有一点,  p = inc; 这个语句和 p = &inc;的一样的意思。这里主要考察的是函数指针的用法。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
5#
 楼主| 发表于 2009-6-10 00:40:00 | 只看该作者
例题五:清找出下面代码的所有错误。这段代码的功能是把一个字符串到序,如 "abcd" 倒叙后变为 "dcba" 。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int 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\\n",dest);
   
    free(dest);
   
    return 0;
}
分析
上面程序中有几处错误:
1、dest = (char *)malloc(len); 这一句应写成 dest = (char *)malloc(len + 1);这个函数的本意是向系统申请一块内存以便存储 "hello, world"这个字符串的倒序。strlen()这个函数返回的是字符串的实际大小,即不包括每个字符串最后都有的结束字符 '\\0' 。使用 malloc 申请内存时必须申请 len + 1 个字节以便存放整个字符串。

2、char *s = &src[len];这个语句使用不恰当。注意数组的元素的个数与下标的关系。这里 len下标实际上是指向了 '\\0',所以要改为 char *s = &src[len - 1];

3、在 *d++ = *s-- 后面还要加上一句 *d = '\\0' 以把 '\\0' 复制过去。这句语句等效于
*d = *s;
d++;
s--;

4、printf() 函数后要增加一个语句 free(dest),使用完 malloc() 分配内存后要使用 free() 函数将其释放,否则可能造成内存泄露。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
6#
 楼主| 发表于 2009-6-10 15:52:06 | 只看该作者
例题六:请写出下面程序的运行结果
[font=[object htmloptionelement]]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void fun(char str[100])
{
    printf("%d\
", sizeof(str));
}
int main()
{
    char str[] = "Hello";
    char *p1 = str;
    int n = 10;
    char *p2 = (char *)malloc(100);
    printf("%d\
", sizeof(str)); /*求数组长度,包括'\\0'*/
    printf("%d\
", strlen(str)); /*求字符串长度,不包括'\\0'*/
    printf("%d\
", sizeof(p1));  /*求char型指针长度*/
    printf("%d\
", strlen(p1));  /*求字符串长度,不包括'\\0'*/
    printf("%d\
", sizeof(n));   /*求 n 这个整型变量的长度*/
    printf("%d\
", sizeof(p2));  /*求 p2 指针类型长度*/
    fun(p2);
    return 0;
}
运行及输出
beyes@linux-beyes:~/C> ./sizeof_and_strlen.exe
6
5
4
5
4
4
4
说明
此种题在招聘 C 语言软件开发工程师时很常见。主要测试对 sizeof() 和 strlen() 的理解。
第一个输出为 6,测的是 str 这个数组的长度,包括末尾的 '\\0'.
第二个输出为 5,测的是字符串自身,不包括结尾的 '\\0'.
第三个输出为 4,由于 p1 是一个指针,sizeof() 求的是变量类型的长度。一个指针变量存放的是一个地址,而 32 位机器的一个地址都是 32 位即 4 个字节。
第四个输出为 5,测的是 p1 指向的字符串的长度,和第二个一样。
第五个输出为 4,一个整型变量的存储长度一般一般是 4 个字节,早期的机器使用 2 个字节来保存 int 型变量。
第六个输出为 4, 这里同样求的是指针变量 p2 的长度,和第三个输出一样。
第七个输出为 4,这里调用了 fun 函数。因为数组作为函数的参数时,对系统来说,char str[100] 和 char *str 是一样的。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
7#
 楼主| 发表于 2009-6-10 16:03:02 | 只看该作者
例题七:下面的这段小程序有什么问题?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char a;
    char *str = &a;
   
    strcpy(str, "hello");
    printf("%s\\n", str);
   
    return 0;
}
说明
这个程序虽然可以编译通过,但运行时会导致程序崩溃,提示 ”段错误“ 。这里,str 指向的变量只有 1 个字节,而复制的字符串 "hello" 需要 6 个字节的空间。应该在 strcpy  函数调用前先分配动态内存并赋给指针 str :
str = (char *) malloc( strlen("hello") + 1 );
在函数返回之前,释放申请的动态内存:
free(str);

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
8#
 楼主| 发表于 2009-6-10 16:13:14 | 只看该作者
例题八: int( *s[10] )(int) 表示的是什么?

首先,[ ] 符号的优先级比 * 号的高,所以 *s[] 表示的是一个指针数组。而 int (*)(int) 表示的是一个指向参数为 int 类型并且返回值也同为 int 类型的函数指针。
所以,整个语句的含义是:定义了一个含有 10 个函数指针的数组。数组的长度为 10,数组元素的类型是指向函数的指针。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
9#
 楼主| 发表于 2009-6-10 16:24:15 | 只看该作者
例题九:假设只知道一个数组名,如何确定这个数组的长度

假定这个数组的数组名是 array,可以用一下语句确定一个数组的长度:

 int length = sizeof( array ) / sizeof( array[0] );

sizeof( array ) 是数组的总长度,而 sizeof( array[0] ) 是数组的第一个元素的长度。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
10#
 楼主| 发表于 2009-6-10 17:43:50 | 只看该作者
例题十:“ char a[10]; int len = strlen(a); ”,len 等于多少?

上面这两条语句虽然语法上是合法的,但这种用法是错误的。
strlen 从数组 a 首地址出发一直到遇到 '\\0' 才结束,计算从数组 a 的第一个元素开始到 '\\0' 总共有多少个字符(不包括字符 '\\0')。由于字符数组没有初始化,数组元素的值是未知的,所以 len 的值也是未定的。

如果对数组进行初始化:
char a[10] = "hello";
int len = strlen(a);
则 len 的值是确定的,为 5 。此时 sizeof(a) 的值为 10,它获取的是数组 a 的总长度。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-5-13 20:36 , Processed in 0.075666 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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