赞
踩
1、一个由C/C++编译的程序占用的内存分为栈区、堆区、全局区、文字常量区、程序代码区存放什么数据?
栈区:一开始编译器就分配好的,函数的局部变量,参数,返回数据。
堆区:由程序员自己进行分配的
全局区(静态区)static):全局变量、静态数据和常量
文字常量:常量字符串
程序代码段:存放函数体的二进制代码
2、static作用?
全局变量:不赋值,默认为零
局部变量:限定作用域,局部函数内使用。
静态函数:只限本模块(C源文件作用域)调用,其他模块(其他C文件)不能调用该静态函数。
3、switch和if区别?
switch类型可以是byte,short,char,都可以隐含转换为int。但是不能是实型(浮点数)
switch是以空间换取时间;if是以时间换取空间。
4、用一个宏表示一年中有多少秒?为什么要用UL?
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
UL:当数值比较大时,乘以另外更大的数值时,int类型可能会越界,用ul强制类型转换可以解决这个顾虑。
5、写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个
#define MIN(x,y) x<y?x:y
6、0UL 表示 无符号长整型 0
7、关键字volatile有什么含意 并给出三个不同的例子。
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
表示该变量是易变的,编译器不应该去优化该值,即编译器不会去假设这个变量的值。它必须去内存中重新获取该值,而不是用寄存器中保存的值。
(1)并行设备的硬件寄存器
(2)一个服务子程序中访问到的非自动变量。
(3)多线程应用中被几个任务共享的变量。
8、无符号整形和符号整形数字相加时,后者自动转化为无符号整形
9、思考一下下面的例子,哪种方式会更好?
#define dPS struct s *
typedef struct s * tPS;
答案是:typedef更好。思考下面的例子:
dPS p1,p2;
tPS p3,p4;
第一个扩展为
struct s * p1, p2;
上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。
10、编写字符串复制功能函数。
void strcpy(char *strdest, const char *strsrc)
{
//对源地址和目的地址加非0断言,
assert( (strdest != null) && (strsrc != null) );
while( (*strdest++ = * strsrc++) != ‘\0’ );
}
11、只用两个变量,就可以交换两个变量的数值。
#include <stdio.h>
void main()
{
int i=60;
int j=50;
i=i+j;
j=i-j;
i=i-j;
printf(“i=%d\n”,i);
printf(“j=%d\n”,j);
}
方法二:
i=j;j=i;i^=j;
方法三:
// 用加减实现,而且不会溢出
a = a+b-(b=a)
12、一个参数既可以是const还可以是volatile吗?解释为什么。
可以,比如寄存器变量,我们希望它是只读的,但是仍可能是易变的。
13.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
c用宏定义,c++用inline
14、unsigned char *p1; unsigned long *p2;p1=(unsigned char *)0x801000;p2=(unsigned long *)0x810000;请问p1+5= ; p2+5= ;
答案:801005;810014。不要忘记了这个是16进制的数字,p2要加20变为16进制就是14
15、写出输出结果?并解释
#include <stdio.h>
void f(unsigned char v)
{
char c = v;
unsigned char uc = v;
unsigned int a = c, b = uc;
int i = c, j = uc;
printf(“----------------\n”);
printf(“%%c: %c, %c\n”, c, uc);
printf(“%%X: %X, %X\n”, c, uc);
printf(“%%u: %u, %u\n”, a, b);
printf(“%%d: %d, %d\n”, i, j);
}
int main(int argc, char *argv[])
{
f(0x80);
f(0x7F);
return 0;
}
输出结果:
%c: ?, ?
%X: FFFFFF80, 80
%u: 4294967168, 128
%d: -128, 128
%c: ,
%X: 7F, 7F
%u: 127, 127
%d: 127, 127
由此可见,最高位若为0时,二者没有区别,若为0时,则有区别了。
16、
int a[3]={1,2,3};
总结就是:a是数组首地址,&a是数组首元素的地址.
a+1:就是数组首地址加上一个元素所占的地址大小,这里int是4个字节,所以加上1x4.
&a+1:代表的是加上整个数组的大小,这里数组尺寸是3,所以+1代表的是地址加上3x4.
*(a+1):代表的是数组第一个元素的!值!不再是元素的地址,这里就是9999.
*(&a+1):将&a+1地址取出来.
:&a+1地址的前一个元素的地址,这个地址中的元素!值!!取出来!
17、找错误
int main()
{
char a;
char *str=&a;
strcpy(str,“hello”);
printf(str);
return 0;
} 答案:没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
18、找错误
char* s=“AAA”;是不合法的,s的指针指向字符常量,所以类型是const char*
19、下面这个程序执行后会有什么错误或者效果:
#define MAX 255
int main()
{
unsigned char A[MAX],i;
for (i=0;i<=MAX;i++)
A[i]=i;
},函数变成死循环,unsigned char 最大值 255
19、写出输出结果
#include <stdio.h>
int inc(int a)
{
return (++a);
}
int multi(int *a,int *b,int *c)
{
return (*c = *a * *b);
}
typedef int (FUNC1) (int );
typedef int (FUNC2) (int *, int *, int * );
void show(FUNC1 fun,int arg1,int *arg2)
{
FUNC1 *p=&inc;
int temp=p(arg1);
fun(&temp,&arg1,arg2);
}
int main()
{
int a;
show(multi,12,&a);
return 0;
}
//结果是 13*12=156
//找错 倒序
#include "string.h"
int main()
{
char *src = "hello,world";//
char *dest = NULL;
int len = strlen(src);
dest = (char *)malloc(len);//1、需要多分配一个字节给“\0”,(char *)malloc(len+1)
char *d = dest;
char *s = src[len];//2、char *s = &src[len-1];src[len]=‘\0’
while (len-- != 0)
*d++ = *s--;
printf("%s", dest);//3、在前一行加上 *d='\0' 4、在下一行加上 释放内存 free(dest);
return 0;
}
20、用变量a给出下面的定义
e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)int *p[10]
f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers) in (*p)[10]
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer) int (*p)(int)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )int (*p[10])(int)
21、const关键字至少有下列n个作用:
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
22、给定结构struct A
{
char t:4;
char k:4;
unsigned short i:8;
unsigned long m;
};问sizeof(A) = ?
给定结构struct A
{
char t:4; 4位
char k:4; 4位
unsigned short i:8; 8位
unsigned long m; // 偏移2字节保证4字节对齐
}; // 共8字节
23、 void main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf(“%d,%d”,(a+1),(ptr-1));
}
输出:2,5
24、
char* s=“AAA”;
printf(“%s”,s);
s[0]=‘B’;
printf(“%s”,s);
有什么错?
"AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。
cosnt char* s=“AAA”;
然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
25、
#i nclude <stdio.h>
int main(void) {
int **p;
int arr[100];
p = &arr;
return 0;
}
解答:
搞错了,是指针类型不同,
int **p; //二级指针
&arr; //得到的是指向第一维为100的数组的指针
#i nclude <stdio.h>
int main(void) {
int **p, *q;
int arr[100];
q = arr;
p = &q;
return 0;
}
26、 一个参数既可以是const还可以是volatile吗?解释为什么。
可以,比如寄存器变量,我们希望它是只读的,但是仍可能是易变的。
27、一个指针可以是volatile 吗?解释为什么。
buffer指向一个地址被A线程使用,B线程修改了buffer所指的地址,同时希望A线程使用新地址,设置volatile。
28、中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf(" Area = %f", area);
return area;
}
(1)中断不应该有返回值
(2)中断子程序中应该尽量少使用浮点类型,因为不可重入,以及printf也是不可重入的,在不同平台移植会出错。
(3)中断不应该传参
29、什么是野指针?空指针?
野指针:定义了指针变量,但是没有初始化,没有指向任何变量或者指向的内存空间是已经销毁的。
空指针:将一个指针变量初始化位NULL。
30、
#define SQUARE(a) ((a)*(a))
int a=5; int b;
b=SQUARE(a++);
a=?,b=?; 7 , 30
31、有数组定义int a[2][2]={{1},{2,3}};则a[0][1]的值为0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。