题型:单选、多选、填空、简答、编程
选择题
一共15道,10单选,5多选,相对简单,只是模糊记得如下知识点:
1、求a的值
经过表达式a = 5 ? 0 : 1的运算,变量a的最终值是 0
boolean虚拟机取值时候是掩码去掉前七位之后取末尾判断,0是false,1是true,而5对应的是00001001,所以这块表示的是1,也就是true,所以对应的是三目运算里面的结果是 0。
2、数组int a[3][4]中的a[2][1]用其他形式表示:
*(*(a+2)+1)
*(a[2] + 1)
int *p = &a[0][0] ;//p[9], 表示 a[2][1];
3、在soc中常常用做对外设寄存器配置总线的是:i2c,spi
4、哈佛结构和冯诺依曼结构的区别:
要理解哈弗结构和冯诺依曼结构的区别,首先要知道我们在编写程序的时候其实可以对程序的代码划分为两个部分,一部分是程序编写完成后就不再需要对其进行修改了的(也就是逻辑代码部分)另一部分就是在程序编写完毕后其内容会随着程序的运行而不断变化的部分(也就是定义变量)。而哈佛结构和冯诺依曼结构就是对于这个两部分代码的存储方式的区别。
哈佛结构(Harvard architecture)是一种将程序指令储存和数据储存分开的存储器结构。
中央处理器首先到程序指令储存器中读取程序指令内容,解码后得到数据地址,再到相应的数据储存器中读取数据,并进行下一步的操作(通常是执行)。程序指令储存和数据储存分开,数据和指令的储存可以同时进行,可以使指令和数据有不同的数据宽度。
哈佛结构的微处理器通常具有较高的执行效率。其程序指令和数据指令分开组织和储存的,执行时可以预先读取下一条指令。
大多数ARM、DSP是哈佛结构。
冯.诺伊曼结构(von Neumann architecture)是一种将程序指令存储器和数据存储器合并在一起的存储器结构。
大多数CPU和GPU是冯诺依曼结构的。
冯诺依曼结构则是将逻辑代码段和变量统一都存储在内存当中,他们之间一般是按照代码的执行顺序依次存储。这样就会导致一个问题,如果当程序出现BUG的时候,由于程序没有对逻辑代码段的读写限定,因此,他将拥有和普通变量一样的读写操作权限。于是就会很容易的死机,一旦他的逻辑执行出现一点该变就会出现非常严重的错误。但是,冯诺依曼结构的好处是可以充分利用有限的内存空间,并且会使CPU对程序的执行十分的方便,不用来回跑。
5、联合体和结构体
结构体(struct)各成员各自拥有自己的内存,各自使用互不干涉,同时存在的,遵循内存对齐原则。一个struct变量的总长度等于所有成员的长度之和。
而联合体(union)各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。
#include<stdio.h>
//结构体
struct u //u表示结构体类型名
{
char a; //a表示结构体成员名
int b;
short c;
}U1;
//U1表示结构体变量名
//访问该结构体内部成员时可以采用U1.a=1;其中"点"表示结构体成员运算符
//联合体
union u1 //u1表示联合体类型名
{
char a; //a表示联合体成员名
int b;
short c;
}U2;
//U2表示联合体变量名
//访问该联合体内部成员时可以采用U2.a=1;其中"点"表示联合体成员运算符
//主函数
int main(){
printf("%d\n",sizeof(U1));
printf("%d\n",sizeof(U2));
return 0;
}
/*程序运行结果是:
12
4*/
填空题4道
1、大小端问题
A=0x12345678存入地址1000H~10003H中,
小端模式:1000H=78 1001H=56 1002H=34 1003H=12
大端模式:1000H=12 1001H=34 1002H=56 1003H=78
2、宏定义计算问题
#define PRODUCT (x) (x*x)
int main()
{
int a,b=3;
a=PRODUCT(b+2);
}
求a值:
b+2*b+2=3+2*3+2=11
3、有符号和无符号混合三目运算问题
void foo(void)
{
unsigned int a = 6;
int b = -20;
int c;
(a+b > 6) ? (c=1) : (c=0);
}
这个问题测试C语言中的整数自动转换原则,这无符号整型问题的答案是c=1。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果c=1。
简答题3道
1、简述任务/线程之间的同步方式
互斥锁:锁机制是同一时刻只允许一个线程执行一个关键部分的代码。
条件变量:条件变量是利用线程间共享全局变量进行同步的一种机制。条件变量上的基本操作有:触发条件(当条件变为 true 时),等待条件,挂起线程直到其他线程触发条件。
信号量:为控制一个具有有限数量用户资源而设计。
事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。
2、简述可执行程序的内存布局
3、设计机制保证锁可以按照先到先得的方式被任务获取,并且占用内存空间最小(题目没有说全,记不清,考察操作系统和队列的应用)
编程题2道
1、比较输入字符串s1和s2前n个字符,忽略大小写,如果字符串s1和s2相同则返回0,不同则返回第一个不同字符的差值。
tolower是一种函数,功能是把字母字符转换成小写,非字母字符不做出处理。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int strcmpx(const char *s1, const char *s2, unsigned int n)
{
int c1, c2;
do {
c1 = tolower(*s1++);
c2 = tolower(*s2++);
} while((--n > 0) && c1 == c2 && c1 != 0);
return c1 - c2;
}
int main(void)
{
int n = 4;
char str3[] = "ABCf";
char str4[] = "abcd";
printf("strcmpx(str3, str4, n) = %d", strcmpx(str3, str4, n));
return 0;
}
2、N X N数组,输出行中最小,列中最大的数的位置,比如:
1 2 3
4 5 6
7 8 9
输出:row=2,col=0
分析:
在矩阵中,一个数在所在行中是最大值,在所在列中是最小值,则被称为鞍点。
//C语言输出矩阵马鞍点
#include<stdio.h>
void Input_Matrix(int m,int n,int a[100][100]) //输入矩阵元素
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
scanf("%d", &a[i][j]);
}
}
}
void Output_Matrix(int m, int n, int a[100][100]) //输出矩阵元素
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%-5d", a[i][j]);
}
printf("\n");
}
}
void Matrix_Mn(int m, int n, int a[100][100]) //输出矩阵马鞍点
{
int flag = 0;
int min, max, k, l;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
min = a[i][j];
for (k = 0; k < m; k++)
{
if (min < a[i][k])
break;
}
if (k == m)
{
max = a[i][j];
for (l = 0; l < n; l++)
{
if (max > a[l][j])
break;
}
if (l == n)
{
printf("%-5d%-5d\n", i, j);
printf("矩阵元素为:a[%d][%d]=%d\n",i,j, a[i][j]);
flag = 1;
}
}
}
}
if (flag == 0)
{
printf("该矩阵没有马鞍点!\n");
}
}
int main(void)
{
int m, n;
int a[100][100];
for (;;)
{
printf("请输入矩阵的行数和列数:\n");
scanf("%d %d", &n, &m);
printf("请输入矩阵中的元素:\n");
Input_Matrix(m, n, a);
printf("矩阵输出为:\n");
Output_Matrix(m, n, a);
printf("马鞍点输出(该点所在的行数和列数):\n");
Matrix_Mn(m, n, a);
}
return 0;
}
题目要求是一个数在所在行中是最小值,在所在列中是最大值,不确定还能不能称为鞍点,但是算法思路相似的。
思路:
- 先找第i行上最小的元素t,以及所在列minj
- 判断t是否为第minj列的最大值,如果不是则在minj列中继续寻找最大值并输出,如果是则输出
#include <stdio.h>
#define N 3
int a[N][N]={1,2,3,4,5,6,7,8,9};
int main()
{
int i,j,t,minj;
for(i=0;i<N;i++)
{
t=a[i][0];
minj=0;
for(j=1;j<N;j++)//行上最小
{
if(a[i][j]<t)
{
t=a[i][j];
minj=j;//找到了行上最小的数所在的列
}
}
int k;
for(k=0;k<N;k++)
if(a[k][minj]>t)//判断是否列上最大
break;
if(k<N) continue;//接着查找下一行
printf("所求点是:a[%d][%d]:%d\n",i,minj,t);
}
return 0;
}
相关基础知识:
break:
(1).结束当前整个循环,执行当前循环下边的语句。忽略循环体中任何其它语句和循环条件测试。
(2).只能跳出一层循环,如果你的循环是嵌套循环,那么你需要按照你嵌套的层次,逐步使用break来跳出。
continue:
(1).终止本次循环的执行,即跳过当前这次循环中continue语句后尚未执行的语句,接着进行下一次循环条件的判断。
(2).结束当前循环,进行下一次的循环判断。
(3).终止当前的循环过程,但他并不跳出循环,而是继续往下判断循环条件执行语句.他只能结束循环中的一次过程,但不能终止循环继续进行。