1. 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述)。
用volatile关键字定义变量,防止编译器对代码进行优化而被省略,切立即输出原值。
建议使用volatile变量的场所:
(1) 并行设备的硬件寄存器
(2) 一个中断服务子程序中会访问到的非自动变量(全局变量)
(3) 多线程应用中被几个任务共享的变量
2. C语言中static关键字的具体作用有哪些 ?
static把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量 后是改变了它的作用域, 限制了它的使用范围。
3. 请问下面三种变量声明有何区别?请给出具体含义
int const p;
int const p;
int const* const p;
答案
一个指向常整型数的指针
一个指向整型数的常指针
一个指向常整型数的常指针
4. 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
-
用变量a给出下面的定义
a) 一个整型数(An integer)
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
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 function 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 return 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,写两段代码 ,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。
#define BIT3 (0x1 < ❤️)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &= ~BIT3;
} -
嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求 设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写 代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指
针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
一个较晦涩的方法是:
*(int * const)(0x67a9) = 0xaa55;
即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。
-
堆栈
int a = 0;全局初始化区 //代码段
char *p1;全局未初始化区 //bss段
main()
{
int b;栈
char s[] =“abc”;栈
char p2;栈
char p3 =“123456”; 123456\0在常量区,p3在栈上。
static int c =0;全局(静态)初始化区 //代码段
p1 = (char)malloc(10);
p2 = (char)malloc(20);分配得来得10和20字节的区域就在堆区。
strcpy(p1,“123456”); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 -
什么是野指针?产生的原因?
“野指针”不是NULL指针,是指向“垃圾”内存(不可用内存)的指针。“野指针”是很危险的,if无法判断一个指针是正常指针还是“野指针”。有个良好的编程习惯是避免“野指针”的唯一方法。
野指针的成因主要有三种:
一、指针变量没有被初始化。指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
二、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
三、指针操作超越了变量的作用范围。比如不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。比如说某个地址的生命期,使用一个没有生命期的指针是非常危险的。 -
sizeof和strlen区别
sizeof
sizeof(…)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
strlen
strlen(…)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。
它的功能是:返回字符串的长度 -
写出strcpy,strcmp,strlen,memcpy函数源码的实现。
char * strcpy( char*strDest, const char *strSrc )
{
char *address =strDest;
while( (*strDest++= * strSrc++) !=‘\0’ );
return address;
}
int strlen( const char *str ) //输入参数const
{
int len;
while( (*str++) !=’\0’ )
{
len++;
}
return len;
}
-
在网络应用中,函数htons,htonl,ntohs,ntohl的作用是什么?
uint32_t htonl(uint32_t hostlong);//32位的主机字节序转换到网络字节序
uint16_t htons(uint16_t hostshort);//16位的主机字节序转换到网络字节序
uint32_t ntohl(uint32_t netlong);//32位的网络字节序转换到主机字节序
uint16_t ntohs(uint16_t netshort);//16位的网络字节序转换到主机字节序 -
简述大端小端字节序的区别
-
进程间通信的方式有
-
管道(pipe),流管道(s_pipe)和有名管道(FIFO)
-
信号(signal)
-
消息队列
-
共享内存
-
信号量
-
套接字(socket)
-
预处理器标识#error的目的是什么?
如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。 -
队列和栈有什么区别?
队列先进先出,栈后进先出