美文网首页
C语言面试题

C语言面试题

作者: 川少叶 | 来源:发表于2018-04-17 22:44 被阅读37次

    0 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

     #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
    

    我在这想看到几件事情:

    1. define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
      2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
    2. 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
    3. 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

    1 如何避免头文件被重复包含

    为避免头文件my_head.h被重复包含,可在其中使用条件编译:

    #ifndef _MY_HEAD_H
    
    #define _MY_HEAD_H    /*空宏*/
    
    int a;
    
    #endif
    

    2 static的作用

    1 声明静态局部变量
    在函数内定义的静态局部变量,该变量存在内存的静态区,所以即使该函数运行结束,静态变量的值不会被销毁,函数下次运行时能仍用到这个值。

    void test1()
    {
        static int a = 1;
        a++;
    }
    

    2 声明静态全局变量
    该变量的作用域只能在定义该变量的文件中,不能被其他文件通过extern引用。

    static int a = 1;
    void test2()
    {
        a++;
    }
    

    3 声明静态外部函数
    在C语言中我们的函数默认都是全局的,也就是说你可以调用其他文件中的函数。在使用的时候,我们象前面一样在头文件中加上extern就可以了。但是有时候我们写的函数并不想让别的文件访问和调用,那么我们在声明函数的时候前面加上static就可以了。

    static void test2()
    {
      printf("Hello world");    
    }
    

    3 const关键字的作用?

    1 声明常变量,使得指定的变量不能被修改

    const int a = 5;/*a的值一直为5,不能被改变*/
    const int b; b = 10;/*b的值被赋值为10后,不能被改变*/
    const int *ptr; /*ptr为指向整型常量的指针,ptr的值可以修改,但不能修改其所指向的值*/
    int *const ptr;/*ptr为指向整型的常量指针,ptr的值不能修改,但可以修改其所指向的值*/
    const int *const ptr;/*ptr为指向整型常量的常量指针,ptr及其指向的值都不能修改*/
    

    2修饰函数形参,使得形参在函数内不能被修改,表示输入参数

    如int fun(const int a);或int fun(const char *str);
    

    3 修饰函数返回值,使得函数的返回值不能被修改

    const char *getstr(void);使用:const *str= getstr();
    const int getint(void);  使用:const int a =getint();
    

    4 extern关键字的作用

    1 用于修饰变量或函数,表明该变量或函数都是在别的文件中定义的,提示编译器在其他文件中寻找定义。

    extern int a;
    extern int *p;
    extern int array[];
    extern void fun(void);
    

    5 sizeof关键字的作用?

    sizeof是在编译阶段处理,且不能被编译为机器码。sizeof的结果等于对象或类型所占的内存字节数。sizeof的返回值类型为size_t。

    变量:int a;  sizeof(a)为4;
    
    指针:int *p;  sizeof(p)为4;
    
    数组:int b[10]; sizeof(b)为数组的大小,4*10;int c[0]; sizeof(c)等于0
    

    6 假设你只知道一个数组的数组名(a[]),如何确定这个数组的长度?

    int a[10]; //a的大小是4*10
    int length = sizeof(a)/sizeof(a[0]);
    

    7 用变量a给出下面的定义

    a) 一个整型数(An integer)
    b)一个指向整型数的指针( A pointer to an integer)
    c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
    d)一个有10个整型数的数组( An array of 10 integers)
    e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
    f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
    g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
    h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
    答案是:

    a) int a; // An integer 
    b) int *a; // A pointer to an integer 
    c) int **a; // A pointer to a pointer to an integer 
    d) int a[10]; // An array of 10 integers 
    e) int *a[10]; // An array of 10 pointers to integers 
    f) int (*a)[10]; // A pointer to an array of 10 integers 
    g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer 
    h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer 
    

    指针和const

    指针和const.png
    常常声明的时候会让人一头雾水,比如下面的声明,均是声明一个int* p的指针:
    int * const p;    // 指针不可改,也就说指针只能指向一个地址,不能更改为其他地址
    int const * p;   // 所指内容不可改,也就是说*p是常量字符串
    int const * const p; // 内容和指针都不能改
    const int * const p; // 同上...内容和指针不能改
    

    指针和数组,函数

    1 区别int (*p)[5]和int *p[5]。
     前者是一个指针,它指向一个含有5个元素的数组。后者是一个数组,它的长度为5,数组中每一个元素指向一个整型变量。
    
    2.区别int *f( int i, int j)和 int (*p)( int i ,int j)
    前者是返回指针的函数,它是一个函数的声明,后者是指向函数的指针,它定义了一个指针。
    即前者是函数,后者为指针。
    注:不能对指向函数的指针做任何运算,如p++、p–、p+n、p-n都是错误的。
    

    8 malloc/free与new/delete的区别

    1. malloc与free是C/C++语言的标准库函数,可用于申请动态内存和释放内存。
    char *p1 = (char*)malloc(10);
    free(p1);
    
    1. new/delete是C++的运算符,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
      我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。

    2. 既然new/delete的功能完全覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
      如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,结果也会导致程序出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。

    参考文章

    https://blog.csdn.net/lngag110/article/details/38024441
    https://blog.csdn.net/lincoln_2012/article/details/49179503
    https://blog.csdn.net/gaoyingju/article/details/7340446
    https://www.kancloud.cn/digest/interview/164698

    相关文章

      网友评论

          本文标题:C语言面试题

          本文链接:https://www.haomeiwen.com/subject/acqmkftx.html