c语言复习第一部分

190 阅读7分钟

25.结构与联合的区别

(1)结构和联合都是由多个不同的数据类型成员组成的,但是联合中所有的成员共用一块地址空间,结构的所有成员存放地址空间不同

(2)对于联合的不同成员赋值,将会对其他成员重写,原来成员的值就不存在了,对于结构的不同成员赋值则不影响。

26 内存分配方式

(1)静态存储区分配,内存在程序编译的时候已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量

(2)栈上创建:执行函数时,函数内部局部变量会在栈上创建,函数结束时这些存储单元被释放

(3)堆上创建:由程序员自己释放与分配

27 const与define相比,有什么优缺点

(1) const作用:定义常量,修饰函数参数,修饰函数返回值。可以提供程序的健壮性

(2) const常量有数据类型,define没有数据类型,编译器对前者进行类型检查,对后者不进行类型检查,只是简单的字符串替换,

(3)有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试

28 数组与指针的区别

数组要么在静态存储区上被创建(如全局数组),要么在栈上被创建,指针可以指向任何类型的内存块。 (1)修改内容上的差别

char a[] = ‚hello‛;a[0] = ‘X’;
char *p = ‚world‛; // 注意 p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误

(2)用sizeof运算符可以计算出数组的容量,计算指针时只能得到指针变量的字节数

29 分别写出BOOL,int ,float,指针类型的变量a与“零”比较的语句

bool if(!a) or if (a)
int if (a==0)
float :const EXPRESSION EXP = 0.0000001
      if(a < EXP && a > -EXP)
指针: if(a!=NULL) or if(a== NULL)

30 判断一段程序是由c编译还是c++编译的

#ifdef _cplusplus
cout<<"c++"
#else
cout<<"c"
#endif

31 带参数的宏与函数的优缺点

            带参宏            函数
处理时间     编译时            程序运行时
参数类型     没有参数类型问题    定义实参,形参
处理过程     不分配内存         分配内存
程序长度      变长             不变
运行速度      不占用运行时间    调用和返回占用时间

32 两个栈实现一个队列功能,思路与算法

设两个栈为A,B,都为空 入队:时将新元素push到A,

出队:(1)判断栈B是否为空 (2)如果不为空,则将栈A中的所有元素依次pop出并push到栈B (3)将栈B的栈顶元素pop出

33 死循环

while(1)
for(;;)
Loop:
goto Loop;

34 位操作

设置a的bit3位为1
a |= (1<<3)

清除a的bit3位:
a &= ~(1<<3)

35 访问固定的内存位置

设置一绝对地址为0x67a9整型变量的值为0xaa66,这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的

int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;

*(int *const)(0x67a9) = 0xaa55;

36中断

中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准 C 支持中断。具 代表事实是,产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt 关键字去定义了一 个中断服务子程序(ISR),请评论一下这段代码的。

__interrupt double compute_area(double radius)
{
  double area = PI * radius * radius;
  printf("\nArea = %f", area);
  return area;
}

(1)ISR不能返回一个值
(2)ISR不能传递参数
(3) ISR中不能做浮点运算
(4) printf()经常有重入和性能上的问题

37动态内存分配

下面的代码片段的输出是什么,为什么?
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");
这是一个有趣的问题。最近在我的一个同事不经意把 0 值传给了函数 malloc,得到了一个合法的指针之
后,我才想到这个问题。这就是上面的代码,该代码的输出是"Got a valid pointer"。我用这个来开始讨
论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方
法和你做决定的基本原理更重要些。

38 Typdef

答: Typedef 在 C 语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。
例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上两种情况的意图都是要定义 dPS 和 tPS 作为一个指向结构 s 指针。哪种方法更好呢?(如果有的话)
为什么?
这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是: typedef 更好。
思考下面的例子:
dPS p1,p2;tPS p3,p4;
第一个扩展为
struct s * p1, p2;
上面的代码定义 p1 为一个指向结构的指, p2 为一个实际的结构,这也许不是你想要的。第二个例子正
确地定义了 p3 和 p4 两个指针。

39 用变量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 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)(int)
f.(int)(*a[10])(int)

40 全局变量

1.全局变量:它的有效范围从定义变量的位置开始到本源文件结束,内存分配为静态存储区

2.局部变量:在一个函数里面定义的变量

3.静态变量:静态变量在一个函数中,只能在这个函数中使用,内存在整个程序运行期间都存在,全局静态变量只在本文件中有效

41 写一个标准宏

交换两个参数:

#define Swap(a,b)\
(a) = (a) + (b);
(b) = (a) - (b);
(a) = (a) - (b);

一年多少秒

#define SECONDOFYEAR (60 * 60 *24*365)UL

求数组元素个数

#define NTBL (sizeof(table))/sizeof(table[0]))

##42 A.c 和 B.c 两个 c 文件中使用了两个相同名字的 static 变量,编译的时候会不会有问题?这两个 static 变量会保存到哪里(栈还是堆或者其他的)

static 的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。 他们都放在静态存储区,但是编译器对他们的命名是不同的。 如果要使变量在其他模块也有意义的话,需要使用 extern 关键字 ##43一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?

将这个指针的next结点copy到本结点1,将next指向next->next,并删除

ptr = ptr->next;
ptr->next = ptr->next->next
free(ptr);

本文使用 mdnice 排版