c语言面试题(感觉比较好的题目)

 

1、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?

答:static全局变量--只在定义了该变量的源文件内有效,初始化一次,防止在其他文件单元中被引用。

    普通全局变量----在各个源文件中都是有效的。

    相同之处都是静态存储方式。

    static局部变量--作用在整个生命周期内,初始化一次,下一次依据上一次的结果。

    普通局部变量----作用在当前函数内,生命周期只在函数内,用完就结束。

    static函数--作用在本文件中,即为内部函数。

    普通函数----可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件,要包含这个头文件。

    static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

 

2、写出下列代码的输出内容

#include <stdio.h>

int inc(int a)

{ return(++a); }

int multi(int*a,int*b,int*c)

{   return(*c=*a**b); }

typedef int(FUNC1)(int in);

typedef int(FUNC2) (int*,int*,int*);

void show(FUNC2 fun,int arg1, int*arg2)

{

FUNC1 p=&inc;

int temp =p(arg1);

fun(&temp,&arg1, arg2);

printf("%dn",*arg2);

}

main()

{

int a;          //局部变量a为0;

show(multi,10,&a);

return 0;

}

答:110

3、请找出下面代码中的所有错误 (题目不错,值得一看)

说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”

#include"string.h"

main()

{

char*src="hello,world";

char* dest=NULL;

int len=strlen(src);

dest=(char*)malloc(len);

char* d=dest;

char* s=&src[len-1];

while(len--!=0)

*d++=*s--;

printf("%s",dest);

free(dest);

dest=NULL;

return 0;

}

答:

方法1:一共有4个错误;

int main()

{

char* src = "hello,world";

int len = strlen(src);

char* dest = (char*)malloc(len+1);//要为分配一个空间   

char* d = dest;

char* s = &src[len-1];          //指向最后一个字符

while( len-- != 0 )

*d++=*s--;

*d = 0;           //尾部要加’\0’

printf("%sn",dest);

free(dest);        // 使用完,应当释放空间,以免造成内存汇泄露

dest = NULL;   //防止产生野指针

return 0;

}

方法2: (方法一需要额外的存储空间,效率不高.) 不错的想法

#include <stdio.h>

#include <string.h>

main()

{

char str[]="hello,world";

int len=strlen(str);

char t;

for(int i=0; i<len/2; i++)

{

t=str;

str=str[len-i-1]; //小心一点

str[len-i-1]=t;

}

printf("%s",str);

return 0;

}

4、软件测试都有那些种类?

黑盒:针对系统功能的测试

白盒:测试函数功能,各函数接口。

5、测试方法

答:人工测试:个人复查、抽查和会审

机器测试:黑盒测试和白盒测试

6、unsigned char *p1;

unsigned long *p2;

p1=(unsigned char *)0x801000;

p2=(unsigned long *)0x810000;

请问p1+5=  ;

p2+5=  ;

答案:0x801005(相当于加上5位) 0x810014(相当于加上20位);

7、Windows消息调度机制是C

A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;

8、TCP/IP通信建立的过程怎样,端口有什么作用?

三次握手,确定是哪个应用程序使用该协议

9、#define Max_CB 500

void LmiQueryCSmd(Struct MSgCB * pmsg)

{

unsigned char ucCmdNum;

......

for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)

{

......;

}

答: 死循环,unsigned char的取值范围是0~255

10、

以下是求一个数的平方的程序,请找出错误:

#define SQUARE(a)((a)*(a))

int a=5;

int b;

b=SQUARE(a++);

答:结果与编译器相关,得到的可能不是平方值.(我在电脑上面显示的是25,为36位编辑器)

11、进程和线程的差别。

答:线程是指进程内的一个执行单元,也是进程内的可调度实体.

与进程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

12、Heap与stack的差别。

答:Heap是堆,stack是栈。

Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。

Stack空间有限,Heap是很大的自由存储区

C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。

程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行

 

13、下述三个有什么区别?

char * const p;

char const * p

const char *p

解答:

char * const p; //常量指针,p的值不可以修改

char const * p;//指向常量的指针,指向的常量值不可以改

const char *p; //和char const *p

14、 解释下列输出结果

char str1[] = "abc";

char str2[] = "abc";

const char str3[] = "abc";

const char str4[] = "abc";

const char *str5 = "abc";

const char *str6 = "abc";

char *str7 = "abc";

char *str8 = "abc";

cout << ( str1 == str2 ) << endl;

cout << ( str3 == str4 ) << endl;

cout << ( str5 == str6 ) << endl;

cout << ( str7 == str8 ) << endl;

结果是:0 0 1 1

解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;

而str5,str6,str7,str8是指针,它们指向相同的常量区域。

15、指出下面代码的输出,并解释为什么。(不错,对地址掌握的深入挖潜)

main()

{

int a[5]={1,2,3,4,5};

int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1));

}

输出:2,5

*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5

&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)

int *ptr=(int *)(&a+1);

则ptr实际是&(a[5]),也就是a+5

原因如下:

&a是数组指针,其类型为 int (*)[5];

而指针加1要根据指针类型加上一定的值,

不同类型的指针+1之后增加的大小不同

a是长度为5的int数组指针,所以要加 5*sizeof(int)

所以ptr实际是a[5]

但是prt与(&a+1)类型是不一样的(这点很重要)

所以prt-1只会减去sizeof(int*)

a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].

16、

char* s="AAA";

printf("%s",s);

s[0]='B';

printf("%s",s);

有什么错?

答: "AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。

cosnt char* s="AAA";

然后又因为是常量,所以对是s[0]的赋值操作是不合法的。

17、

int main()

{

char a;

char *str=&a;

strcpy(str,"hello");

printf(str);

return 0;

}

答;没有为str分配内存空间,将会发生异常

问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

Strcpy的在库函数string.h中.程序的主要错误在于越界进行内存读写导致程序崩溃//

18、

关键字static的作用是什么?

答:1)定义静态局部变量,作用域从函数开始到结束.

2) 在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

3) 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝

19、

关键字const有什么含意?

答 :1)表示常量不可以修改的变量。

2)可以修饰参数,作为输入参数.

3)修饰函数,防止以外的改动.

4)修饰类的成员函数,不改变类中的数据成员.

20、

c和c++中的struct有什么不同?

答:

c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private.

 

21、在c语言库函数中将一个字符转换成整型的函数是atool()吗,这个函数的原型是什么?

  函数名: atol

  功 能: 把字符串转换成长整型数

  用 法: long atol(const char *nptr);

#include <stdio.h>

int main()

{

    long l;

    char *str="123456789";

    l = atol(str);

    printf("str=%s,l=%d\n",str,l);

    return 0;

}

 

22、下面4个例子中存在哪些问题,请一一指出:

(1)、

void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( str );
 strcpy( str, "hello world" );
 printf( str );
}
(2)、
char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}

void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}
(3)、
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}
(4)、
void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它语句
}

(1)、GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char *str = NULL;GetMemory( str );后的str仍然为NULL;
(2)、char p[] = "hello world"; return p;的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
(3)、GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句*p = (char *) malloc( num );后未判断内存是否申请成功,应加上:

if ( *p == NULL )
{
 ...//进行申请内存失败处理
}

(4)、试题4存在与试题3同样的问题,在执行char *str = (char *) malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = NULL;试题3的Test函数中也未对malloc的内存进行释放。

23、再看看下面的一段程序有什么错误:
swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}
  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:
swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}
24、以下为Windows NT下的32位C++程序,请计算sizeof的值
void Func ( char str[100] )
{
 sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
解答:
sizeof( str ) = 4
sizeof ( p ) = 4
剖析:
Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。
数组名的本质如下:
1)数组名指代一种数据结构,这种数据结构就是数组;例如:

char str[10];cout << sizeof(str) << endl;输出结果为10,str指代数据结构char[10]。
2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;char str[10]; str++; //编译出错,提示str不是左值 
3)数组名作为函数形参时,沦为普通指针。Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。

posted @ 2015-02-27 00:11  天王星B  Views(529)  Comments(0Edit  收藏  举报