1.
a)5。
b)存在风险,因为 c=c++%5; 这个表达式对 c 有两次修改,行为未定义,c 的值不确定。
2.
a)a=2,b=100,c=2,d=6,e=5
b)stack:d;data:a;bss:b,c,e
BSS段: BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS 是英文 Block Started by Symbol 的简称。 BSS 段属于静态内存分配。
数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用 free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧 “{}”中定义的变量(但不包括 static 声明的变量, static 意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
3.
a)ISR不能返回一个值
b)ISR不能传递参数
c)printf函数有重入和性能上的问题。
可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。
4.
a)
在变量 a 的定义前加上 volatile 关键字可以防止编译器的类似优化。
volatile 变量可能用于如下几种情况:
① 并行设备的硬件寄存器(如:状态寄存器,例中的代码属于此类);
② 一个中断服务子程序中会访问到的非自动变量(也就是全局变量);
③ 多线程应用中被几个任务共享的变量。
b)
1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
c)
一个指向常整型数的指针
一个指向整型数的常指针
一个指向常整型数的常指针
5.
a)little endian:78 56 34 12(低->高),big endian:12 34 56 78(低->高)
big endian 是指低地址存放最高有效字节(MSB),而 little endian 则是低地址存放最低有效字节(LSB)。
我们一般将 endian 翻译成“字节序”,将 big endian 和 little endian 称作“大尾”和“小尾”。
b)如果形参个数少于或等于4,则形参由 R0、R1、R2、R3 四个寄存器进行传递;若形参个数大于 4,大于 4 的部分必须通过堆栈进行传递。
c)所谓中断应该是指外部硬件产生的一个电信号,从 cpu 的中断引脚进入,打断 cpu 当前的运行;
所谓异常,是指软件运行中发生了一些必须作出处理的事件,cpu 自动产生一个陷入来打断当前运行,转入异常处理流程。
6. 待解答
7.
a)高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象叫做优先级反转。此时高优先级任务和中等优先级任务之间没有任何共享资源但执行顺序却发生了倒置,这种情况称为优先级反转,而高优先级任务因为等待低优先级任务释放资源而阻塞的情况则不称为优先级反转。
b)优先级继承策略(Priority inheritance): 继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢复初始优先级。在上述例子中体现为当高优先级任务需要等待低优先级任务释放资源而阻塞时,就将低优先级任务的优先级升为高优先级任务的优先级,当它退出临界区后就将其优先级恢复为初始优先级。
优先级天花板策略(Priority ceilings): 优先级天花板是指将申请(占有)某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级.(这个优先级称为该资源的优先级天花板)。在上述例子中体现为当低优先级任务申请占有某资源时就将这个低优先级任务的优先级升为能访问该资源的所有任务中最高优先级任务的优先级。
优先级继承策略对任务执行流程的影响相对较小,因为只有当高优先级任务申请已被低优先级任务占有的临界资源这一事实发生时,才抬升低优先级任务的优先级。而天花板策略是谁占有就直接升到最高。
8. 0
9. C
10. 4,12,44
11.
a)有问题,没有结束符\0。
b)不可用,局部变量。
12.
a="cde" 使得 a 指向静态分配区的 cde ,然后用 free 的话会导致内存出错。
13.
cp linux-2.4-20.tz /usr/src
tar xvf linux-2.4-20.tz
cd linux-2.4-20
make memuconfig
make dep;
make bzImage;
make modules;
make modules_install;
make install
14.
a)程序崩溃。因为 GetMemory 并不能传递动态内存,Test 函数中的 str 一直都是 NULL。strcpy(str, "hello world"); 将使程序崩溃。
b)可能是乱码。因为 GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。
c)能够输出 hello,内存泄漏。
d)篡改动态内存区的内容,后果难以预料,非常危险。因为 free(str); 之后 str 成为野指针,if(str != NULL) 语句不起作用。
15.
所谓"程序库",简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分,来完成执行功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。
程序库可分三类:静态库,共享库和动态加载库。
静态库,是在执行程序运行前就已经加入到执行码中,在物理上成为执行程序的一部分;共享库,是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。动态加载库,其实并不是一种真正的库类型,应该是一种库的使用技术,应用程序可以在运行过程中随时加载和使用库。
16. 待解答
17. 待解答
18.
嵌入式系统的硬件系统
> 嵌入式处理器
> 存储器
> I/O系统
嵌入式系统的软件系统
> 操作系统
> 应用软件
19.
l /bin 该目录中存放 Linux 的常用命令。
l /boot 该目录下存放的都是系统启动时要用到的程序,当用 lilo 引导 Linux 时,会用到这里的一些信息 grub 的配置文件也是放在这里的。
l /dev 该目录包含 Linux 系统中使用的所有外部设备,它实际上是访问这些外部设备的端口,你可以访问这些外部设备,与访问一个文件或一个目录没有区别。
l /etc 该目录存放了系统管理时要用到的各种配置文件和子目录,例如网络配置文件、文件系统、X 系统配置文件、设备配置信息、设置用户信息等。
l /sbin 该目录用来存放系统管理员的系统管理程序。
l /home 如果建立一个名为 “xx” 的用户,那么在 /home 目录下就有一个对应的 “/home/xx”路径,用来存放该用户的主目录。
l /lib 该目录用来存放系统动态连接共享库,几乎所有的应用程序都会用到该目录下的共享库。
l /lost+found 该目录在大多数情况下都是空的。但当突然停电、或者非正常关机后,有些文件就临时存放在这里。
l /mnt 该目录在一般情况下也是空的,你可以临时将别的文件系统挂在该目录下。
l /proc 可以在该目录下获取系统信息,这些信息是在内存中由系统自己产生的。
l /root 如果你是以超级用户的身份登录的,这个就是超级用户的主目录。
l /tmp 用来存放不同程序执行时产生的临时文件。
l /var 这是系统在工作时预先设置的工作目录,如各种服务的日志文件和收发的邮件等。
l /usr 最复杂和最重要的目录之一,要用到的应用程序和文件几乎都存放在这个目录下面。其中包括
/usr/X11R6
/usr/bin
/usr/sbin
/usr/doc
/usr/include
/usr/lib
/usr/man
/usr/src
/usr/local/bin
/usr/local/lib
20. 待解答
21.
Exemplary description of memory allocation map for TMS320VC6416
MEMORY
{
vecs: o = 00000400h l = 200h
PRAM: o = 00000e00h l = 20000h
DRAM: o = 00020e00h l = 000df200h
EMIFACE0: o = 80000000h l = 10000000h
EMIFACE1: o = 90000000h l = 10000000h
}
SECTIONS
{
"vectors" > vecs
.text > PRAM
.cinit > DRAM
.stack > DRAM
.bss > DRAM
"ExtMem" > EMIFACE0
}
22. 待解答
23.
C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;
改后答案依次为9,10,10,11
24.
(1)25 (2)4 (3) 4 (4)4 (5)4
char(1 Byte),short(2Byte)→int(2 Byte)→unsigned(2 Byte)→long(4 Byte)→double(8 Byte)
25.
static long getelem(long n,long k) //利用递归计算杨辉三角的第row行,col列的元素
{
if (k==0||n==k) return 1;
else return getelem(n-1,k-1)+getelem(n-1,k);
}
void output(long n) //输出杨辉三角,n为杨辉三角的阶数
{
int row,col;
for(row=0;row<=n;row++)
{
for(col=0;col<=row;col++)
cout<<getelem(row,col)<<" ";
cout<<endl;
}
}
26.
int isPrimeNum(int num)
{
int i, flag = 1;
if(num <= 3)
return 1;
if(!(num%2))
return 0;
for(i = 2; i < num/2; i++)
{
if(!(num%i))
{
flag = 0;
break;
}
}
return flag;
}
27.
struct Node
{
int value;
struct Node *next;
};
int main()
{
int total = 30, out_index = 9, out_counter = 0,temp_counter = 0,left_counter = 15;
int i;
struct Node *list,*head,*temp;
temp = (struct Node*)malloc(1);
temp->value = 1;
temp->next = NULL;
list = head = temp;
for(i = 1; i < 30 ; i++)
{
temp = (struct Node*)malloc(1);
temp->value = 1;
temp->next = NULL;
list->next = temp;
list = list->next;
}
list->next = head;
list = head;
while(1)
{
if(out_counter == total - left_counter)
break;
if(temp_counter == out_index - 1)
{
if(list->value == 1)
{
list->value = 0;
out_counter++;
temp_counter = 0;
struct Node *t = head;
for(i = 0; i < total; i++)
{
printf("%-d ",t->value);
t = t->next;
}
printf("\n");
}
}
else
{
temp_counter += list->value;
}
list = list->next;
}
getchar();
return 0;
}
28.
int fibonacci(int n)
{
if(n == 1 || n == 2)
return n;
else if(n > 2)
return fibonacci(n-1)+fibonacci(n-2);
}
29. 防止该头文件被重复引用
30.
对于 #include <filename.h>,编译器从标准库路径开始搜索filename.h,对于#include “filename.h”,编译器从用户的工作路径开始搜索 filename.h。
31. #define SECONDS_PER_YEAR (365*24*60*60)UL //无符号整形
32. #define MIN(A,B) ((A>B)?(B):(A))
33.
int main(void)
{
int array[8] = {3,7,19,25,35,48,59,88};
int start = 0, count = 8, end, middle, obj = 48, isFound = 0;
end = count-1;
while(end > start)
{
middle = (end + start)/2;
if(array[middle] == obj)
{
isFound = 1;
break;
}
else if(array[middle] < obj)
{
start = middle + 1;
}
else
{
end = middle - 1;
}
}
if(isFound)
printf("\n==============Num is Found\n");
else
printf("\n==============Num is Not Found\n");
return 0;
}
34.
int main(void)
{
unsigned short unsTest = 328;
unsigned short unsTest2 = unsTest;
unsigned short bit = 0x01;
int i;
for(i = 0; i < 16; i++)
{
if(unsTest & bit)
unsTest2 &= ~bit;
else
unsTest2 |= bit;
bit = bit << 1;
}
printf("\nunsTest = %d, unsTest2 = %d\n",unsTest,unsTest2);
return 0;
}
35.
int charToNum(char *c,int len)
{
int num = 0;
int i;
for(i = 0; i < len; i++)
{
num = num*10 + (int)(*c - '0');
c++;
}
return num;
}
36.
char *strcpy(char *strDest, const char *strSrc)
{
char *start = strDest;
while((*strDest++ = *strSrc++) != '\0');
strDest = start;
return start;
}
*p++,由于++和*同优先级,结合方向自右而左,等价于*(p++)
运算符优先级:( ) [ ] . → 单目运算符 → 双目运算符(算术→移位→关系→逻辑→赋值→条件)→ 三目运算符
37.
int main()
{
int i,j;
for(i = 0; i < 5; i++)
{
for(j = 0; j < 5; j++)
{
if((i == 0) || (i == 4) || (j == 0) || (j == 4))
printf("%d ", 1);
else if(i == j && i== 2)
printf("%d ", 3);
else
printf("%d ", 2);
}
printf("\n");
}
}
38.
int outIndex(int array[], int countIndex, int arrayCount)
{
int outIndex = countIndex - 1;
int outCount = 0;
int leftCount = arrayCount;
int index = 0;
int i;
while(1)
{
if(leftCount == 1)
break;
if(outCount == outIndex)
{
if(array[index] != 0)
{
array[index] = 0;
leftCount--;
outCount = 0 ;
printf("\n\n");
for(i = 0; i < 17; i++)
printf("%d ",array[i]);
printf("\n\n");
}
}
else
outCount += array[index];
index++;
if(index == 17)
index = 0;
}
for(i = 0; i < arrayCount; i++)
if(array[i] == 1)
{
index = i;
break;
}
printf("\n\n+++++++++++index = %d\n\n",index);
return index;
}
39.
struct NODE
{
int value;
struct NODE *leftChild;
struct NODE *rightChild;
};
typedef struct NODE Node;
void traversal(Node *tree)
{
if(tree == NULL)
return ;
traversal(tree->leftChild);
printf(" %d",tree->value);
traversal(tree->rightChild);
}
40.
struct NODE
{
int value;
struct NODE*next;
};
typedef struct NODE Node;
int find(Node *link, int num)
{
int isFound = 0;
while(link->value != 0)
{
if(link->value == num)
{
isFound = 1;
break;
}
else
link = link->next;
}
return isFound;
}
void deleteNode(Node *link, int num)
{
if(find(link,num))
{
Node *temp;
while(link->value != 0)
{
if(link->next->value == num)
{
temp = link->next;
link->next = temp->next;
free(temp);
break;
}
else
link = link->next;
}
}
}
41.
能,局部会屏蔽全局。局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
42.
可以用引用头文件的方式,也可以用extern关键字。如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个函数名写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
43.
可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
44.
1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些函数所在 DLL 的导入库,导入库向系统提供了载入 DLL 时所需的信息及 DLL 函数定位。
2.运行时动态链接(run-time dynamic linking),运行时可以通过 LoadLibrary 或LoadLibraryEx 函数载入 DLL。DLL 载入后,模块可以通过调用 GetProcAddress 获取 DLL 函数的出口地址,然后就可以通过返回的函数指针调用 DLL 函数了。如此即可避免导入库文件了。
45. 60。
运算符优先级:( ) [ ] . → 单目运算符 → 双目运算符(算术→移位→关系→逻辑→赋值→条件)→ 三目运算符
运算符结合性:多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。
46.
引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。
47.
static 全局变量与普通的全局变量有什么区别:static 全局变量只初使化一次,防止在其他文件单元中被引用;
static 局部变量和普通局部变量有什么区别:static 局部变量只被初始化一次,下一次依据上一次结果值;
static 函数与普通函数有什么区别:static 函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。
48.
1>封装:将客观事物抽象成类,每个类对自身的数据和方法实保护(private、protected、public)
2>继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。
3>多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
49.
static 关键字至少有下列 n 个作用:
1) 函数体内 static 变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
2) 在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
3) 在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
4) 在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
5) 在类中的 static 成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的 static 成员变量。
const 关键字至少有下列 n 个作用:
1) 欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
2) 对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;
3) 在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
4) 对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;
5) 对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。例如:const classA operator*(const classA& a1,const classA& a2);
operator* 的返回结果必须是一个 const 对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。
50.
都是在堆(heap)上进行动态的内存操作。用 malloc 函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor。New 和 delete 是操作符,malloc 和 free 是函数。
51. 30。
52. 当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。
53. 不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C# 是类型安全的。
54. 全局对象的构造函数会在 main 函数之前执行。
55.
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或 new 申请任意多少的内存,程序员自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
56.
Heap 是堆,Stack 是栈。 Stack 的空间由操作系统自动分配/释放,Heap 上的空间手动分配/释放。 Stack 空间有限,Heap 是很大的自由存储区 C 中的 malloc 函数分配的内存空间即在堆上,C++ 中对应的是 new 操作符。程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行。
57.
通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址 *10H+ 通用寄存器内地址,就得到了真正要访问的地址。
58.
从机制上:c 是面向过程的(但 c 也可以编写面向对象的程序);c++ 是面向对象的,提供了类。C++ 侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。
59.
2次就可以了,方法:将其分成 3 堆,分别是 3 个、3 个、2 个。
第一次天平两边各放 3 个,会有两种情况,一、两边持平一样重,那较重的球则不在里面,那就把剩下的两个称一下就能找到较重那个了。第二种情况是有一边较重,那较重的球就在较重那边的 3 个之中,第二次称就是就在这 3 个之中拿出两个来比较,也有两种情况,持平则较重的是没放进去称的那个,有一边较重则那个就是较重的。
60.
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
1) 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
2) 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行。
3) 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于
进程的资源。
4) 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销
明显大于创建或撤消线程时的开销。
61. 输出:2,5。Ptr 实际是 &(a[5]),也就是 a+5。
62. 执行结果是: 52。
63.
1) if ( flag );if ( !flag )
2) const float EPSINON = 0.00001;if ((x >= - EPSINON) && (x <= EPSINON)
3) if (p == NULL);if (p != NULL)
64.
1)
优点:程序简洁
缺点:多执行了 N-1 次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
2)
优点:循环的效率高
缺点:程序不简洁
65.
Node* ReverseList(Node *head) //链表逆序
{
if(head == NULL || head->next == NULL)
return NULL;
Node *p1 = head, *p2 = head->next;
if(p2->next == NULL)
{
head = p2;
p1->next = NULL;
p2->next = p1;
return head;
}
Node *p3 = head->next->next;
p1->next = NULL;
p2->next = p1;
head = p2;
while(p3 != NULL)
{
p2 = p3;
p3 = p2->next;
p2->next = head;
head = p2;
}
return head;
}
66.
Node* InsertNode(Node *list, int value)
{
Node *p = list;
Node *pt = (Node*)malloc(sizeof(Node));
pt->value = value;
pt->next = NULL;
if(list == NULL)
{
return pt;
}
while(p->next != NULL)
{
if(p->next->value >= value)
break;
p = p->next;
}
pt->next = p->next;
p->next = pt;
return list;
}
Node* MergeList(Node *list1, Node *list2)
{
if(list1 == NULL)
return list2;
if(list2 == NULL)
return list1;
Node *p1 = list1, *p2 = list2;
while(p2 != NULL)
{
list1 = InsertNode(p1,p2->value);
p2 = p2->next;
}
return list1;
}
67.
Node* MergeList_Recursion(Node *list1, Node *list2)
{
if(list1 == NULL)
return list2;
if(list2 == NULL)
return list1;
if(list2 != NULL)
{
list1 = InsertNode(list1,list2->value);
list1 = MergeList_Recursion(list1,list2->next);
}
return list1;
}
68.
int getSecond(int array[], int count)
{
int first = 0, second = 0;
int i;
for(i = 0; i < count; i++)
{
if(array[i] > first)
{
second = first;
first = array[i];
}
else if(array[i] > second)
second = array[i];
}
return second;
}
69. (1)9;(2)10;(3)错误;(4)11
70.
没有为 str 分配内存空间,将会发生异常
问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
71.
char* longSubStr(char longStr[], char shortStr[])
{
if(strstr(longStr, shortStr) != NULL)
return shortStr;
int i, j;
char *strBuf = (char*)malloc(255);
for(i = strlen(shortStr) - 1; i >= 0; i--)
for(j = 0; j < strlen(shortStr) - 1; j++)
{
memcpy(strBuf, &shortStr[j], i);
strBuf[i] = '\0';
if(strstr(longStr, strBuf) != NULL)
return strBuf;
}
return NULL;
}
72.
(1) int a; // An integer
(2) int *a; // A pointer to an integer
(3) int **a; // A pointer to a pointer to an integer
(4) int a[10]; // An array of 10 integers
(5) int *a[10]; // An array of 10 pointers to integers
(6) int (*a)[10]; // A pointer to an array of 10 integers
(7) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
(8) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
73.
(1) const 意味着"只读"。
1) 关键字 const 的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的
2) 通过给优化器一些附加的信息,使用关键字 const 也许能产生更紧凑的代码。
3) 合理地使用关键字 const 可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少 bug 的出现。
(2) 前两个的作用是一样,a 是一个常整型数。第三个意味着 a 是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思 a 是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着 a 是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
74.
#define BIT3 (0x1 << 3)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &= ~BIT3;
}
75.
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;
76.
输出是 ">6" 。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。
char,short→int→unsigned→long→double
77.
对于一个 int 型不是 16 位的处理器为说,上面的代码是不正确的。应编写如下:
unsigned int compzero = ~0;
78. 该代码的输出是 "Got a valid pointer" 。
79.
选 (a) 结构题的成员在内存中的地址是按照他们定义的位置顺序依次增长的。如果一个结构体的指针被看成 它的第一个成员的指针,那么该指针的确指向第一个成员。
80. 选 (b)。
81. 选(a) 。ptr 是一个数组的指针,该数组有 3 个 int 成员。
82.
选(b) 。 sizeof 操作符给出其操作数需要占用的空间大小,它是在编译时就可确定的,所以其操作数即使是一个表达式,也不需要在运行时进行计算。( ++i + ++ i ) 是不会执行的,所以 i 的值还是 3。
83.
选(c) 。考查什么时候数组就是指针.对某些类型 T 而言,如果一个表达式是 T[] ( T 的数组), 这个表达式的值实际上就是指向该数组的第一个元素的指针。所以 (buf+1)[5] 实际上就是 *(buf +6) 或者 buf[6] 。
84.
选(b) 。sizeof(int )的值是 2,所以 p+=sizeof(int) 指向 argv[2],这点估计大家都没有什么疑问。
(p+=sizeof(int))[-1] 指向 argv[1],因为 (p+=sizeof(int))[-1] 就相当于 (p+=2)[-1],也就是(p+2-1)。
85.
char* numToStr(char *s, int num)
{
int count = 0;
while(num != 0)
{
char c = num % 10 + '0';
num = num / 10;
*s++ = c;
count++;
}
char sr[255];
int i;
for(i = 0; i < count; i++)
sr[i] = *(--s);
sr[count] = '\0';
memcpy(s, sr, count);
return s;
}
86. 内存碎片,碎片收集的问题,变量的持行时间。
87.
char* strrev(char* dest, char* src)
{
if(src == NULL)
return NULL;
int slen = strlen(src);
int i;
for(i = 0; i < slen; i++)
{
dest[i] = src[slen - i - 1];
}
dest[slen] = '\0';
return dest;
}
88.
Node* ListNext(Node *cur)
{
if(cur == NULL)
return NULL;
else if(cur->next == NULL)
return NULL;
else
return cur->next;
}
Node* ListInsert(Node *head, Node *newNode)
{
Node *pStart = head;
if(head == NULL)
{
head = newNode;
return head;
}
while(head->next != NULL)
{
if(head->value == newNode->value)
return NULL;
if(head->next->value > newNode->value)
{
newNode->next = head->next;
head->next = newNode;
return head;
}
head = head->next;
}
head->next = newNode;
return head;
}
Node* ListRemove(Node *head, Node *theNode)
{
if(head == NULL || theNode == NULL)
return NULL;
if(head->value == theNode->value)
{
Node *pNode = head;
head = head->next;
free(pNode);
return NULL;
}
while(head != NULL)
{
if(head->next->value == theNode->value)
{
Node *pNode = head->next;
head->next = pNode->next;
free(pNode);
return head;
}
head = head->next;
}
return NULL;
}
89.
char * const cp; ( * 读成 pointer to ) cp is a const pointer to char ;
const char * p; p is a pointer to const char;
char const * p; 同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。
90.
其一:MAX=255,数组A的下标范围为:0..MAX-1
其二:当i循环到255时,循环内执行:A[255]=255;
这句本身没有问题。但是返回 for (i=0;i<=MAX;i++) 语句时,
由于 unsigned char 的取值范围在 (0..255),i++ 以后 i 又为 0 了,无限循环下去。
注:char 类型为一个字节,取值范围是 [-128,127],unsigned char [0 ,255]。
91.
ASSERT() 是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为 FALSE (0), 程序将报告错误,并终止执行。如果表达式不为 0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量 n 在程序中不应该为 0,如果为 0可能导致错误,你可以这样写程序:
ASSERT( n != 0);
ASSERT 只有在 Debug 版本中才有效,如果编译为 Release 版本则被忽略。
assert() 的功能类似,它是 ANSI C 标准中规定的函数,它与 ASSERT 的一个重要区别是可以用在 Release 版本中。
92.
int delRepeatElem(int array[], int count)
{
int i, j;
for(i = 0; i < count; i++)
{
for(j = count - 1; j > i; j--)
{
if(array[j] == array[i])
{
int k;
if(j != (count-1))
{
for(k = j; k < count; k++)
{
array[k] = array[k + 1];
}
}
count--;
}
}
}
return count;
}
93.
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。
94.
实时操作系统是保证在一定时间限制内完成特定功能的操作系统。提供及时响应和高可靠性是其主要特点。
95. 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于 1。
96. 递归太多,消息循环膨胀,方法中分配的数组太大。
97. O(n^2)
98. if(x>0.000001&&x<-0.000001)
99. switch的参数不能为实型。
标签:Node,head,NULL,return,int,笔试,next,99,嵌入式 From: https://www.cnblogs.com/kitsum/p/13964734.html