兆易創新嵌入式軟件工程師筆試題目解析


哈嘍,大家好。今天分享的是兆易創新的嵌入式軟件開發工程師的筆試題目。這份題目中等難度,考察基礎知識的偏多,最后的編程題只考了一個結構體數組的初始化。所以,在准備校招時,將重點還是要放在基礎知識上。下面看下這份題目你可以答幾分?

本文已同步更新在github,點擊跳轉。希望大家能給個star支持下!

@

目錄

單選題

1.Linux中使用 mkdir命令創建新的目錄時,在其父目錄不存在時先創建父目錄的選項是()

A -m

B -d

C -f

D -p

D

mkdir [選項] [目錄]

-m --mode=模式,建立目錄的時候同時設置目錄的權限。

-p --parents 若所建立的上層目錄目前尚未建立,則會一並建立上層目錄。

-v --verbose 每次創建新目錄都顯示信息。

-h --help 幫助信息。

2.下面代碼創建了多少個進程(不包含main進程本身)()

int main(int argc,char* argv[])
{
   fork();
   fork() && fork() || fork();
   fork();
}

A 19

B 30

C 24

D 29

A

這道題主要考了兩個知識點,一是邏輯運算符運行的特點;二是對fork的理解。

如果有一個這樣的表達式:cond1 && cond2 || cond3 這句代碼會怎樣執行呢?

1、cond1為假,那就不判斷cond2了,接着判斷cond3。

2、cond1為真,這又要分為兩種情況:

​ 2.1 cond2為真,這就不需要判斷cond3了。

​ 2.2 cond2為假,那還得判斷cond3。

fork調用的一個奇妙之處在於它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值:

1、在父進程中,fork返回新創建子進程的進程ID。

2、在子進程中,fork返回0。

3、如果出現錯誤,fork返回一個負值(題干中說明了不用考慮這種情況)。

在fork函數執行完畢后,如果創建新進程成功,則出現兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數返回0,在父進程中,fork返回新創建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。

有了上面的知識之后,下面我們來分析fork() && fork() || fork()會創建幾個新進程。

很明顯fork() && fork() || fork()創建了4個新進程。

總結:

第一行fork生成1個新進程。

第二行的三個fork生成4+4=8個新進程。

第三行的fork會生成10個新進程(這是因為前面總共有10個進程,調用一次fork生成10個新進程。

所以一共會生成1+8+10=19個新進程。

3.如果下列公式成立:3A*124=446C。則采用的是()進制

A 11

B 12

C 14

D 16

C

看個位。最后的結果446C個位為C,因此,A,B可以排除。

假設為14進制,(A * 4 )%14= 12,結果正好為C。因此,答案為14進制。

4.下面關於字符數組的初始化,那個是正確的?()

A char b[2][3] ={"d","e","f"};

B char b[2][3] ={"d","e"};

Cchar b[2][3] ={{"d","e","f"},{"a","b","c"}};

Dchar b[2] ={"d","e"};

B

通常情況下,二維數組的每一行分別使用一個字符串進行初始化。 例如:

char c[3] [8]={{"apple"},{"orange"},{"banana"}};

等價於:

char c[3][8]={"apple","orange","banana"};

A:應改為char b[3][2] ={"d","e","f"};

C:應改為char b[2][3][2] ={{"d","e","f"},{"a","b","c"}};

D:應改為 char b[2][2]={"d","e"};

5.在32位系統中,下列類型占用8個字節的為()

A int

B unsigned long long

C char

D short int

B

32位操作系統

int:4字節

unsigned long long:8字節

char :1字節

short int:2字節

注意和64位操作系統的區別:64位系統中,指針變量和long以及unsigned long 都占8個字節,其他的和32位系統一樣

簡答

1.

int a[6] = {1,2,3,4,5,6};
printf("%d\n",*((int*)(&a+1)-1)); 

那么打印結果是什么?

6。

*((int*)(&a+1)-1))化簡為:*(p-1) p=(int*)(&a+1)

&a是一個指向int(*)[6]的指針。由於&a是一個指針,那么在32位機器上, sizeof(&a)=4,但是&a+1的值取決於&a指向的類型,由於&a指向

int(*)[6],所以&a+1 = &a + sizeof(int(*)[6])=&a+24&a是數組的首地址,由此&a+1表示a向后移動了6個int從而指向a[6](越界),所以p指向的是a[6]。

由於p是int * 類型,那么p-1就指向a[5],所以 *(p-1)=a[5]=6。

2.請寫出常量指針和指針常量的代碼形式,並簡述他們的區別

int const *p1;const 在前,定義為常量指針

int *const p2; * 在前,定義為指針常量

常量指針p1:指向的地址可以變,但內容不可以重新賦值,內容的改變只能通過修改地址指向后變換。

指針常量p2:指向的地址不可以重新賦值,但內容可以改變,必須初始化,地址跟隨一生。

3.如何避免頭文件被重復包含

  1. 條件編譯:
#ifndef _HEADERNAME_H
#define _HEADERNAME_H


...//(頭文件內容)


#endif
  1. pragma once

指定當前文件在構建時只被包含(或打開)一次,這樣就可以減少構建的時間,因為加入#pragma once后,編譯器在打開或讀取第一個#include 模塊后,就

不會再打開或讀取隨后出現的相同#include模塊。

4.運行char name[] = "/dev/spdev"后,系統會分配幾塊內存,這些內存共占多少個字節?

11字節。

字符串最后以\0結尾,共占據11字節。

5.如下代碼,請設計宏定義STR(x),將USART_RATE轉換成字符串並打印出來

#define USART_RATE 115200
#define STR(x)____?
printf("usart rate = %s\n",STR(USART_RATE));

#define STR(x) #x

:會把參數轉換為字符串

6.已知結構體成員d的地址為p1,請獲取成員變量b的地址。

struct data{
	int a;
	char b;
	short c;
	short d;
	int e;
};

p1 - 4 * sizeof(p1)

結構體中成員變量在內存中存儲的其實是偏移地址。也就是說結構體的首地址+成員變量的偏移地址 = 結構體成員變量的起始地址。具體如下圖所示。

結構體在內存中的存儲

因此,將指針p1向上移動4個單位即可。即p1-4 * sizeof(p1)

7.請寫出下列代碼的輸出結果

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

d

buff是指針數組 ,一個3個元素的數組,數組里面是個字符串指針,這里執行buff+1時,則buff指向下一個數組元素,即int。

因此,*(buff+1)[0]指向int的地址,*(buff+1)[1] 指向double的地址,而最后是輸出一個字符。所以,輸出d。

8.下面的代碼輸出什么?為什么?

void foo(void)
{
	unsigned int a = 6;
	int b = -20;
	(a+b>6)?puts(">6"):puts("<=6");
}

>6

C中運算有規定,如果整型變量間進行數據運算,只要有一個變量是無符號的,結果就按無符號數據輸出,因此a+b > a
結果會輸出 >6

編程題

表一:人員信息表:(info_table)

序號(num) 姓名(name) 性別(gender) 年齡(age)
0 張三(Bob) 男(man) 60
1 李四(Chris) 男(man) 30
2 小紅(Colin) 女(woman) 56

表二:人員職業表:(work_table)

序號(num) 姓名(name) 職業(work) 等級(level)
0 張三(Bob) 司機(driver) 9
1 李四(Chris) 廚師(chief) 3
2 小紅(Colin) 幼師(teachers) 6

表三:技能成績表:(grade_table)

序號(num) 姓名(name) 技能(skill) 成績(grade)
0 張三(Bob) 開車(drive) 50
1 李四(Chris) 烹飪(cook) 64
2 小紅(Colin) 教學(teaching) 55

如上所示有人員-職業-成績的三個關系表

請嘗試

1.使用結構體表示三個表格。

2.設計一個函數來依次錄入人員信息

如add_personnel(info_table,work_table,grade_table);

/*
 * @Description: 兆易創新編程題
 * @Version: 
 * @Autor: 公眾號【嵌入式與Linux那些事】
 * @Date: 2021-04-03 21:46:16
 * @LastEditors: 公眾號【嵌入式與Linux那些事】
 * @LastEditTime: 2021-04-03 22:03:38
 */
#include <stdio.h>
//人員信息表
typedef struct info_table{
    char name[6];
    char gender[5];
    int age;
}INFO;
//人員職業表
typedef struct work_table{
    char name[6];
    char work[10];
    int level;
}WORK;
//技能成績表
typedef struct grade_table{
    char name[6];
    char skill[10];
    int grade;
}GRADE;
/**
 * @Description: 依次錄入人員信息
 * @param {INFO} *pinfo 
 * @param {WORK} *pwork
 * @param {GRADE} *pgrade
 * @Return: 無
 * @Author: 公眾號【嵌入式與Linux那些事】
 */
void add_personnel(INFO *pinfo,WORK *pwork,GRADE *pgrade){
      int i;
      for(i = 0;i < 3;i++){
      printf("請依次輸入第%d個人的信息:姓名,性別,年齡\n",i+1);
      scanf("%s%s%d",pinfo[i].name,pinfo[i].gender,&pinfo[i].age);
      printf("%s,%s,%d\n",pinfo[i].name,pinfo[i].gender,pinfo[i].age);
    }
      for(i = 0;i < 3;i++){
      printf("請依次輸入第%d個人的信息:姓名,職業,等級\n",i+1);
      scanf("%s%s%d",pwork[i].name,pwork[i].work,&pwork[i].level);
      printf("%s,%s,%d\n",pwork[i].name,pwork[i].work,pwork[i].level);
    }
      for(i = 0;i < 3;i++){
      printf("請依次輸入第%d個人的信息:姓名,技能,成績\n",i+1);
      scanf("%s%s%d",pgrade[i].name,pgrade[i].skill,&pgrade[i].grade);
      printf("%s,%s,%d\n",pgrade[i].name,pgrade[i].skill,pgrade[i].grade);
    }
}
int main()
{
    INFO info_array[3];
    WORK work_array[3];
    GRADE grade_array[3];
    add_personnel(info_array,work_array,grade_array);
    return 0;
}

今天的題目就分享到這里,關於題目,有任何疑問都可以私信我。下一篇文章,將會分享大廠的筆試題目解析。

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/qq_16933601/article/details/115752750


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM