12月9号 C语言笔记

  1. 函数 query 查找在二分法中第一次查找到的值等于 value 的元素位置,如果找到,则输出相应的下标;如果没有找到,则输出 This element does not exist.

二分法第一次找到,不是出现的最小坐标的位置,是二分的第一个找到的位置。

  1. 函数题可以看头文件,头文件相当于是提示,比如有 #include <math.h>,说明可能要用到里面的某些函数,比如 pow 或者 log10

  2. 其中,characters 是用户输入的字符集合,n 是密码长度( n>1 ),除 generatePasswords 函数外,还需增加递归函数实现上述功能。

他的意思是,你还可以多写一个函数……你可以另外写一个 dfs,然后在 generatePasswords 里面调用它。

  1. 有序表 insert 函数的如下代码是找到第一个比 value 大的元素下标,如未找到,iCount
for (i = 0; i < Count; i++)
    if (value < a[i])
        break;

正确,小于号其实是 a[i] > value 。太坑了。

  1. 宏定义 #define 是 C/C++ 中的预处理指令,会在预处理阶段进行简单的文本替换

具体规则如下(deepseek写得太好了,一点都删不了):

1. 基本替换规则

#define 标识符 替换文本

预处理时,源代码中所有独立出现的标识符都会被替换为对应的文本。

2. 会替换的内容

会被替换的情况:

#define PI 3.14159
#define MAX 100
#define SQUARE(x) ((x)*(x))

int main() {
    // 普通标识符会被替换
    double area = PI * r * r;      // 替换为 3.14159 * r * r
    
    int arr[MAX];                   // 替换为 int arr[100];
    
    int x = SQUARE(5);             // 替换为 ((5)*(5))
    
    // 宏的参数也会被替换
    #define ADD(a,b) (a + b)
    int sum = ADD(x, y);           // 替换为 (x + y)
    
    return 0;
}

不会被替换的情况:

#define MAX 100
#define TEST "hello"

int main() {
    // 1. 字符串常量中的相同文本不会被替换
    printf("MAX value is: %d", MAX);
    // 输出:"MAX value is: 100"(字符串内的"MAX"保持不变)
    
    // 2. 注释中的宏名不会被替换
    // This is MAX value  // 这里的MAX不会被替换
    
    // 3. 标识符的一部分不会被替换
    int MAXimum = 50;    // "MAXimum" ≠ "MAX",不替换
    int MAX_VALUE = 200; // "MAX_VALUE" ≠ "MAX",不替换
    
    // 4. 被单/双引号包围的字符
    char c = 'X';        // 字符常量不替换
    
    return 0;
}

3. 带参数的宏替换

#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define SWAP(x,y) {int t=x; x=y; y=t;}

int main() {
    int m = MIN(3+2, 4);  // 替换为:((3+2) < (4) ? (3+2) : (4))
    int a=1, b=2;
    SWAP(a,b);            // 替换为:{int t=a; a=b; b=t;}
    return 0;
}

4. 字符串化和连接运算符

# 字符串化运算符

#define STR(s) #s
printf("%s", STR(hello));  // 替换为:printf("%s", "hello");

## 连接运算符

#define CONCAT(a,b) a##b
int xy = 10;
int val = CONCAT(x, y);    // 替换为:int val = xy;

5. 特殊注意事项

嵌套宏定义

#define A 10
#define B (A + 20)  // 预处理时会展开两次
int x = B;          // 替换为:int x = (10 + 20);

递归宏不会无限展开

#define A B
#define B A
int x = A;  // 预处理会检测到循环,展开一次后停止

条件编译中的宏

#if defined(DEBUG)  // defined() 是预处理运算符,不进行文本替换
    // ...
#endif

6. 避免替换的技巧

// 如果不想让某个标识符被替换
#undef PI  // 取消宏定义
const double PI = 3.14159;  // 使用常量

// 或者用括号防止替换
#define MAX (100)

7. 最佳实践

  1. 全大写命名宏,与变量区分
  2. 带参数的宏每个参数和整体都要加括号
  3. 多行宏用 do { ... } while(0) 包装
  4. 简单的常量尽量用 const 替代 #define
// 好的宏定义
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define LOG(msg) do { \
    fprintf(stderr, "[%s] %s\n", __TIME__, msg); \
} while(0)

总之,宏替换是词法级别的文本替换,不会理解代码的语义,因此使用时需格外小心,避免产生意外的副作用。

  1. 被调函数调用被调函数本身属于嵌套调用。

错误(可以等作业出答案校对一下)。课本中先介绍了函数中调用其他函数,是嵌套调用。介绍到递归调用,说递归调用是一种新的调用方式。所以这应该不是嵌套调用。

  1. 参数是指针别忘记函数调用写实参的时候加上取地址符。课后作业11,5-1的第三个空要加个 & 号。
posted @ 2025-12-09 19:42  Zlc晨鑫  阅读(3)  评论(0)    收藏  举报