嵌入式题目
1、strcmp函数的用法
头文件为string.h,函数原型为:
extern int strcmp(const char *s1,const char *s2);
设这两个字符串为s1,s2,
int strcmp(const char *string1, const char *string2) { for (; *string1 == *string2; string1++, string2++) { if (*string2 == '\0') { return 0; } } return (*(unsigned char *)string1) < (*(unsigned char *)string2) ? -1:+1; }
另外一种方式实现:
int strcmp(const char *string1, const char *string2) { int ret; while (*string1 == *string2) { assert((string1 != NULL) && (string2 != NULL)); if (*string1 == '\0') return 0; string1++; string2++; } ret = *string1 - *string2; if (ret > 0) return 1; else return 0; }
2、strcpy函数的用法
strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*,函数原型为:
char *strcpy(char* dest, const char *src);
char* strcpy(char *string1, const char *string2) { char *str = string1; assert((string1 != NULL) && (string2 != NULL)); while (*string2 != '\0') { *string1 = *string2; string1++; string2++; } *string1 = '\0'; return str; }
3、编程实现Socke?
socket相当于进行网络通信两端的插座,只要对方的socket和自己的socket有通信连接,双方就可以进行通信
服务端程序编写:
1)调用serversocket(int port)创建一个服务器端的套接字,并绑定到指定的端口号;
2)调用accept(),监听连接请求,有连接请求,则接收连接,返回通信套接字;
3)调用socket的getOutStream()和getinputStrem()获取输出流和输入流,开始网络的输入与输出;
4)关闭通信套接字socket.close()。
客户端的程序编写:
1)调用socket创建一个套接字,并连接到服务器;
2)调用socket类的getoutputstream()和getinputstream获取输出流和输入流,开始网络的数据发送和接收;
3)关闭通信套接字socket.close()。
4、C++中explict关键词的作用?
C++提供了关键词explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
5、写一个函数实现字符串压缩功能,例如”abbcccaaaa“能被压缩成”a1b2c3a4“?
6、共模电路和差模电路的结构?共模信号和差模信号的区别?
7、三相四线电力矢量图?有用功率的计算公式理解?
8、有一副扑克牌,共54张,大小王2张,剩余的花色四种:方块、梅花、红桃、黑心。
(1)用熟悉的语言去描述这副扑克牌;
(2)扑克牌有缺失,写出找出缺失扑克牌的算法(程序方框图)
9、Linux线程与进程的区别?
1)线程与进程的定义:
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,行的基本单位。线程自己基本不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器、一组寄存器和栈),但是它可与同属一个进程的其他线程共享进程所拥有的全部资源,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的单元。
2)线程与进程的关系:
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。相对于进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
3)线程与进程的区别:
主要差别在于它们是不同的操作系统资源管理方式。进程拥有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响,而线程只是一个进程中的不同执行路径。线程拥有自己的堆栈和局部变量,但是线程之间没有独立的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比线程的的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
总结:
- 一个程序至少有一个进程,一个进程至少有一个线程
- 线程的划分尺度小于进程,使得多线程的程序并发性高
- 进程在执行的过程中拥有独立的内存单元,而多个线程共享内存,从而极大提高了程序的运行效率
- 线程在执行过程中和进程是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
- 从逻辑角度的意义看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。
4)线程与进程的优缺点:
线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
10、Linux进程运行状态图?
图:Linux进程运行状态
- 运行状态(TASK_RUNNING):当进程正在被CPU执行,或已经准备就绪随时可以由调度程序执行,则该进程处于运行状态(running)
- 可中断睡眠状态(TASK_INTERRUPTIBLE):进程收到一个信号,都可以唤醒进程转换到就绪状态(运行状态)
- 不可中断睡眠状态(TASK_UNINTERRUPTIBLE):处于该状态只有被使用wake_up()函数唤醒才能转换到可运行的就绪状态
- 暂停状态(TASK_STOPPED):进程收到SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态
- 僵死状态(TASK_ZOMBIE):进程已经停止运行,但其父进程还没有询问其状态时,则进程处于僵死状态
11、下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论以下这段代码。
__interrupt double compute_area(double radius) { double area = PI * radius *radius; printf("nArea = %f", area); return area; }
答:
1)ISR不能返回一个值;
2)ISR不能传递形参;
3)浮点一般都是不可重入的;
4)printf函数有重入和性能上的问题。
12、用变量a给出下面的定义
a) 一个整型数(An integer)
b) 一个指向整型数的指针(A pointer to an integer)
c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer
to an integer)
d) 一个有10个整型数的数组(An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to
integers)
f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a fu
nction that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型
数( An array of ten pointers to functions that take an integer argument and r
eturn an integer )
答:
a) int a;
b) int *a;
c) int **a;
d) int a[10];
e) int *a[10];
f) int (*a)[10];
g) int (*a)(int b)
h) int (*a[10])(int b)
12、 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
13、关键字static的作用是什么?
C语言中,static关键词有三个作用:
1)在函数体内,一个被声明为静态的变量,函数被调用过程中维持其值不变;
2)在模块内(但在函数体外),一个被声明为静态的变量,能被模块内的所用函数进行调用;
3)在模块内,一个被声明为为静态的函数只可被这一模块内的其他函数进行调用。静态函数被声明模块内的本地范围内使用。
14、关键词const是什么含义?
1)只读
2)告诉用户这个参数的应用目的
3)给优化器一些附加的信息,产生更紧凑的代码
4)防止不希望改变的参数被无意的代码修改
下面的声明是什么意思?
a)const int a; b)int const a; c)const int *a; d)int * const a; e)int const * a const;
a)a是一个整形常量;
b)a是一个整形常量;
c)a指向一个整形常量;
d)a是一个常量指针,指向一个整形数;
e)a是一个指向整形常量的常指针。
15、volatile关键字有什么含义?并给出三个不同的例子
定义为volatile的变量说明这个变量可能会被意想不到地改变,编译器不会去假设这个值。优化器在用到这个变量时必须每次小心地读取这个变量的值,而不是使用保存在寄存器里面备份的值。
下面是volatile变量的几个例子:
1)并行设备的硬件寄存器(如:状态寄存器);
2)一个中断服务子程序中会访问到的非自动变量;
3)多线程应用中被几个任务共享的变量。
16、嵌入式系统总是要用户对变量或寄存器进行位操作,给定一个整形变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit3,在以上两个操作中,要保持其他位不变
#define BIT3 (0x1<<3) void set_bit3(void) { a|=BIT3; } void clear_bit3(void) { a &=~BIT3; }
17、嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求
设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写
代码去完成这一任务。
/*第一种*/ int *ptr; ptr = (int *)0x67a9; *ptr = 0xaa55; /*第二种*/ *(int * const)(0x67a9) = 0xaa55;