系统相关
首页 > 系统相关> > [c语言]西邮Linux兴趣小组2020纳新面试题

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

作者:互联网

一.运行下面的代码,输出结果是什么,解释原因。

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

        这里会输出“>”这个符号,因为i是全局变量,会初始化为0,对sizeof(i),i为int类型,所以为4,

i--后i为-1,所以-1<4,输出“<”符号。

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

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

        宏是简单的替换,所以C=2+2*3+3=11,而不是c(2+2)*(3*3)

三.分析下面程序的输出结果

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

%zu是size_t的输出类型,size_t是标准c库里定义的。

/*  32位 */
typedef unsigned int    size_t;
typedef int             ssite_t;
 
/*  64位 */
typedef unsigned long   size_t;
typedef long            ssize_t;

strlen()是获取该字符串的长度,而sizeof是获取该变量占据的字节数。

所以结果是26和27,sizeof比strlen多获取了“\0”占据的字节数。

(int argc.char*argv[])是命令行参数有关的感兴趣可以去了解。

四.在程序中执行此函数,输出结果是什么,在同一程序中多次执行该函数,产生的输出结果是否相同?

void fun()
{
 int x = 0;
 static int num = 0;
 for (int i = 0; i < 5; i++)
 {
 x++;
 num++;
 }
 printf("x = %d num = %d\n", x, num);
}

num是static定义的静态局部变量,它的生命周期一直到本程序的结束,而作用域是本函数,本函数出去后,该变量就不能再调用,但多次调用该函数,num会承接上次调用该函数时的num的值,所以,num一直增加,而x每一次调用就从0开始。

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

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;
}

作用:将十进制转换为二进制

        mask的值是2^32次方,1在符号位上,将number与mask进行“&”位与运算,总共做32次,将number的二进制梅一位进行计算得出。

加上number为3,那么运算就是

1:        10000000 00000000 00000000 00000000

              10000000 00000000 00000000 00000011//得到第一位的值

2:        01000000 00000000 00000000 00000000

              10000000 00000000 00000000 00000011//得到第二位的值

…………

32:         00000000 00000000 00000000 00000001

                10000000 00000000 00000000 00000011//得到第32位的值

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

int main(int argc, char *argv[])
{
     char *str = "Xiyou Linux Group";
     printf("%c\n", *str + 1);
     return 0;
}

结果为:Y 

*(str+1)的话就是:字符串的指针表示,*str为字符串指针,str就是字符串第一个字符的地址,printf("%c",*str)就是输出第一个字符,*(str+1)就是输出第二位字符处。

而*str+1,就是在*str值的基础上+1,而字符不能+1,所以会转换成ascii加1,X的ascii+1正好是Y.

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

int main(int argc, char *argv[])
{
    double a = 3.14;
    float b = a;
    if ((float)a == b)
    {
        printf("Xiyou");
    }
    if (a != b)
    {
        printf("LinuxGroup\n");
    }
    return 0;
}

结果:LinuxGroup

因为计算机计算出来的小数点后的值是有精度的,常数赋值不会有问题,而经过计算的和常数赋值的比较会出现误差,计算的会有精度损失,这时候就需要用一个极小的值做比较大小(记得求绝对值,因为你可能不能确定哪一个大,哪一个小)。

例如:

#include<stdio.h>
#include<math.h>
int main(){
    double a=1.14;
    double b=0.9+0.24;

    if(fabs(a-b)<0.00000001){
        printf("True\n");
    }else{
        printf("False\n");
    }

    return 0;
}

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

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

运行结果:Xiyou Linux Group 2020

a的输出结果是Xiyou Linux Group 20,%d输出printf的返回值,printf的返回值是20,里面的printf意味着有20个字符,而Xiyou Linux Group 20正好20个字符。

a[6]的里面是十六进制的ascii码,还有大小端的知识,根据输出结果看,我的是小端模式。

附送测试方法:

int main(){
    int num = 0x12345678;
    char cs = *(char*)&num;

    // 低地址处是高字节,则为大端
    if ( cs == 0x12 )    
        printf("大端");
    else{
        printf("小端");
    }
}

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

int main(int argc, char *argv[])
{
    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,是一个二维数组,相当于包含两个一维的数组,而第一个一维数组的第三个值没有赋,所以没有第三个值,第二个数组的第二位,即a[1][1],值为{5,2}中的2.

        对b,也是一个二维数组,但是相较于a,没有{}包裹,所以第一个一维数组的有第三个值,为5,第二个一维数组的第2,3位没有赋值,所以没有b[1][1],未初始化,为随机数,0为巧合。

        对c,是一个二维数组,包含的一维数组有两个值,所以它的值全赋了,按常输出,c[1][1]值为2.

        对d,是一个二维数组,包含的一维数组有两个值,但它只赋了三个值,第四个未赋值,所以第四个数。d[1][1]为随机数,0为巧合。

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

int main(int argc, char *argv[])
{
     int a = 1;
     printf("%d\n", *(char *)&a);
}

 输出结果:1

        (char*)&a,将a的地址强制转化为字符类型的指针,然后输出该地址的值的ascii码值,即将int类型4字节的,变成char类型的1字节的值,但在小端模式下(我前面说了),1的低地址存储在低字节,转化为char类型,没有变化。

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

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

        按题目改都是错的(乐), 因为带const的都是常量,是为了防止自己乱改加的东西,不能更改,b是一个字符串指针,而字符串指针类似于const char b[],字符串指针指向的内容是不可修改的,用字符串指针定义的是存放在静态存储区,是常量,不可更改。

  十二.    c源程序->可执行文件过程,gcc

        我上一个博客说过了,就不再说了。

对于gcc:浅显易懂的GCC使用教程——初级篇_大娱乐家-CSDN博客_gcc使用,我觉得这个讲的特别好,我讲也讲不这么清楚,所以我直接贴链接。

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

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,3,2,6,5,4

先将1与3比较,发现1<3,到下一位,3与2比较,3向后移动一位…………(将最大的数移动到最后一位)

 然后从第一次内循环出来,进行第二次比较。(第二大的值移动到倒数第二位)

…………最后由小到大排好序

 

标签:面试题,int,00000000,纳新,char,西邮,str,printf,main
来源: https://blog.csdn.net/yeyr2/article/details/121639435