C语言面试题

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要。在目前的计算机系统或嵌入式系统中,内存资源仍然是...
    一生信仰阅读 4,985评论 0 2
  • 1.static关键字的作用? 1)第一个作用:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量...
    轻皱眉头浅忧思阅读 4,464评论 1 9
  • 《2018 iOS面试题系列》 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问...
    八级大狂风AM阅读 13,834评论 1 46
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,461评论 30 472
  • 文/少林林默 嫁人当嫁辛夷,比起秋水的渣,小白的软弱,辛夷对妖刀是始终如一。 ❤ 辛夷,最后的毕业典礼,也是他的婚...
    尤林默阅读 6,691评论 8 22

友情链接更多精彩内容