C、C++常见问题整理

1变量的声明和定义有什么区别

变量的定义为变量分配地址和存储空间, 变量的声明不分配地址。 一个变量可以在多个地方声明, 但是只在一个地方定义。 加入e x t e r n 修饰的是变量的声明, 说明此变量将在文件以外或在文件后面部分定义。

说明:很多时候一个变量, 只是声明不分配内存空间, 直到具体使用时才初始化, 分配内存空间, 如外部变量。

int main()
{
extern int A;
//这是个声明而不是定义,声明A是一个已经定义了的外部变量
//注意:声明外部变量时可以把变量类型去掉如:extern A; dosth(); //执行函数
}
int A; //是定义,定义了A为整型的外部变量

2简述 #ifdef、#else、#endif和#ifndef的作用

利用#ifdef、#endif将某程序功能模块包括进去,以向特定用户提供该功能。在不需要时用户可轻易将其屏蔽。

#ifdef MATH
#include "math.c" #endif

在子程序前加上标记,以便于追踪和调试。

#ifdef DEBUG
printf ("Indebugging.	!");
#endif

应对硬件的限制。由于一些具体应用环境的硬件不一样,限于条件,本地缺乏这种设备,只能绕过硬件,直接写出预期结果。
注意: 虽然不用条件编译命令而直接用i f 语句也能达到要求, 但那样做目标程序长
(因为所有语句都编译),运行时间长( 因为在程序运行时间对if 语句进行测试)。而采用条件编译, 可以减少被编译的语句, 从而减少目标程序的长度, 减少运行时间。

3 写出int 、bool、 float 、指针变量与 “零值”比较的if 语句

//int与零值比较
if (  n  ==  0 )
if ( n  !=  0 )
//bool与零值比较
if	(flag) //	表示flag为真
if	(!flag) //	表示flag为假
//float与零值比较
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON) //其中EPSINON是允许的误差(即精度)。
//指针变量与零值比较
if (p == NULL)
if (p != NULL)

4结构体可以直接赋值吗

声明时可以直接初始化, 同一结构体的不同对象之间也可以直接赋值, 但是当结构体中含有指针“ 成员” 时一定要小心。
注意: 当有多个指针指向同一段内存时, 某个指针释放这段内存可能会导致其他指针的非法操作。 因此在释放前一定要确保其他指针不再使用这段内存空间。

5sizeof 和strlen 的区别

sizeof是一个操作符,strlen是库函数。 sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为‘\0’的字符串作参数。
编译器在编译时就计算出了sizeof的结果,而strlen函数必须在运行时才能计算出来。并且sizeof计算的是数 据类型占内存的大小,而strlen计算的是字符串实际的长度。
数组做sizeof的参数不退化,传递给strlen就退化为指针了

6 C语言的关键字 static 和 C++ 的关键字 static 有什么区别

在 C 中 s t a t i c 用来修饰局部静态变量和外部静态变量、 函数。 而C++ 中除了上述功能外,还用来定义类的成员变量和函数。 即静态成员和静态成员函数。
注意: 编程时static的记忆性,和全局性的特点可以让在不同时期调用的函数进行通信, 传递信息,而 C + + 的静态成员则可以在多个对象实例间进行通信,传递信息。

7 C 语言的 malloc 和 C++ 中的 new 有什么区别

new 、delete 是操作符,可以重载,只能在C++ 中使用。malloc、free 是函数,可以覆盖,C、C++ 中都可以使用。
new 可以调用对象的构造函数,对应的delete 调用相应的析构函数。malloc 仅仅分配内存,free 仅仅回收内存,并不执行构造和析构函数
new 、delete 返回的是某种数据类型指针,malloc、free 返回的是void 指针。

注意:malloc申请的内存空间要用free释放, 而new申请的内存空间要用delete释放,不要混用。

8 写一个 “标准”宏MIN

#define min( a , b ) ( ( a ) < = ( b ) ? ( a ) : ( b ) )

9 volatile有什么作用

状态寄存器一类的并行设备硬件寄存器。
一个中断服务子程序会访问到的非自动变量。多线程间被几个任务共享的变量。
注意:虽然volatile在嵌入式方面应用比较多,但是在P C 软件的多线程中,volatile 修饰的临界变量也是非常实用的。

10 a和&a有什么区别

  • &a:其含义就是“ 变量a 的地址” 。
  • *a :用在不同的地方,含义也不一样。

在声明语句中,*a 只说明a是一个指针变量,如int *a;
在其他语句中,*a 前面没有操作数且a是一个指针时,*a代表指针a指向的地址内存放的数据,如b=*a;
*a前面有操作数且a是一个普通变量时,a代表乘以a,如 c =b a。

11 用C编写一个死循环程序

while(1)
{ }

注意: 很多种途径都可实现同一种功能, 但是不同的方法时间和空间占用度不同, 特别是对于嵌入 式软件, 处理器速度比较慢,存储空间较小, 所以时间和空间优势是选择各种方法的首要考虑条件。

12 结构体内存对齐问题

#include<stdio.h> struct S1
{
int i:8; char j:4; int a:4; double b;
};

struct S2
{
int i:8; char j:4; double b; int a:4;
};
struct S3
{
int i; char j; double b; int a;
};
int main()
{
printf("%d\n",sizeof(S1)); // 输 出 8 printf("%d\n",sizeof(S1); // 输 出 12 printf("%d\n",sizeof(Test3)); // 输 出 8
return 0;
}

sizeof(S1)=16

sizeof(S2)=24

sizeof(S3)=32

说明: 结构体作为一种复合数据类型, 其构成元素既可以是基本数据类型的变量, 也可以是一些复合型类型数据。 对此, 编译器会自动进行成员变量的对齐以提高运算效率。 默认情况下, 按自然对齐条件分配空间。 各个成员按照它们被声明的顺序在内存中顺序存储, 第一个成员的地址和整个结构的地址相同, 向结构体成员中s i z e 最大的成员对齐。
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制, 它们会要求这些数据的首地址的值是某个数k ( 通常它为 4 或 8 ) 的倍数, 而这个k 则被称为该数据类型的对齐模数。

13全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?

全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束时所占内存释放);
而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不可直接访问,模块结束(函数调用完毕),局部变量消失,所占据的内存释放。操作系统和编译器,可能是通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载.局部变量则分配在堆栈里面。