• 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;           //尾部要加’’

    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 ",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。

  • 相关阅读:
    Python安装
    Python的种类
    Windows server 下 DNS服务器 实现递归查询和循环查询的配置方法
    Command Injection_low、Medium、high、Impossible
    Brute Force_impossible
    Brute Force_high
    Brute Force_medium
    Brute Force_low
    脚本黑客1----HTML基础笔记
    windows服务器大量端口被dns.exe占用的解决方法
  • 原文地址:https://www.cnblogs.com/try-again/p/4302460.html
Copyright © 2020-2023  润新知