2016年下半年嵌入式系统设计师案例
试题一【说明】某综合化智能空气净化器设计以微处理器为核心包含各种传感器和控制器具有检测环境空气参数包含温湿度、可燃气体、细颗粒物等空气净化、加湿、除湿、加热和杀菌等功能并能通过移动客户端对其进行远程控制。图1-1为该系统电气部分连接图除微处理器外还包括了片上32KB FLASH以及SRAM和EEPROM。【问题1】该系统的SRAM的地址线宽度为11数据线宽度为8其容量为多少字节分析【问题2】该系统分别设计了iOS和Android两种不同操作系统下的客户端程序二者在开发上都使用MVC模型M—视图V—控制器C设计模式。在典型的程序设计中用户可以直接和视图进行交互通过对事件的操作可以触发视图的各种事件再通过控制器以达到更新模型或数据的目的。请完善图1-2所示的流程模型。分析MVCModel-View-Controller模型-视图-控制器是一种经典的软件架构设计模式广泛用于用户界面GUI和 Web 应用程序中。它的核心思想是将应用程序的输入、处理、输出解耦从而提高代码的可维护性、可扩展性和可测试性。MVC 的三个核心组件① Model模型职责管理应用程序的数据、业务逻辑和规则。特点不依赖视图或控制器不关心数据如何显示或如何接收用户输入。例子数据库操作、数据计算、状态管理。② View视图职责负责数据的可视化呈现即用户界面。特点从 Model 获取数据并显示不处理业务逻辑。例子HTML 页面、GUI 窗口、图表。③ Controller控制器职责接收用户输入点击、键盘、API 请求等调用 Model 更新数据并选择 View 显示结果。特点起“中介”作用协调 Model 和 View。答案(1) 控制器 (2) 视图 (3) 模型【问题3】该系统采用数字式激光传感器检测PM2.5、PM10并通过异步串行接口将数据上报给处理器通信波特率为9600bps上报周期为1.5秒数据帧内容包括报文头、指令号、数据6字节、校验和及报文尾具体字段描述如表1-1所示。王工根据数据报文通信协议使用C语言编写了对应的数据接收和校验程序请根据注释要求补全程序。程序段如下#define uint16_t unsigned short#define uint8_t unsigned charuint16_t Pm25;uint16_t Pm10;void ProcessSerialData(){uint8_t mData 0;uint8_t i 0;uint8_t mPkt[10] {0};uint8_t mCheck 0;while (Serial.available() 0){mData Serial.read();delay(2); // 延迟 2 毫秒// 等待直到有效数据包接收到if(mData (1)){mPkt[0] mData;mData Serial.read();if(mData (2)){mPkt[1] mData;mCheck 0;// 接收数据并进行校验计算for(i0; i 6; i){mPkt[i2] Serial.read();delay(2);mCheck (3);}mPkt[8] Serial.read();delay(1);mPkt[9] Serial.read();if(mCheck (4)) // 校验判断{Serial.flush();// 请使用位操作方式计算 Pm25 和 Pm10 的值Pm25 (5);Pm10 (6);}}}}}分析已知的报文格式第 (1) 空报文头判断代码位置if(mData (1))原理程序循环读取串口数据等待第一个字节mData是合法的报文头。根据协议表报文头固定为0xAA十六进制。如果第一个字节不匹配则丢弃并继续下一个字节直到找到0xAA才认为可能是一帧数据的开始。答案0xAA--------------------------------------------------------------------------------------------------------------------------第 (2) 空指令号判断代码位置if(mData (2))原理接收到0xAA后程序立即读取下一个字节应为指令号。协议规定指令号为0xC0用于标识该数据帧类型比如 PM2.5/PM10 数据。如果指令号不对说明不是预期的数据帧丢弃。答案0xC0--------------------------------------------------------------------------------------------------------------------------第 (3) 空累加校验和的数据源代码位置mCheck (3);原理校验和规则数据1 到 数据6的字节加和。程序中mPkt[2]~mPkt[7]正好对应 数据1 ~ 数据6。在for循环中i 0到5依次读取的字节存入mPkt[i2]并累加到mCheck。所以mCheck mPkt[i2]或mCheck mData变量mData刚被赋值为Serial.read()的返回值都可以。答案 mPkt[i2] // 或 mData--------------------------------------------------------------------------------------------------------------------------第 (4) 空校验结果的判断代码位置if(mCheck (4))原理校验和字节第 9 字节索引 8是接收方提前算好并发送的。接收方重新计算数据1~数据6的加和mCheck应与收到的mPkt[8]比较。相等则数据有效否则说明传输错误丢弃。答案mPkt[8]--------------------------------------------------------------------------------------------------------------------------第 (5) 空PM2.5 值的位操作计算代码位置Pm25 (5);原理根据表 1-1mPkt[2] PM2.5 低字节mPkt[3] PM2.5 高字节PM2.5 是一个 16 位无符号整数高位左移 8 位加上低位。公式PM2.5(高字节×256) 低字节或位运算Pm25((uint16t)mPkt[3]8)∣mPkt[2]Pm25((uint16t)mPkt[3]8)∣mPkt[2]答案(uintl 6_t)mPkt[2] | (uintl 6_t)(mPkt[3]8)--------------------------------------------------------------------------------------------------------------------------第 (6) 空PM10 值的位操作计算代码位置Pm10 (6);原理表 1-1mPkt[4] PM10 低字节mPkt[5] PM10 高字节公式PM10 (高字节×256) 低字节位运算Pm10((uint16t)mPkt[5]8) ∣ (uintl 6_t)mPkt[4]答案--------------------------------------------------------------------------------------------------------------------------举例说明假设传感器实际测量的值PM2.5 0x01A4十进制 420PM10 0x02B3十进制 6911. 拆分高低字节数据项高字节低字节PM2.50x010xA4PM100x020xB3假设 ID 字节1 0x12ID 字节2 0x34随意举例2. 原始数据帧十六进制3. 计算校验和8 位无符号溢出舍弃进位校验和0xA40x010xB30x020x120x34校验和0xA40x010xB30x020x120x340xA4 1640x01 10xB3 1790x02 20x12 180x34 52累加164 1 165165 179 344344 2 346346 18 364364 52 416416 大于 255取低 8 位416 - 256 160十六进制0xA0所以mPkt[8] 0xA04. 完整发送数据十六进制序列AA C0 A4 01 B3 02 12 34 A0 AB索引0 1 2 3 4 5 6 7 8 95. 接收方处理过程读到0xAA→ 可能是帧头下一字节是0xC0→ 指令正确循环 6 次读入A4, 01, B3, 02, 12, 34存到mPkt[2]~mPkt[7]累加校验mCheck 0xA40x010xB30x020x120x34 0x1A0但由于uint8_t类型实际结果 0xA0只留低 8 位读入下字节0xA0→mPkt[8]读入最后字节0xAB→mPkt[9]帧尾判断mCheck mPkt[8]→0xA0 0xA0成功6. 计算 PM2.5 和 PM10PM2.5Pm25(0x018)∣0xA4(256)164420PM10Pm10(0x028)∣0xB3(512)179691结果与传感器原值一致。PM2.5和PM10的数据其底层基本的计算逻辑建议初学者好好学习下这样有助于大家打基础下面将其详细的计算过程给大家详细的解释下。数据PM2.5 和 PM10的计算过程已知数据来自举例PM2.5 高字节 0x01PM2.5 低字节 0xA4PM10 高字节 0x02PM10 低字节 0xB3公式位运算PM2.5(高字节≪8) ∣ 低字节PM10 (高字节≪8) ∣ 低字节其中 8左移 8 位相当于乘 256|按位或相当于加法当低 8 位无重叠时以PM2.5为例 详细计算过程参考答案(1) 0xAA(2) 0xC0(3) mPkt[i2](4) mPkt[8](5)uintl 6_tmPkt[2] |uintl 6_tmPkt[3]8或其等价形式(6)uintl 6_tmPkt[4] |uintl6 _tmPkt[5]8或其等价形式常识PM2.5 和 PM10 是空气中颗粒物Particulate Matter, PM的两种常见监测指标它们的数字表示颗粒物的直径大小单位微米μm。1PM10可吸入颗粒物直径≤ 10 微米实物比较约为一根头发直径的 1/5 ~ 1/7头发直径约 50~70 μm来源扬尘、道路灰尘、花粉、霉菌孢子、部分工业粉尘等进入人体可被鼻腔、咽喉的纤毛和黏液阻挡一部分但仍能进入上呼吸道鼻、咽、喉健康影响引起咳嗽、哮喘、支气管炎、过敏性鼻炎等2PM2.5细颗粒物直径≤ 2.5 微米实物比较约为头发直径的 1/20 ~ 1/30肉眼不可见来源自然火山灰、沙尘、森林火灾人为燃煤、汽车尾气、工业废气、油烟、吸烟进入人体可穿过鼻腔、咽喉直达肺泡部分可进入血液循环健康影响短期咳嗽、胸闷、眼睛刺痛长期肺癌、心血管疾病、中风、慢性肺病试题二【说明】王工在采用某16位嵌入式CPU进行A/D采集硬件电路设计时利用8255控制器C口中的PC0输出控制信号利用PC7读入AD574的状态信号利用A口和B口读入AD574转换好的12位数据。图2-1为该A/D采集硬件系统设计的部分连接示意图。其中AD574各个管脚功能定义如表2-1所述。AD574的控制功能状态表如表2-2所示。8255控制器各个管脚及地址控制描述如表2-3所示。【问题1】在该嵌入式系统设计中AD574是工作在12位转换模式还是8位转换模式分析从题目给出的器件描述中可以看出根据AD574的A0管脚确定12位/8位模式从原理图可以看出A0接地即低电平。结合AD574的功能描述可以知道该系统设计中AD574工作在12位模式。【问题2】图2-1中245为双向缓冲器在该硬件设计中配置8255控制字时CPU需要向245进行数据输出245的A口传输给B口在获取AD采集数据时CPU需要接收245所传输过来的数据245的B口传输给A口。根据硬件设计描述DR分别为高、低电平时245双向缓冲器在A、B口之间进行数据传输的方向。分析DR高电平时A口传向B口DR低电平时B口传向A口图2-1中245为双向缓冲器在该硬件设计中配置8255控制字时CPU需要向245进行数据输出245的A口传输给B口在获取AD采集数据时CPU需要接收245所传输过来的数据245的B口传输给A口。根据硬件设计图可以看出当DR为高电平时RD信号是无效的也就是读信号无效即此时为写信号有效。在写信号有效情况下数据传输方向是从处理器向8255方向进行数据传输即从A口传输给BP。反之如果RD为低电平时此时RD信号有效也就是读信号有效既需要从外部将数据读入到CPU处理器中即从8255进行数据读取放到处理器中所以方向应该是从B口传输到A口。【问题3】在该A/D变换中如果用1/2LSB最低有效位来表示量化误差当该A/D控制器的量程范围为5V时其量化误差是多大分析由于工作在12位其范围为4096个刻度。另外考虑到采用1/2LSB作为量化误差所以误差大小即为5v/4096*20.61mv。【问题4】王工根据上述硬件设计编写对应的数据采集程序首先需要对8255进行初始化然后进行数据采集请根据注释要求补全如下X86汇编程序。初始化 8255 程序如下INIT8255: MOV DPTR, (1) ; 进行 8255 的工作模式配置MOV A, 10011010BMOVX DPTR, AMOV A, 00000001BMOVX DPTR, A数据采集程序如下ORG 0200HACQU: NOPMOV DPTR, (2) ; 通过 8255 的 C 口进行 AD574 的MOV A, (3) ; 转换控制MOVX DPTR, AMOV A, (4)MOVX DPTR, AWAIT: MOVX A, DPTRANL A, (5) ; 通过与操作判断 AD 转换是否完毕JNZ WAITMOV DPTR, (6) ; 读取 8255 A 口的 AD 转换数据MOVX A, DPTRMOV R2, A ; 有效数据存放在 R2 寄存器中MOV DPTR, (7) ; 读取 8255 B 口的 AD 转换数据MOVX A, DPTR ANL A, ______ (8)______ ; 提取A寄存器中有效的低4位数据 MOV R3, A ; 4位有效数据存放在R3寄存器中 RET分析运行数据采集程序时首先需要对8255进行初始化然后进行数据采集。在该程序中需要先进行8255的工作模式配置由原理图和8255的工作模式可知在该配置情况下必须使得8255的A1A011即工作在寻址控制器模式下同时保证8255的片选有效即必须使得A15A141A13A12A11…A20才可以所以此时需要给DPTR寄存器的地址为#C003H。在进行数据采集过程中需要先通过8255的C口进行AD574的转换控制要对C口操作即需要A1A010再考虑到片选的有效性需要给DPTR的地址是#C002H。在进行一次数据转换时需要在PCO产生一个上升沿所以要给C口输出配置为#00H和#01H。当从C口取出状态字后需要借助C口的最高位STS进行转换完毕的状态判断因此取出数据存在A寄存器后需要和#80H进行与操作来判断最高位的完成状态。当判断有有效数据时候需要分别从8255的A口和B口进行数据的获取因此需要分别配置A口和B口的地址依次为#C000H和#C001H。在进行12位数据合并时只需要通过与操作取出低4位数据和#OFH进行与操作即可。答案(1) #C003H(2) #C002H(3) #00H(4) #01H(5) #80H(6) #C000H(7) #C001H(8) #0FH试题三【说明】某嵌入式控制软件中通过采集传感器数值来计算输出控制率同时为提高数据采集的可靠性对采集数值使用三余度采集方法进行三个通道的数据采集。1、三余度数据采集及处理要求(1)如果某通道采集值在[-3.03.0]v正常范围内且与任一相邻通道间差值不大于0.5v则该通道数据满足要求(2)如果某通道釆集值超过[-3.03.0]v正常范围或者此通道采集值与其他两个通道的差值均大无0.5v则该通道数据不满足要求(3)如果三通道值均满足要求则取三通道中差值较小的两通道数据乎均值(4)如果三通道值均满足要求且相邻两数值的差值相等则取三个采集值的中间值(5)如果仅有一个通道数据不满足釆集要求取满足要求的两个通道数据平均值(6)如果大于一个通道数据不满足采集要求取安全值0v。2、对计算输出控制率的具体处理算法如下(1)如果依据采集数据计算的控制率C1与目前实际控制率C0差值不大于0.01则使用本周期计算控制率Cdft行输出控制否则使用目前实际控制率C0输出控制连续超过范围计数加1不上报传感器故障(2)如果连续3个周期计算的控制率C1与目前实际控制率C0差值大于0.01则上报传感器三级故障连续超过范围计数清零使用目前实际控制率C0输出控制如果已经连续3个周期控制率差值超过范围并已上报三级故障但第4个周期计算的控制率C1与目前实际控制率C0差值不大于0.01则清除三级故障上报并使用C1进行输出控制(3)如果累计大于等于10个周期计算的控制率C1与目前实际控制率C0差值大于0.01则上报传感器二级故障使用目前实际控制率C0输出控制(4)如果累计大于等于100个周期计算的控制率C1目前实际控制率C0差值大于0.01则上报传感器一级故障清除二级故障并切断输出控制输出安全值0(5)如果低级故障和高级故障同时发生则按高级故障上报和处理。【问题1】为了测试采集算法在不考虑测量误差的情况下根据所设计测试用例的输入填写表3-1中的1〜6空预期输出结果精度为小数点后保留两位数字。答案(1) 1.90v(2) 1.55v(3) 2.70v(4) -2.90v(5) 0v(6) 0v【问题2】白盒测试方法和黑盒测试方法是目前嵌入式软件测试常用的方法。请简述白盒测试方法与黑盒测试方法的概念。同时依据本题说明指明问题1中设计的测试用例使用了白盒测试方法还是黑盒测试方法。分析白盒测试也称结构测试、逻辑测试或基于程序的测试这种测试应了解程序的内部构造并且根据内部构造设计测试用例。黑盒测试又称功能测试、数据驱动测试或基于需求规格说明的测试这种测试不必了解被测对象的内容情况而依靠需求规格说明中的功能来设计测试用例。问题1中设计的测试用例使用了黑盒测试方法。【问题3】为了测试控制率计算算法在不考虑测量误差的情况下请完善所设计的测试用例填写表3-2中的空1〜6。答案(1) 1.454(2) 2(3) 9到98都可以(4) 二级故障(5) 0(6) 一级故障试题四【说明】某公司承接了一个数据处理模块的项目由沈工负责模块的方案设计沈工的设计方案如图4-1所示。该数据处理模块以PowerPC处理器为核心设计了存储器、以太网、温度传感器、调试接口等功能电路。处理器外接FLASH存储器用于存储上电初始化程序和应用程序。处理器通过I2C接口连接测温电路监控模块的工作温度。以太网、串口、调试离散量等用于软件调试和状态显示。测温电路选用ADT7461AR芯片用于测试模块温度。ADT7461AR是一个双通道数字温度计工作电压3v至5v具有低/超温报警功能采用I2C接口实现主机对远程/本地温度数据的采集f采集数据存储在高/低两个数据寄存器中每个寄存器为16位高寄存器表示整数值低寄存器表示小数值。存储模块采用某公司的FLASH存储芯片。支持编程、擦除、复位等操作命令。该FLASH芯片的常用命令序列如表4-1所示。表中的地址和数据皆为16进制数。【问题1】ADT7461AR芯片支持两种测温模式其中第0种模式为二进制模式用0表示0度测温范围为0℃〜127℃第二种模式为偏移二进制模式用64表示0度测温范围为-55℃〜150℃温度数据转换关系如表4-2所示。请在1〜4处写出对应温度的二进制数。【问题2】沈工用C语言实现对FLASH的操作需按照表4-1中定义的命令序列顺序执行即可。仔细阅读下列代码请在1〜4处将对应的C语言代码补全。#define FLASH_BASE_ADDRESS xxxxxxxx 此处代码略/* 定义向 FLASH 空间写一个命令的宏 */#define FLASH_WRITE_BYTE(addr, data) xxxxxxxx 此处代码略/* Reset Flash */void ResetFlash(void){FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS, 0xF0);return;}/* 对 FLASH 的擦除是按扇区进行的SectorErase 函数每次可擦除一个扇区。假设某扇区的偏移地址为 offset_addr下面 SectorErase 函数作为擦除该扇区的命令序列 */void SectorErase(int offset_addr){FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS 0x555, 0xAA);FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS (1), 0x55);FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS 0x555, (2));FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS 0x5AA, 0xAA); // 原图中为 0x5A根据常见 JEDEC 标准推测应补全但保持原样 0x5AFLASH_WRITE_BYTE(FLASH_BASE_ADDRESS 0x2AA, 0x55);FLASH_WRITE_BYTE(FLASH_BASE_ADDRESS (3), (4));return;}分析本题中采用的FLASH芯片为NORFLASHNORFLASH是很常见的一种存储芯片数据掉电不会丢失。NORFLASH支持ExecuteOnChip即程序可以直接在FLASH片内执行这意味着存储在NORFLASH上的程序不需要复制到RAM就可以直接运行。因此在嵌入式系统中NORFLASH很适合作为启动程序的存储介质。NORFLASH的读取和RAM很类似只要能够提供数据的地址数据总线就能够正确的给出数据但不可以直接进行写操作。对NORFLASH的写操作需要遵循特定的命令序列最终由芯片内部的控制单元完成写操作。FLASH一般都分为很多个SECTOR每个SECTOR包括一定数量的存储单元对有些大容量的FLASH还分为不同的BANK每个BANK包括一定数目的SECTOR。FLASH的擦除操作一般都是以SECTOR、BANK或是整片FLASH为单位的。在对FLASH进行写操作的时候每个位可以通过编程由1变为0但不可以由0修改为1。为了保证写操作的正确性在执行写操作前都要执行擦除操作擦除操作会把FLASH的一个SECTOR、一个BANK或是整片FLASH的值全修改为0xFF这样写操作就可以正确完成了。Flash芯片一般都支持编程、擦除、复位等操作命令命令序列可参考芯片厂家提供的用户手册。本项目中根据芯片手册提供的常用命令序列表可知SECTOR擦除操作共需要6个周期的总线写操作完成命令序列如下将0xAA写到FLASH芯片地址0x555将0x55写到FLASH芯片地址0x2AA将0x80写到FLASH芯片地址0x555将0xAA写到FLASH芯片地址0x555将0x55写到FLASH芯片地址0x2AA将0x30写到要擦除的SECTOR对应的地址。答案(1) 0x2AA(2) 0x80(3) offset_addr(4) 0x30【问题3】该嵌入式系统对处理的性能要求较高沈工在完成软件设计后需要对每一个函数的执行性能进行测试检测其是否满足系统设计的要求。沈工通过PowerPC处理器内部的高精度时钟寄存器TimeBase进行计时该寄存器由高低两个32位的寄存器组成根据总线频率自动递增当低32位寄存器递增到0xFFFFFFFF时向高32位寄存器进位。计数值可以换算成时间值精确到微秒级。在功能函数functkm1()的执行体前后进行时间统计最后计算出该函数的执行时间值请在1〜2处将对应的C语言代码补全。struct timeBase{unsigned int upper;unsigned int lower;};void function1(void){struct timeBase tb0, tb1, tb2;long value;/* 获取 TimeBase 寄存器中的计数值 */TimeBaseGet(tb0.upper, tb0.lower);/* 函数执行体... *//* 再次获取 TimeBase 寄存器中的计数值 */TimeBaseGet(tb1.upper, tb1.lower);tb2.upper tb1.upper - tb0.upper;/* 当低 32 位计数值未反转则直接进行计算否则需借用高位进行计算 */if ( tb1.lower tb0.lower ){tb2.lower (1);}else{tb2.upper - 1;tb2.lower (2);}/* 根据总线频率将时钟节拍转换为时间值 */value CountToUs(tb2);printf(%s cost time %dus.\n, __function__, value);}分析当tb1的低32位大于等于tb0的低32位时tb2的高位等于tb1的高位与tb0的高位的差值tb2的低位等于tb1的低位与tb0的低位的差值。当tb1的低32位小于tb0的低32位时则需借用高位进行计算。tb2的高位等于tb1高位与tb0高位的差值再减1tb2的低位等于0xFFFFFFFF-tb0的低位tb1的低位再加1。答案(1) tb1.lower-tb0.lower(2) 0xFFFFFFFF-tb0.lowertb1.lower1试题五【说明】【程序1】是关于条件编译的一段程序示例【程序2】是一段switch语句应用示例。C语言要求switch之后圆括弧内的“表达式”类型必须是整型或字符型。该程序代码中a与x的对应关系如表5-1所示。【程序3】是冒泡排序算法的实现。假设有N个数据存放在数组aa中用冒泡排序将这N个数从小到大排序。首先在aa[0]到aa[N..1]的范围内依次比较两个相邻元素的值若aa[j]aa[j1]则交换aa[j]与aa[j1]j的值取012…N-2经过这样一趟冒泡就把这N个数中最大的数放到aa[N-1]中。接下来对aa[0]到aa[N-2]中的数再进行一趟冒泡这样就将该范围内的最大值换到aa[N-2]中。依次进行下去最多只要进行N-1趟冒泡就可完成排序。如果在某趟冒泡过程中没有交换相邻的值则说明排序已完成可以提前结束处理。【C程序代码1】#include stdio.h#define _DEF_Xmain(){int x;#ifndef _DEF_Xx 1;#elsex 2;#endifprintf(x%d\n, x);}【C程序代码2】{case 0:case 1:case 2:if ( a 2 ) x 1;else _(1)_;break;case 3:_(2)_;break;case 4:_(3)_;break;default:printf(a is error\r\n);}【C程序代码3】#include stdio.h#define N 8main(){int i, j, aa[N], temp, swap;clrscr();for(i0; iN; i)scanf(%d, (4) );for(i0; iN; i){swap 0;for(j0; j(5); j){if(aa[j] aa[j1]){swap 1;temp aa[j];aa[j] aa[j1];aa[j1] temp;}}}}【问题1】(1)什么是c语言的条件编译(2)请解释#ifndef的作用。(3)分析【C程序代码1】写出该段执行后的输出结果。分析(1) 条件编译C语言中提供控制编译器流程的语句。或C源程序中希望对其中一部分内容只是在满足一定条件时才进行编译形成目标代码这种对一部分内容指定编译的条件称为条件编译。(2) #ifndef的作用#ifndef 是 C/C 预处理器中的一个条件编译指令全称是 if not defined如果没有定义。如果#ifndef后面的“宏名”未定义则编译其体内的程序段否则编译#else部分的程序段如果没有#else部分则当“宏名”己定义时直接跳过#endif。(3) x2【问题2】完成【C程序代码2】中的1〜3空将答案写到相应的位置。答案(1)x3(2)x1(3)x2【问题3】完成【C程序代码3】中的4〜6空将答案写到相应的位置。答案(4) aa[i](5) N-i-1(6) !swap或swap0