这篇文章是对linux 近三年的纳新面试题的小小总结,篇幅有点长,希望你可以耐心看完,看完你一定有收获,有什么不妥可以提出的吖

知识点一:sizeof()和strlen()的异同

先看道题我们再来总结知识点

输出:16   12

解析:I  love Linux \0\0\0一共是15个内存,生成字符类型的时候会在后面自动补充一个'\0',所以是16

strlen是以遇到的第一个'\0'为结束符, I  love Linux为12个字符长度

显而易见,这道题考查的是与sizeof()和strlen()相关的知识点,我们来总结一下

学以致用,我们来练习一道题

输出结果:26  27

!!你对了吗,没有对的话好好看一下知识点哦

知识点二:unsigned int:

无符号整型,表示从0开始到2^32-1的所有整数,
unsigned后面的int可以省略
递减运算符–(顺便也把递增运算符++了解一下叭)
知识点三:递增递减运算符
“++”和“– –”是两个很特殊的运算符,它们是单目运算符,这个算子还必须是变量。这两个运算符分别叫做递增和递减运算符他们的作用就是给这个变量+或者-1。
例如:
         count++:
         count +=1
         count=count+1
前缀后缀
●++和–可以放在变量的前面,叫做前缀形式,也可以放在变量的后面,叫做后缀形式。

·a++的值是a加I以前的值,而++a的值是加了I以后的值,无论哪个,a自己的值都加了I了。

知识点四:交换两个整数的三种方式

解析:
(1) 使用了一个中间变量 ,先把a的值赋给中间变量,再把b的值赋给a,再把中间变量的值赋给b;
(2) 通过数学运算 将两个变量的值进行交换;
(3) 按位异或(^) :两者相同为0,不同为1;用异或运算讲a与b相应位若相同记为0,不同记1,其值给a,再将b与a进行异或运算实现b到a的转变,再用a与b进行异或运算实现a到b的转变.

按位异或小小知识点

知识点五:static关键字

先看题

输出结果:1,1(多次执行b的值会一直是1,a的值会一直增加)
解析:使用static修饰符定义静态局部变量,它的生命周期是整个应用程序的运行时间,只会被初始化一次,所以第一次执行的时候a的值是1,多次执行a的值就会递增。

知识点总结

♞static关键字的功能
①先来介绍它的第一条也是最重要的一条:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。

②static的第二个作用是保持变量内容的持久。 存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。

③static的第三个作用是默认初始化为0 。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。

☞学以致用,做道题叭

输出结果:5 5
BUT!!多次执行num的值会按照5的倍数递增5,10,15

拓展小知识(芝士 就是力量)
★static全局变量和普通全局变量区别:static全局变量和普通全局变量存储方式都为静态存储方式,区别在于各自的作用域,普通全局变量的作用域是整个源程序,,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都有效,而静态全局变量则限制了作用域,只在定义该变量的源文件中有效.

★static局部变量和普通局部变量区别:static局部变量和普通局部变量的存储方式即生存期不同,static局部变量具有全局的生存期, 只初始化一次, 离开函数后仍然存在, 具有函数内的局部作用域,是特殊的全局变量.

★static函数和普通函数区别:static函数与普通函数作用域不同,仅在本文件.只在当前源文件中使用的函数应该说明为内部函数即static修饰的函数,内部函数应该在当前源文件中说明和定义.对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。

知识点六:printf函数的返回值

例题:

输出结果: Xiyou Linux Group2019
解析:
函数嵌套,先打印了一个空字符,之后打印Xiyou Linux Group2,0通过%d被打印出来,19作为返回值被最后一次printf函数打印出来

知识点总结
printf()函数也有一个返回值,它返回打印字符的个数.
大部分C函数都有一个返回值,这是函数计算并返回给主调程序的值.可以把返回值赋给变量,也可以用于计算,还可以作为参数传递.

知识点七:宏定义#define

输出结果:3
解析:
你是不是认为结果是4但是,不是这样啦,应该是1+1*1+1=3因为这里没有(),所以先算乘法,如果是4应该这样写:
#define X(a+b)

知识点总结

宏定义一般形式:
#define 标识符 字符串
“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。
“标识符”为所定义的宏名。
“字符串”可以是常数、表达式、格式串等。
例如:#define M (a+b)它的作用是指定标识符M来代替表达式(a+b)。
在编写源程序时,所有的(a+b)都可由M代替,而对源程序作编译时,将先由预处理程序进行宏代换,即用(a+b)表达式去置换所有的宏名M,然后再进行编译。
注意:定义M来替代表达式(a+b),若 s= M * M 在预处理时经宏展开后该语句变为: S=(a+b)(a+b)注意的是,在宏定义中表达式(a+b)两边的括号不能少 ,否则会发生错误。
☞啥也不多说,练题
 

输出结果:11

我猜你肯定对了,所以不用我多说*~*

知识点八:按位运算and逻辑运算

输出结果:
x=-1,y=4,t=-1
x=0,y=5,t=1

知识点总结:

递增递减运算符(第一题中有所以在这里就不说啦)
按位运算安排起来

看完清清楚楚的图,现在你是明明白白的叭ฅ˙Ⱉ˙ฅ
☞练一道题就更明白啦

 小小解析:十进制的7对应二进制的111
                 所以呢这段代码的功能就是把十进制转化成二进制

下面是逻辑运算啦

逻辑运算的结果
在编程中,我们一般将零值称为“假”,将非零值称为“真”。逻辑运算的结果也只有“真”和“假”,“真”对应的值为 1,“假”对应的值为 0。

①与运算(&&)参与运算的两个表达式都为真时,结果才为真,否则为假。
例如:
5&&0
5为真,0为假,相与的结果为假,也就是 0。(5>0) && (4>2)
5>0 的结果是1,为真,4>2结果是1,也为真,所以与的结果为真,也就是1。

②或运算(||)参与运算的两个表达式只要有一个为真,结果就为真;两个表达式都为假时结果才为假。
例如:
10 || 0
10为真,0为假,相或的结果为真,也就是 1。(5>0) || (5>8)
5>0 的结果是1,为真,5>8 的结果是0,为假,所以相或的结果为真,也就是1。

③非运算(!)参与运算的表达式为真时,结果为假;参与运算的表达式为假时,结果为真。
例如:!0
0 为假,非运算的结果为真,也就是 1。
!(5>0)
5>0 的结果是1,为真,非运算的结果为假,也就是 0
知识点九:结构体struct

虽然排列顺序不同,但是结果都是16.

知识点总结

结构体在为其内部的变量分配内存时,遵循边界对齐原则。边界由结构体中最大数据类型决定。之所以要进行边界对齐,是为了防止有些数据同时占据两个相邻的边界,导致数据总线在访问时要访问两次,提高了工作效率。

结构体字节对齐一般满足这三个条件:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
 2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成       员之间加上填充字节。
 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员        之后加上填充字节。

知识点十:数据的溢出

输出结果:没有给a赋值,运行程序时编译器会报错,如果忽略,则ch输出-1
解析and知识点总结:
char类型的取值范围为-128~127,超出范围就会溢出,上溢是从-128往回,下溢则是从128往回;
255是一个整数,在计算机中存储数据采用补码的形式,而正数原码补码相同,
例如 :
原码 1111 1111
反码 1111 1111
补码 1111 1111
用char来看待这个二进制数字,由于符号位为1,则为负数,负数由补码求原码
补码 1111 1111
原码 1000 0001
所以呢,1111 1111用int来看是255
用char来看是-1.

知识点十一:const关键字

我们先来看一道题

请找出下面的代码的错误

int a =1;
int const b=2;
const int c=3;
void func0(int n){n+=1;n=a;
}
void func1(int*n){*n+=1;n=&a;
}
void func2(const int *n){//const*n前面表示不可以修改指针n所指向的内容*n+=1;//不能赋值n=&a;
}
void func3(int *const n){//const 在n前面表示不可以改变指针n所指向的地址*n+=1;n=&a;//不可以改变指向
}
void func4(const int *const n){//表示既不可以改变n所指向的内容,也不可以改变n所指向的地址*n+=1;//不能赋值n=&a;//不能改变指向
}

错误我已经在题目中指出,现在我们就来总结一下const的用法

const限定符,它把一个对象转换成一个常量,而常量不能修改,所以根据const修饰的对象,可以确定对象是否可以被修改。

例如:

char*const p:指向char的常指针,指针须在声明时就初始化,之后不可以改变它的指向

char  const*和const char *p:是同一种char类型指针,p所指向的内容不可以修改

char const* const p:  const修饰p和*p,所以p的值和p所指向的内容都不可以修改

知识点十二:指针与数组的理解

第一行:定义了一个int类型的变量val并初始化为2018;
第二行:声明了一个int类型的指针变量pi并初始化为2019;
第三行:将val变量的地址赋给pi;(&为取地址符)

第四行:将pi指向的空间所存储的数据改为0.

第二行代码解析:为20个char类型的值请求内存空间,并设置p指向该位置.
第三行代码解析:声明指针变量q,指向p所指向的空间(p和q指向了同一个地址.)
输出结果解析:输入Xiyou空格后改变了*p的值,再输入Linux 回车后改变了*q的值(实际改变                             的是同一个地址的数据),之后输入的Linux覆盖了之前输入的Xiyou,所以输出结                           果是:Linux Linux

这是我的电脑上的输出结果

解析:
每次执行输出的结果不一致,a分配的内存是动态的,所以a的地址一直变.
a表示数组的首地址
&a表示数组首元素的地址
a+1表示数组首地址加上一个元素 所占的地址大小,
int为4个字节,所以加4(1*4)
&a+1表示加上整个数组的大小,
这里数组尺寸是4,所以+1代表的是地址加上16(4x4).

数组与指针有很多零碎的小知识点,在这里我就不详细解释,有兴趣可以看看 c primer plus这本书

知识点十三:传值与传址的区别

结合下面的程序,简要谈谈传值和传址的区别

#include<stdio.h>
int ver=123;
void func1(int ver)
{ver++;printf("ver=%d\n",ver);//1026
}void func2(int*pr)//传入ver的地址给指针pr
{*pr=1234;//在此函数内部修改pr指向地址中的值printf("*pr=%d\n",*pr);//1234pr=5678;//警告(直接把int型常量赋值给int*指针)/*printf("*pr=%d\n",*pr);/*pr指向的地址已经被修改,其值不确定*/printf("ver=%d\n",ver);//123(全局变量)
}int main()
{int a=0;//函数内部变量int ver=1025;for(int a=3;a<4;a++){static int a=5;//静态全局变量(仅在此循环中起作用)printf("a=%d\n",a);//5a=ver;printf("a=%d\n",a);//1025func1(ver);int ver=7;//仅在此循环中起作用printf("ver=%d\n",ver);//7func2(&ver);}printf("a=%d\tver=%d\n",a,ver);//0(传值) 1025(传值)(函数内部变量会覆盖全局变量)return 0;
}

知识点总结

传值:

1)在传值中函数中函数参数压栈的参数的副本,任何的修改在副本上作用,没有作用在原来的变量上

2)传值时就是在内存中新开辟一个空间,将值赋给这个新开辟的空间,其生命周期为该函数调用结来时释放该空间,计算结果不影响原调用数据内存空间的值。
传址:

同样新开辟一个空间,但不同的是将所用数据空间的内存地址存在新开辟的空间中即指针,对原数据进行操作,操作后结果影响原数据。

知识点十四:c语言中变量的生命周期

全局变量:

进程开始时创建,进程结束时销毁,在代码编译后,直接将其初始值写入到执行文件中,创建时按照定义时的初始值进行赋值
局部变量和参数变量:

进入函数时创建,退出函数时销毁

全局静态变量:

定义一个全局变量并使用static关键字修饰时,这个变量就成了全局静态变量
它的生命周期和全局变量相同,但作用域被限制在文件内
静态局部变量:

在函数内使用static关键字修饰一个变量时,这个变量就为静态局部变量
它的生命周期同全局变量相同,作用域被限制在函数内。

知识点十五:两种字节序(大.小端)

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。
小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处(低低高高)
大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处(高低低高)

了解了概念,我们可以通过这段代码来看一看我们的电脑是哪种字节序

#include<stdio.h>
int main()
{
short int x=0x1122;
char x0,x1;
x0=((char*)&x)[0];
x1=((char*)&x)[1];
printf("%#x",x0);
return 0;
}//如果输出0x22则为小端
//输出0x11则为大端

学以致用,看题看题*~*

#include<stdio.h>
int main()
{int data[]={0x636c6557,0x20656d6f,0x78206f74,0x756f7969,0x6e694c20,0x67207875,0x70756f72,0x32303220,0x00000a31};puts((const char*)data);//输出结果:Welcome to xiyou Linux group 2021/*相当于:0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x200x74 0x6f 0x200x78 0x69 0x79 0x6f 0x75 0x200x4c 0x69 0x6e 0x75 0x78 0x200x67 0x72 0x6f 0x75 0x70 0x200x32 0x30 0x32 0x31*/return 0;//大小端
}

知识点十六:斐波那契数列相关知识

#include<stdio.h>//头文件
int main()//主函数,程序的入口
{ int i,f1,f2,f3,row; //定义变量  f1=1,f2=1; //变量初始化   printf("输入需要输出的行数:");//提示语句  scanf("%d",&row); //键盘输入行数   printf("%d\n%d\n",f1,f2); //先输出第一行和第二行   for(i=1;i<row-1;i++) ///循环控制后row-2行    {    f3=f2+f1; //第3行的值是前面两行之和    printf("%d\n",f3);     f1=f2; //变量赋值     f2=f3;  }}

一题多解(使用递归来解决)

#include<stdio.h>
int f(int n)
{
if(n==1||n==2)     return 1;
else       return f(n-1)+f(n-2);
}
int main()
{   int i;   scanf("%d",&i);   printf("%d",f(i));    return 0;}

知识点十七:冒泡排序以及选择排序

冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

算法描述
①比较相邻的元素。如果第一个比第二个大,就交换它们两个;
②对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
③针对所有的元素重复以上的步骤,除了最后一个;
④重复步骤1~3,直到排序完成。

稳定性
在相邻元素相等时,它们并不会交换位置,所以,冒泡排序是稳定排序。适用场景冒泡排序思路简单,代码也简单,特别适合小数据的排序。但是,由于算法复杂度较高,在数据量大的时候不适合使用。

代码优化
在数据完全有序的时候展现出最优时间复杂度,为O(n)。其他情况下,几乎总是O( n2 )。因此,算法在数据基本有序的情况下,性能最好。要使算法在最佳情况下有O(n)复杂度,需要做一些改进,增加一个flag的标志,当前一轮没有进行交换时,说明数组已经有序,没有必要再进行下一轮的循环了,直接退出。
 直接看代码

#include<stdio.h>
#include<stdbool.h>
int main()
{
int a[10];
int n;
int temp;
bool flag=true;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n-1&&flag;i++)
{
for(int j=0;j<n-1-i;j++)
{
flag=false;
if(a[j]>a[j+1])
{
flag=true;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;           }        }    }
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
} return 0;
}

下面我们来了解了解选择排序

选择排序
选择排序是一种简单直观的排序算法,它也是一种交换排序算法,和冒泡排序有一定的相似度,可以认为选择排序是冒泡排序的一种改进。

算法描述
①在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
②从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
③重复第二步,直到所有元素均排序完毕。

稳定性
用数组实现的选择排序是不稳定的,用链表实现的选择排序是稳定的。不过,一般提到排序算法时,大家往往会默认是数组实现,所以选择排序是不稳定的。

适用场景
选择排序实现也比较简单,并且由于在各种情况下复杂度波动小,因此一般是优于冒泡排序的。在所有的完全交换排序中,选择排序也是比较不错的一种算法。但是,由于固有的O(n2)复杂度,选择排序在海量数据面前显得力不从心。因此,它适用于简单数据排序。

#include<stdio.h>//头文件
int main()//主函数
{
int i,j,min,temp,array[11];//定义整型变量和数组
printf("输入数据:\n");//提示语句
for(i=1;i<=10;i++)//依次键盘录入10个数据
{
printf("array[%d]=",i-1);//数组下标从0开始
scanf("%d",&array[i]);
}
printf("\n");//换行
printf("原样输出:\n");//提示语句
for(i=1;i<=10;i++)//将键盘录入的10个数原样输出
{
printf("%5d",array[i]);
}
printf("\n");//换行
for(i=1;i<=9;i++)
{
min=i;//把第一个数作为最小的
for(j=i+1;j<=10;j++)
{
if(array[min]>array[j])//判断大小,小的为min      {
min=j;      }
}
temp=array[i]; //大小交换
array[i]=array[min];
array[min]=temp;
}printf("排序输出:\n");//提示语句  for(i=1;i<=10;i++)//输出排序后的10个数  {    printf("%5d",array[i]);  }  printf("\n");//换行  return 0;//主函数返回值为0}

下面的知识点大多数都是文字描述性的,有一丢丢枯燥,你可以大概了解了解哈

知识点十八:Linux命令ls的输出解释

先看一道题

-al 指各项说明,查看设备是否具有读写权限.
第一列指文件类型及权限;
第二列指链接占用的节点;
第三列指文件所有者;
第四列指文件所有者的用户组;
第五列指文件大小;
第六列指文件的创建时间或者最近修改时间;
第七列是文件名称.

拓展小知识

西邮linux小组2019-2021面试题总结相关推荐

  1. 西邮Linux小组免试题揭秘

    欢迎来到小码哥的博客 博客搬家啦 blog.ma6174.com 西邮Linux小组免试题揭秘 还记得东京大学情报理工学系的招生海报吗?只要答对了问题,然后你就被录取了.当时可火了,人人和微博疯狂转载 ...

  2. 西邮Linux小组2019-2021面试试题二三事

    目录 1.关于static 2.)关于printf()返回值 3.sizeof 和strlen() 4.数据的溢出 5.有关运算符 1.)|和|| 2.)<<和>> 6.关于c ...

  3. 西邮Linux小组22-20纳新面试题目及题解

    西邮Linux兴趣小组2022纳新面试题题解 感谢 Zhilu 重新录入题目原件.好人一生平安. 本题目只作为Xiyou Linux兴趣小组2022纳新面试的有限参考. 为节省版面,本试题的程序源码省 ...

  4. 西邮linux小组面试题总结(2016-5-30)

    1.const和define的区别: 1->const在编译阶段用,define在预处理阶段才替换 2->const检查类型,const int i=3.5,这就是错的:define不检查 ...

  5. 西邮Linux兴趣小组纳新笔试试题

    下面是西邮Linux小组今年纳新的笔试试题 1. 下面这个程序的输出结果是什么? int main() { int a = (1, 2); printf("a = %d\n", a ...

  6. 西邮linux兴趣小组网络,西邮Linux兴趣小组纳新笔试试题

    下面是西邮Linux小组今年纳新的笔试试题,原文在这里. 1. 下面这个程序的输出结果是什么? int main() { int a = (1, 2); printf("a = %d\n&q ...

  7. 西邮Linux兴趣小组2021纳新面试题

    #include<stdio.h> #include<string.h> int main(void) {char s[]="I love Linux\0\0\0&q ...

  8. 西邮linux兴趣小组2019,2020补纳面试题

    西邮linux兴趣小组2019,2020补纳面试题 2019补纳 2020补纳 C语言基础 数据结构与算法 GNU Linux常识 关于纳新试题,您需要了解: 本题仅作为面试有限参考 为了代码的简洁, ...

  9. 西邮Linux兴趣小组2019面试题总结

    西邮Linux兴趣小组2019面试题总结 unsigned int unsigned int 取值范围为0~4294967295,当i减到0后,再进行一次自减,会变为4294967295,永远满足&g ...

最新文章

  1. mysql数据库驱动_JDBC 加载mysql数据库驱动
  2. (JAVA)Object类之String类
  3. C++ 查看输入流中的下一个字符
  4. 前端大屏幕项目的一点思考
  5. pcl中ransac提取直线_SIFT关键点提取
  6. 录ppt的时候录光标_光标的使用.ppt
  7. Epub,Mobi,Azw3电子书格式的区别,有什么好用的安卓epub阅读器
  8. 获取当前日期上周的周一和周日日期
  9. Windows常用注册表文件-修改右键菜单
  10. 图像处理与计算机视觉基础相关领域的经典书籍以及论文
  11. 习题8-14 商队抢劫者(Caravan Robbers, ACM/ICPC SEERC 2005, UVa1616)
  12. 英特尔AVX指令集解析
  13. ZooKeeper - 分布式锁
  14. [DLX+bfs] hdu 4069 Squiggly Sudoku
  15. Pytorch中的DDP
  16. 爱普生墨仓式打印机故障检查,卡纸,清洗打印头,补充墨水详解(非常实用)
  17. 2021年中国程序员薪资和生活现状调查报告
  18. 国仁网络资讯:短视频拍摄如何上热门;掌握这8大拍摄运镜手法即可。
  19. 快拷神器ExtremeCopy
  20. android应用判断蓝牙是否连接,如何以编程方式判断蓝牙设备是否已连接?

热门文章

  1. (数组)88. 合并两个有序数组(java)
  2. 确定性随机数发生器测试向量——DRBG-HASH-SHA1
  3. Windebug双机调试环境搭建2020-10-12
  4. Vue中使用 class 类样式的方式
  5. 特征选择与稀疏学习详解
  6. 解决VA加载失败问题:visual assist ({44630D46-96B5-488C-8DF9-26E21DB8C1A3})未加载。请与程序包供应商联系以获得帮助
  7. h5端点击复制分享链接
  8. matlab 打印多个变量,matlab中怎么输出一个变量的值
  9. webstorm 格式化代码Ctrl+alt+l 失效
  10. noip day2 聪明的质检员