第六十九天学习记录:对陈正冲编著《C 语言深度解剖》中关于3.预处理的学习以及作者留下问题的学习

文章介绍了C语言中的预处理指令,包括#define、#undef、#include等,以及预编译宏如_LINE_、_FILE_等。同时,讨论了预处理在实际编程中的作用,如条件编译和宏展开。通过示例解释了宏定义的使用和注意事项,并分析了代码片段中变量z的值计算过程。
摘要由CSDN通过智能技术生成

对于预处理,可以说是包括笔者在内的很多人在打开代码编辑器时看到的第一句语言。
比如:#pragma once,#define _CRT_SECURE_NO_WARNINGS 1,#include
但因为学习C语言时预编译往往不是最先开始学习的,因此就会造成知其然不知其所以然的状况。
比如笔者在加入工作之后,由于基本上没有基础,在打开别人代码首先看到一堆预编译时的第一感觉是抓狂的。有种进入陌生荒野的感觉。
但后面找到熟悉的“内容”后,发现改动程序代码很少牵扯到这些预编译内容,因此这些“陌生的句子”便被淡忘了。以一种存在即合理的态度对待,可敬而不可近……
直至开始系统性学习C语言的时候,才逐渐对预编译内容了解。
至于为什么工作四年还这么菜,笔者在第一天学习记录已经交代过……那时为了尽快保住“饭碗”和负债压力,短时间功利性的学习逐渐造成了今天的这种局面。

ANSI 标准定义的 C 语言预处理指令:

预处理名称意 义
#define宏定义
#undef撤销已定义过的宏名
#include使编译程序将另一源文件嵌入到带有#include 的源文件中
#if、#else、#elif、#endif#if 的一般含义是如果#if 后面的常量表达式为 true,则编译它与#endif 之间的代码,否则跳过这些代码。命令#endif 标识一个#if 块的结束。#else命令的功能有点象 C 语言中的 else ,#else 建立另一选择(在# if 失败的情况下)。#elif 命令意义与 else if 相同,它形成一个 if else-if 阶梯状语句,可进行多种编译选择。
#ifdef 、 #ifndef用#ifdef 与#ifndef 命令分别表示“如果有定义”及“如果无定义”,是条件编译的另一种方法。
#line改变当前行数和文件名称,它们是在编译程序中预先定义的标识符命令的基本形式如下:#line number[“filename”]
#error编译程序时,只要遇到 #error 就会生成一个编译错误提示消息,并停止编译
#pragma为实现时定义的命令,它允许向编译程序传送各种指令例如,编译程序可能有种选择,它支持对程序执行的跟踪。可用#pragma 语句指定一个跟踪选择。

ANSI 标准 C 定义的另外几个宏:

_LINE_ 表示正在编译的文件的行号
_FILE_ 表示正在编译的文件的名字
_DATE_ 表示编译时刻的日期字符串
_TIME_ 表示编译时刻的时间字符串
_STDC_ 判断该文件是不是定义成标准 C 程序

以上部分内容已在之前学习课程的视频中出现,这里再次巩固。

对于《C 语言深度解剖》这本书对各种知识点的讲解很明确,作者习惯留下很多问题,这里主要对这些问题进行学习。

#define SQR(x) ((x)*(x))
#define SUM(x) (x)+(x)

四个问题:
A),上述宏定义中“SUM”、“SQR”是宏吗?
B),#define EMPTY这样定义行吗?
C),打印上述宏定义的值:printf(“SUM (x)”);结果是什么?
D), “#define M 100”是宏定义吗?

解答:
A) 是宏定义,中间的空格可以忽略。

B) 不行,宏定义必须有替换文本,EMPTY 没有。

C) 这样仅仅是打印了一个字符串 “SUM (x)”,并没有进行宏替换。正确的打印方法应该是:

printf("SUM(5) = %d\n", SUM(5));  // 结果是 5+5 = 10
printf("SQR(5) = %d\n", SQR(5));  // 结果是 5*5 = 25

D) 是宏定义:将 “M” 替换为 “100”。

请思考一下这个问题:

#define X 3
#define Y X*2
#undef X
#define X 2
int z=Y;

z 的值为多少?
答:4
在上面的代码片段中,首先定义了X的值为3,然后定义了Y的值为X*2,因此Y被展开后的值为6。接着通过#undef X取消了对X的定义,然后重新定义了X的值为2。

最后创建了一个整型变量z,其值赋为Y即6。根据预处理的过程,Y会被展开为X*2,而此时的X的值已经被重新定义为2,因此实际上z的值为4。

因此,最终结果是z等于4。

#include <stdio.h>

#define X 3
#define Y X*2
int y = Y;
#undef X
#define X 2
int z = Y;

int main()
{
	printf("%d %d\n", y,z);
	return 0;
}

如下代码运行为:6 4

pragma

#pragma pack 的其他用法:
#pragma pack(push) //保存当前对其方式到 packing stack
#pragma pack(push,n) 等效于
#pragma pack(push)
#pragma pack(n) //n=1,2,4,8,16 保存当前对齐方式,设置按 n 字节对齐
#pragma pack(pop) //packing stack 出栈,并将对其方式设置为出栈的对齐方
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值