1.extern
extern关键字用于在多个文件中引用同一个全局变量的声明
在一个头文件中,如果这个变量声明了,但是在cpp文件中没找到他的定义,那么编译就会报错,但是如果加了extern,编译器就不会给头文件报错,而是给cpp文件报错,如果函数没定义的话。或者定义出错的话。
2.关于反复调用简单函数的选择
在C中,我们使用define来定义这种函数,井号define是一种,文本替换的选择,就是默认的把一种文本转换成另外一种文本,方便快捷,但是不检查数据类型,所以可能出现意想不到的问题。
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
int main() {
int num = 5;
printf("Square of %d is %d\n", num, SQUARE(num));
return 0;
}
在C++中,可以直接把函数定义为内联函数,也就是inline,这样在编译的时候,编译器会直接把这个代码加入到代码中,避免了函数调用的开销。
#include <iostream>
inline int square(int x) {
return x * x;
}
int main() {
int num = 5;
std::cout << "Square of " << num << " is " << square(num) << std::endl;
return 0;
}
3.C++是类型安全吗
在上次的文章中,我提到了四种cast,这种类型转换中,reinterpret cast就是暴力转换,这种不考虑后果的转换很恐怖,很容易出问题。
4. 当一个类 A 中没有生命任何成员变量与成员函数,这时 sizeof(A)的值是多少,请解释一下编译器为什么没有让它为零。
为1而不是0,因为编译器仍然为他分配了一个地址来区分不同的类,也就是说,别看人家穷,人家是有编制的。
5.数组和指针在 C 和 C++ 中有几个关键的区别:
存储位置:
数组:在静态存储区(全局数组)或栈上(局部数组)分配内存,其大小在编译时确定。
指针:可以动态指向任意内存地址,其内存分配方式更灵活。
修改内容的区别:
对于数组,如 char a[] = “hello”;,可以修改内容(例如 a[0] = ‘X’;),因为它在可写的内存区域。
对于指针,如 char *p = “world”;,它指向一个常量字符串,试图修改 p[0] = ‘X’; 会导致未定义行为,通常是运行时错误,因为字符串字面量通常存储在只读内存中。
使用 sizeof 的差异:
对于数组,sizeof(a) 返回整个数组的字节数。
对于指针,sizeof§ 返回指针变量本身的字节数(通常是 4 或 8 字节),而不是指向的内存块的大小。指针本身并不存储它所指向内存的大小。
6.extern“C”有什么作用?
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。
这是因为 C++编译后库中函数名会变得很长,与 C 生成的不一致,造成C++不能直接调用
C 函数,加上 extren “c”后,C++就能直接调用 C 函数了。
Extern “C”主要使用正规 DLL 函数的引用和导出 和 在 C++包含 C 函数或 C 头文件时使用。
使用时在前面加上 extern “c” 关键字即可。可以用一句话概括 extern “C”这个声明的
真实目的:实现 C++与 C 及其它语言的混合编程。
7.线程和进程
进程是操作系统中分配资源的基本单位,每个进程都有自己的地址空间、数据和代码,允许程序并行执行。进程之间相互独立,通常无法直接访问彼此的内存。
线程是进程中的一个执行单元,同一进程内的多个线程共享该进程的资源(如内存和文件句柄),可以更高效地执行任务。线程之间的通信和切换开销较小,适合并发处理。
简单来说,进程是资源分配的基本单位,而线程是执行的基本单位。
8.SendMessage和PostMessage
SendMessage是阻塞的,会等消息处理完
PostMessage不是阻塞的,不等消息处理完
9.CMemoryState
用来看当前的内存情况,用来排除内存泄漏
10.#include <filename.h>和 #include “filename.h” 有什么区别?
对于#include <filename.h> ,编译器从标准库路径开始搜索 filename.h对于#include “filename.h” ,编译器从用户的工作路径开始搜索 filename.h
11.#error
用来自定义报错
12.#ifndef #define
#ifndef AFX_MYHEADER_H // 检查是否未定义
#define AFX_MYHEADER_H // 定义宏,标记这个头文件已被包含
// 头文件内容,例如函数声明和类定义
#endif // 结束条件编译块
13.在定义一个宏的时候要注意什么?
答:定义部分的每个形参和整个表达式都必须用括号括起来,以避免不可预料的错误发生
#define SQUARE(x) x * x
#define SQUARE(x) ((x) * (x))
这样
14.数组在做函数实参的时候会转变为什么类型?
数组在做实参时会变成指针类型。 他只需要指向数组的首地址去传入就好了,这样不需要浪费系统资源。
15.系统会自动打开和关闭的 3 个标准的文件是?
(1) 标准输入—-键盘—stdin
(2) 标准输出—-显示器—stdout
(3) 标准出错输出—-显示器—stderr
16.在 Win32 下 char, int, float, double 各占多少位?
(1) Char 占用 8 位,1个字节
(2) Int 占用 32 位 ,4个字节
(3) Float 占用 32 位,4个字节
(4) Double 占用 64 位,8个字节