【校招面经】“学完C语言” · 这些高频面试考点你都掌握了吧~

目录

一、大小端字节序

1.大小端引入

2.何为大端小端

3.百度真题 

思路

代码执行 

4.作业补充 

二、深入理解static关键字 

1.static修饰局部变量

2. static修饰全局变量

3.static修饰函数

三、深剖const关键字 

1.const修饰变量

2.常变量可成为数组一部分吗?

3.const修饰指针

四、手写求字符串长度函数(strlen) 

1.方法一:普通解法

2.方法二:递归法

3.方法三:指针 - 指针

五、手写字符串拷贝函数(strcpy)

六、遇见安然遇见你,不负代码不负卿!


【前言】

为了考察自己对于C语言掌握情况,我特意在论坛里面整理了近百份C/C++研发方向的面经,我发现有很多知识点频繁被考察,下面我将这些高频考点分享给大家,铁汁们看看自己能答对多少个。(顺便说一下哈,C语言内容其实是非常多的,这里所说的“学完C语言”,指的仅仅是学完C语法而已)

【声明】

下面所总结的内容可能并不是面面俱到的,后续还会有所补充。 

【注意】:博主刚建立了一个社区和QQ学习群,链接和二维码在最下面哦,非常欢迎铁汁们的加入!

  

一、大小端字节序

1.大小端引入

看看下面这段代码:

#include<stdio.h>
 
int main()
{
	int a = 0x11223344;//以十六进制的形式赋值给a
 
	return 0;
}

很明显,在内存中存储的顺序不对呀,这是为什么?这里就要介绍大小端了。

2.何为大端小端

大端字节序存储:

当一个数据的低位放到高地址处,数据的高位放到低地址处;

小端字节序存储:

当一个数据的低位放到低地址处,数据的高位放到高地址处

比如上面的栗子:

3.百度真题 

下面看看15年百度的一道价值10分的笔试题! 

百度2015年系统工程师笔试题(10分):

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。 

概念的话都在上面啦,请看看如何设计小程序来判断...

思路

可以定义一个整型变量,并且初始化为1,所以它转换成十六进制表示形式就是0x00 00 00 01如果当前机器是小端字节序存储,那么从低地址到高地址就是01 00 00 00;如果当前机器是大端字节序存储,那么从低地址到高地址就是00 00 00 01;所以不同点就在于低地址处一个是01,一个是00,那怎么去判断呢?这里就可以使用前面指针所学的解引用操作,不过对于整型指针来说一次访问4个字节,而我们想要的仅仅读取到1个字节即可。所以这里就需要进行强制类型转换,将int* 转换成char* 类型的,这样的话进行指针解引用操作的时候,一次就只能访问一个字节的内容了。

分析起来很简单,下面看看代码该如何编写:

代码执行 

#include<stdio.h>
 
int main()
{
	int a = 1;//00 00 00 01
	char* p = (char*)&a;
	if (1 == *p)
	{
		printf("小端n");
	}
	else
	{
		printf("大端n");
	}
	return 0;
}

上面这段代码只是方便大家理解,实际上我们交给面试官看的话,这么写代码就显得很low啦,所以下面才是满分答案:

#include<stdio.h>
 
int check_sys()
{
	int a = 1;//0x00 00 00 01
	return (*(char*)&a);//返回0-大端;返回1-小端
}
 
int main()
{
	int ret = check_sys();
	if (1 == ret)
	{
		printf("小端n");
	}
	else
	{
		printf("大端n");
	}
	return 0;
}

4.作业补充 

unsigned int a = 0x1234;
unsigned char b = &a;
 
在32位大端式处理器变量b 等于()
A:0x00
B:0x12
C:0x34
D:0x1234
 
 
//很明显,答案是A,因为实际上a中放的是0x00001234

问:字符类型有大小端字节序问题吗?

答:没有,因为字符类型只有一个字节,何来字节序一说呢。


二、深入理解static关键字 

在我整理百份面经后,我发现,static、extern、const、struct等关键字是大多数公司考察的重点,考的相当频繁,其中不乏知名大厂!

下面详细介绍static关键字:

static —— “静态”之意

C语言中static是用来修饰变量和函数的。

  • 修饰局部变量——静态局部变量
  • 修饰全局变量——静态全局变量
  • 修饰函数——静态函数

1.static修饰局部变量

//代码1
#include<stdio.h>
void test()
{
	int a = 1;//局部变量a的作用域在test()中,当a出了作用域就被销毁了,下次调用test()时,又需要重新创建a
	a++;
	printf("%d ", a);
}
 
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		test();
	}
	return 0;
}

//代码2
#include<stdio.h>
void test()
{
	//static修饰局部变量a
	static int a = 1;
	a++;
	printf("%d ",a);
}
 
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		test();
	}
	return 0;
}

看:上面的两块代码几乎一样,只不过第二个代码中自定义函数test()里面用static修饰局部变量,所以出现了这样的差异。

根据代码2的结果推测出每一次调用test(),使用的a都是上一次函数调用时留下的a;第二次调用test()时,由于上次函数调用产生的a没有被销毁,所以不会再次创建a,直接跳到了下一步,a++

【敲黑板】:

static修饰局部变量的时候,其实是改变了变量的存储类型,由栈区存储变成了静态区存储,从而使得静态的局部变量出了自己的作用域也不会被销毁,其实也就是相当于改变了这个变量的生命周期。

这里补充一条小知识点:

内存是一块比较大的空间,在使用内存的时候,会划分出不同的功能区域:栈区、堆区、静态区(这里为了好理解就直接这样说了,后面会详细介绍到这块内容)

2. static修饰全局变量

//代码1
//add.c文件
int g_val = 2018;//g_val是在add.c文件中定义的全局变量
 
//test.c文件
//如果想使用来自其他文件(外部文件)的全局变量,要先声明一下
extern int g_val;
//extern是一个关键字,专门用来声明外部符号的
int main()
{
	printf("%dn", g_val);
	return 0;
}

上面这个程序是正常编译的,不过下面的这个程序就不行了哦

/代码2
//add.c文件
static int g_val = 2018;
 
//test.c文件
extern int g_val;
 
int main()
{
	printf("%dn", g_val);
	return 0;
}

第二个程序编译的时候会报错,因为出现连接性错误。

【解释】

一个全局变量在整个工程中的其他子文件内部能被使用,是因为全局变量具有外部链接属性什么叫外部链接属性,一个变量在一个文件中定义,但是在另一个文件中可以使用(访问)叫外部链接属性当一个全局变量被static修饰的时候。其外部链接属性就变成了内部连接属性;使得这个全局变量只能在自己的源文件内部使用,其他文件不能再使用,因为它不再具有外部链接属性,给我们的感觉是作用域变小了。另外,局部变量只有内部链接属性

3.static修饰函数

//代码1
//add.c文件
int Add(int x, int y)
{
	return x + y;
}
 
//test.c文件
extern int Add(int x, int y);
int main()
{
	printf("%dn", Add(2, 3));
	return 0;
}

上面的程序编译正常,但是下面的程序编译时会出现错误哦。

//代码2
//add.c文件
static int Add(int x, int y)
{
	return x + y;
}
 
//test.c文件
extern int Add(int x, int y);
int main()
{
	printf("%dn", Add(2, 3));
	return 0;
}

这个程序编译时出现连接性错误。

因为函数本身就具有外部链接属性,static修饰函数的时候,函数本来是具有外部链接属性的,但是被static修饰后,就变成了内部连接属性,导致这个函数只能在自己的源文件内部使用,给我们的感觉是改变了作用域。


三、深剖const关键字 

1.const修饰变量

【注意】:const修饰的只读变量不可直接被修改

//const修饰的只读变量不可以直接被修改
const int a = 10;
a = 20;//错误

问:const修饰的变量真的不能被修改吗?

其实const修饰的变量可以被间接修改掉 

//const修饰的变量可以间接被修改
const int i = 10;
int* p = &i;
*p = 20;
printf("%dn", i);//打印20

这样的话就有一个问题:const修饰变量意义何在?

  1. 让编译器进行直接修改式检查;
  2. 告诉其他程序猿(正在修改你代码的或者阅读你代码的)这个变量后面不要改哦,也属于一种”自描述”含义

2.常变量可成为数组一部分吗?

const int n = 10;
int arr[n] = {0};

注意,上面的代码在VS编译器(标准C)下直接报错了,但在gcc(GNU扩展)下可以正常编译,所以我们一切都要向标准看齐,这样的话,也就是不可以!上面的定义是错误的。 

3.const修饰指针

面试题:const* 和 *const 什么区别?

const修饰指针的时候(有两种):

const放在*的左边(const int* p) ,修饰的是*p,使得*p不能改变(保证指针指向的内容不能通过指针修改),但是指针变量p本身可以改变;
const放在*的右边(int* const p),修饰的是p,使得p 不能改变。但是*p可以被修改

题目描述:

下列选项中哪一种形式声明了一个指向char类型变量的指针P,P的值是不可修改的,但P指向的变量的值是可以修改的?C

A:const char* p;//const修饰*p
B:char const* p;//const修饰*p
C:char* const p;//const修饰p
D:const char* p;//const既修饰*p,又修饰p

思路:其实一看到题目中说p的值是不可修改的我们就应该想到const放在*的右边。


四、手写求字符串长度函数(strlen) 

库函数strlen()原型: 

1.方法一:普通解法

//方法一:普通方法
int my_strlen(const char* str)
{
    assert(str);//最好加上断言
	int count = 0;
	while (*str++)
	{
		count;
	}
	return count;
}

2.方法二:递归法

int my_strlen(const char* str)
{
	//找重复:my_strlen(str+1)是原问题的重复
	//找边界
	if (*str == '')
	{
		return 0;
	}
	return my_strlen(str + 1) + 1;
}

3.方法三:指针 - 指针

//方法三:指针 - 指针
int my_strlen(const char* str)
{
    assert(str);//最好加上断言
	char* end = str;
	while (end++)
	{
		;
	}
	return end - str;
}

五、手写字符串拷贝函数(strcpy)

//本题需要注意的有两点:
//一是str1要足够大
//二是要保存str1的首地址
char* my_strcpy(char* str1, const char* str2)
{
	assert(str1 && str2);//最好加上断言
	char* ret = str1;//注意哦,记得保存str1的首地址
	while (*str1++ = *str2++)
	{
		;
	}
	return ret;
}

【敲黑板】:本题需要注意的有两点:

  1. str1要足够大
  2. 保存str1的首地址 

六、遇见安然遇见你,不负代码不负卿!

今天暂且到这里咯,后续会持续更新的哈,目标大厂,从最基本的知识点做起!

如果有所收获,求求来个三连吧~

博主昨天刚建立了一个社区,非常欢迎铁汁们的加入并同步自己的博文到社区里引流,后面我也会在社区里开展一些奖励活动的哟,快来join us!

【招贤纳士】:建立初期,希望大家各显神通,表现积极优秀的童鞋可以搭伙一同管理社区!

https://bbs.csdn.net/forums/Bit-runout?category=0https://bbs.csdn.net/forums/Bit-runout?category=0icon-default.png?t=LA92https://bbs.csdn.net/forums/Bit-runout?category=0

最近由于我忙着复习备战期末考试,所以有很多铁汁给我的私信都没有及时回复,实在是对不起,所以我建立了一个QQ群,里面有很多资料,包括C/C++研发方向、Java研发方向的书籍,还有许多算法书,欢迎大家加入,如果有问题可以发到群里面,我们一同探讨,总之一句话,拒绝躺平,冲刺大厂!

QQ群号:926297014

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>