第一题:

运行下面的代码,输出结果是什么,请解释说明:

#include<stdio.h>
int i;
int main(int argc, char *argv[])
{i--;if (i > sizeof(i)){printf(">\n");}else{printf("<\n");}return 0;
}

输出结果为:>

说明:sizeof运算符返回一个unsigned类型,而当i和sizeof(i)比较大小时,先将int类型的i转化为unsigined int类型,而-1转化成unsigined int类型是4294967295大于sizeof(i)=4;所以该程序输出>.

第二题:

执行下面的代码段,输出结果和你预想的一样没吗?谈谈你对宏的理解:

#include<stdio.h>
#define A 2+2
#define B 3+3
#define C A*B
int main(int argc,char *argv[])
{printf("%d\n",C);return 0;
}

该程序输出11;

在编译时,编译器会把C替换成2+2×3+3,因此计算结果是11.

宏:一些命令组织在一起,作为一个单独命令完成一个特定任务

它在某些地方与函数相似,但可省去函数调用的代价,但是代码长度会大一些。因为不管宏语句在代码中出现了多少次,每次都被完整的宏体所替代,而函数码在程序中只存在一次就可以了。

与函数的区别,是宏将代码复制到调用处,而函数是转去执行,如调用10次,则宏的代码被复制10次,而函数的代码只有一份。使用宏的速度快,但程序较大,使用函数程序较小,但相对速度要慢。

所以比较短小又使用频繁的功能适合做成宏,而相对大些的写成函数。

宏嵌套的展开规则:

1.一般的展开规律像函数的参数一样:先展开参数,再分析函数,即由内向外展开
2.当宏中有#的时候,不展开参数
3.当宏中有##的时候,先展开函数,再分析参数
4.##运算符用于将参数连接到一起,预处理过程把出现在##运算符两侧的参数合并成一个符号,注意不是字符串。

第三题:分析下面程序的输出结果:

#include<stdio.h>
int main(int argc,char*argv[])
{char str[]="Welcome to XiyouLinuxGroup";printf("%zu %zu\n",strlen(str),sizeof(str));return 0;
}

该程序输出26 27;

strlen函数计算字符串的长度,遇到\0则停止并返回,而sizeof是计算字符串所占内存大小,sizeof运算符算入了字符串最后一个\0而strlen遇到则\0立即返回因此strlen函数计算出的结果比sizeof运算符计算出的结果小1。

第五题:

分析以下程序,推测并验证其作用:

#include<stdio.h>
int main(int argc,char*argv[])
{int number;unsigned mask;mask=1u<<31;scanf("%d",&number);while(mask){printf("%d",(number&mask)?1:0);mask>>=1;}return 0;
}

该程序的作用是将输入的整数number以二进制形式输出。

1U 表示 无符号整型 1,语句mask=1u<<31的作用是将1左移31位后赋值,mask的值就是1000 0000 0000 0000 0000 0000 0000 0000,

接下来读入一个数字number,循环时对number与mask进行按位与计算,如果(number&&mask)则输出1,否则输出0,每循环一次将mask右移一位并赋值,直到mask每一位全部为0推出循环。

C按位运算符:

(1)二进制反码或按位取反:~

一元运算符~把1变为0,把0变为1.   例如:

~(10010011)//表达式

(01101100)//结果值

(2)按位与:&

二元运算符&通过逐位比较两个运算对象,生成一个新值,对于每个单位,只有两个运算对象中相应的位都为1时,结果才为1,否则都为0.例如:

(10010011)&(11110001)//表达式

(10010001)//结果值

(3)按位或:|

二元运算符|,通过逐位比较两个运算对象,生成一个新值。对于每个位,如果两个运算对象中相应的位为有一个为1,结果为1.例如:

(10010011)|(11110001)//表达式

(11110011)//结果值

(4)按位异或:^

二元运算符^逐位比较两个运算对象,对于每个位,如果两个运算对象中相应的位一个为1,一个不为1,则结果为1,否则结果为0.例如:

(10010011)^(11110001)//表达式

(01100010)//结果值

移位运算符:

(1)左移:<<

左移运算符<<将其左侧运算对象每一位的值向左移动其右侧运算对象指定的位数,左侧运算对象移出左末端位的值丢失,用0填充空出的位置

(01100111)<<2//表达式

(10011100)//结果值

(2)右移:>>

右移运算符>>将其左侧运算对象每一位的值向右移动其右侧运算对象指定的位数,右侧运算对象移出右末端位的值丢失,用0填充空出的位置

(01100111)>>2 //表达式

(00011001) //结果值

第六题:

下面程序的运行结果是什么,请解释说明:

#include<stdio.h>
int main()
{char *str="Xiyou Linux Group";printf("%c\n",*str+1);return 0;
}

程序运行的结果是Y;

说明:printf("%c\n",*str+1);语句的作用是打印一个字符,*的优先级比+高,因此*str为X,*str+1为Y故输出Y。

C语言运算符优先级:

优先级

运算符

名称或含义

使用形式

结合方向

说明

1

[]

数组下标

数组名[常量表达式]

左到右

--

()

圆括号

(表达式)/函数名(形参表)

--

.

成员选择(对象)

对象.成员名

--

->

成员选择(指针)

对象指针->成员名

--

2

-

负号运算符

-表达式

右到左

单目运算符

~

按位取反运算符

~表达式

++

自增运算符

++变量名/变量名++

--

自减运算符

--变量名/变量名--

*

取值运算符

*指针变量

&

取地址运算符

&变量名

!

逻辑非运算符

!表达式

(类型)

强制类型转换

(数据类型)表达式

--

sizeof

长度运算符

sizeof(表达式)

--

3

/

表达式/表达式

左到右

双目运算符

*

表达式*表达式

%

余数(取模)

整型表达式%整型表达式

4

+

表达式+表达式

左到右

双目运算符

-

表达式-表达式

5

<<

左移

变量<<表达式

左到右

双目运算符

>>

右移

变量>>表达式

6

>

大于

表达式>表达式

左到右

双目运算符

>=

大于等于

表达式>=表达式

<

小于

表达式<表达式

<=

小于等于

表达式<=表达式

7

==

等于

表达式==表达式

左到右

双目运算符

!=

不等于

表达式!= 表达式

8

&

按位与

表达式&表达式

左到右

双目运算符

9

^

按位异或

表达式^表达式

左到右

双目运算符

10

|

按位或

表达式|表达式

左到右

双目运算符

11

&&

逻辑与

表达式&&表达式

左到右

双目运算符

12

||

逻辑或

表达式||表达式

左到右

双目运算符

13

?:

条件运算符

表达式1?

表达式2: 表达式3

右到左

三目运算符

14

=

赋值运算符

变量=表达式

右到左

--

/=

除后赋值

变量/=表达式

--

*=

乘后赋值

变量*=表达式

--

%=

取模后赋值

变量%=表达式

--

+=

加后赋值

变量+=表达式

--

-=

减后赋值

变量-=表达式

--

<<=

左移后赋值

变量<<=表达式

--

>>=

右移后赋值

变量>>=表达式

--

&=

按位与后赋值

变量&=表达式

--

^=

按位异或后赋值

变量^=表达式

--

|=

按位或后赋值

变量|=表达式

--

15

逗号运算符

表达式,表达式,…

左到右

--

第七题:

以下程序的运行结果是什么,你知道怎么判断两个浮点数是否相同吗?

#include<stdio.h>
int main()
{double a=3.14;float b=a;if((float)a==b){printf("Xiyou");}if(a!=b){printf("LinuxGroup\n");}return 0;
}

该程序的运行结果是XiyouLinuxGroup;

将double类型的a赋给b时有精度缺失因此a!=b但是在第一个if语句里面将a暂时转化成了float类型,因此此时b与同样有精度缺失的a相比较,二者的大小是相等的。

第八题:

运行下面的代码,解释运行结果并谈谈自己的理解。

#include<stdio.h>
int main(int argc,char*argv[])
{int a[6]={0x6f796958,0x694c2075,0x2078756e,0x756f7247,0x30322070,0};printf("%d\n",printf("%s",(char*)a));return 0;
}

该程序中数组a中存储的数以小端模式存储,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

什么是大端和小端

大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

举个例子,比如数字 0x12 34 56 78(4个字节)在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址(数字高位存于低地址)
0x12 | 0x34 | 0x56 | 0x78
可见,大端模式和字符串的存储模式类似。
2)小端模式:
低地址 ------------------> 高地址(数字高位存于低地址)
0x78 | 0x56 | 0x34 | 0x12

printf("\n%d \n\n",printf("%s",(char*)a));语句里面嵌套的那一个printf语句将a数组中的每一个元素按照小端模式表示出来以ASCII码的形式输出,最后一位ASCII码为0其表示的字符是NULL,停止输出,并返回打印的字符数20;外层的printf语句打印20;

因此该程序的输出为Xiyou Linux Group 2020

第九题:

分析下列程序的输出,解释其原因。

#include<stdio.h>
int main()
{int a[2][3]={{5,7},{5,2}};int b[2][3]={5,7,5,2};int c[2][2]={{5,7},{5,2}};int d[2][2]={5,7,5};printf("%d %d\n",a[1][1],b[1][1]);printf("%d %d\n",c[1][1],d[1][1]);return 0;
}

该程序的输出为:

2 0
2 0

原因:

数组a和c的赋值就是按照格式,只给前两行的每一行的前两个赋值,而数组b和d就是按照顺序给第一行赋值完转到第二行(按顺序赋值)

数组赋值时,如果赋值的个数小于数组分配的个数,会给该数组未赋值的部分自动赋值为0

第十题:

执行下面的程序段,其输出结果是什么,请依据相关知识,解析其原因。

#include<stdio.h>
int main(int argc,char*argv[])
{int a=1;printf("%d\n",*(char*)&a);return 0;
}

该程序的输出结果时是1;

&a得到了a的地址,(char*)强制转换为指针类型,之后又对其进行解引用,得到该地址上的对象的值,即a的值1

第十一题:

下面程序段的输出结果是什么,若取消第4行的const注释,a数组还能被修改吗?如果取消第7,8行的注释,程序还能正常运行吗,试着解释其原因。

#include<stdio.h>
int main(int argc,char*argv[])
{/*const*/char a[]="XiyouLinux\0";char *b="XiyouLinux\0";a[5]='\0';//b[5]='\0';printf("%s\n",a);//printf("%s\n",b);return 0;
}

该程序的运行结果是:Xiyou

如果取消第3行的注释,a会被声明为只读常量,程序不能正常运行;

b是一个字符串指针,而字符串指针类似于const 类型的数组,字符串指针指向的内容是不可修改的,用字符串指针定义的是存放在静态存储区,是常量,不可更改。

第十二题:

一个c源文件到一个可执行文件的过程中经历了一系列步骤,你了解这个过程吗,谈谈你对gcc的认识。

C编程的基本策略是,用程序把源代码文件转换成可执行文件。典型的C实现通过编译和链接两个步骤来完成这一过程。编译器把源代码转换成中间代码,连接器把中间代码和其他代码合并,生成可执行文件 。

在使用gcc编译程序时,编译过程可以细分为4个阶段:

●       预处理(Pre-Processing)

●       编译(Compiling)

●       汇编(Assembling)

●       链接(Linking)

Linux程序员可以根据自己的需要让gcc在编译的任何阶段结束,检查或使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为今后的调试做好准备。与其他常用的编译器一样,gcc也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。

gcc提供了30多条警告信息和3个警告级别,使用它们有助于增强程序的稳定性和可移植性。此外,gcc还对标准的C和C++语言进行了大量的扩展,提高了程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量。

第十三题:

仔细阅读下面这个函数,你可以看出这个函数的功能吗?试着理解算法原理,并尝试优化它。

void sort(int arr[],int size)
{int i,j,tmp;for(i=0;i<size-1;i++){for(j=0;j<size-i-1;j++){if(arr[j]>arr[j+1]){tmp=arr[j];arr[j]=arr[j+1];arr[j+1]=tmp;}}}
}

这段代码写的是冒泡排序;

冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端

冒泡排序的思路:

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、每趟从第一对相邻元素开始,对每一对相邻元素作同样的工作,直到最后一对。
3、针对所有的元素重复以上的步骤,除了已排序过的元素(每趟排序后的最后一个元素),直到没有任何一对数字需要比较。

//改进后的冒泡排序
void sort(int arr[],int size)
{int i,j,tmp;for(i=0;i<size-1;i++){int count=0;for(j=0;j<size-i-1;j++){if(arr[j]>arr[j+1]){tmp=arr[j];arr[j]=arr[j+1];arr[j+1]=tmp;count++;}}if(count==0){break;//如果一小轮完成之后没有数字的交换,则证明数组已经变得有序,可直接跳出循环,增加效率}}
}

西邮Linux兴趣小组2020纳新试题相关推荐

  1. 西邮Linux兴趣小组2020纳新试题题解

    西邮Linux兴趣小组2020纳新试题题解 1. 请试着解释其输出. int main(int argc , char *argv[]) {unsigned char a = 255;char ch ...

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

    1.大小和长度竟然不是一个意思, sizeof()和strlen()有什么异同之处? 他们对于不同参数的结果有什么不同?请试举例子说明. int main(void) { char s[] = &qu ...

  3. 西邮Linux兴趣小组2021纳新试题②

    1. 结果:127 -128 signed char的范围是-128~127 unsigned char的范围是0~256 计算a-ch是把ch转换成整数,而输出ch是进行了类型转换为char类型,1 ...

  4. [c语言]西邮Linux兴趣小组2020纳新面试题

    一.运行下面的代码,输出结果是什么,解释原因. int i; int main(int argc, char *argv[]) {i--;if (i > sizeof(i)){printf(&q ...

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

    1. 请试着解释其输出 int main(int argc , char *argv[]) {unsigned char a = 255;char ch = 128;a -= ch;printf(&q ...

  6. 西邮Linux兴趣小组2019纳新试题总结

    1.下面代码段将打印出多少个'='?运用相关知识解释该输出. int main() {for(unsigned int i=3;i>=0;i--){putchar('=');} } 无数个'=' ...

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

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

  8. Xiyou Linux兴趣小组2020纳新试题

    1.请试着解释其输出 int main(int argc , char *argv[]) { unsigned char a = 255; char ch = 128; a -= ch; printf ...

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

    注: 本题目仅作西邮Linux兴趣小组2021纳新面试题的有限参考. 为节省版面本试题的程序源码中省略了#include指令. 本试题中的程序源码仅用于考察C语言基础,不应当作为C语言代码风格的范例. ...

最新文章

  1. Uploadify jquery+falsh+UploadHandler.ashx
  2. [教程]Python函数的参数
  3. [转载] 后台进程符的使用 [文摘]
  4. 网关和路由器的区别_工业网关和工业路由器的区别?
  5. Nginx深入详解之过滤模块
  6. 人工智能 信道估计 深度学习_DEMO演示|基于IVP02D 人工智能工作站的深度学习引擎,实现人群热力估计...
  7. Oracle入门(十三C)之高级查询(下)
  8. java循环结构教程
  9. Spring.NET 1.3.1 正式版已发布
  10. Qt下继承于QObject创建的线程
  11. 有了docsify神器,从此爱上看文档
  12. 机器学习-学习笔记3.1-局部加权回归
  13. Java手机列表(供开发者参考)
  14. 腾讯云阿里云4月服务器价格对比
  15. 第08课:Retained 消息和 LWT
  16. 百万钱包借款时填资料一直显示服务器异常,百万钱包有连续放款失败,然后突然推过的吗?我已经失败四五...
  17. 6-ipv6基础知识之-有状态和无状态自动配置
  18. Perl函数及参数介绍
  19. 消费升级背景下零食行业发展报告_三只松鼠IPO闯关成功“零食第一股”能否守住食品安全底线...
  20. 手用计算机电池,二手电脑器材中的电池问题

热门文章

  1. 组态王图素制作_组态王教程很实用.doc
  2. 【网络工程师】<软考中级>无线通信网
  3. Android Home键引起的闪屏问题
  4. 计算机三级数据库备考,考三级数据库的一些建议和回答一些常见问题
  5. 2023北方民族大学计算机考研信息汇总
  6. [完]机器学习实战 第一章 机器学习基础(Maching Learning Foundation)
  7. 5.TypeScript入门之TS高级类型(class类)
  8. php系列之搭建PHP开发环境(XAMPP+PhpStorm)
  9. 立创EDA电路设计与制作
  10. css 实现 图片旋转