社区
C语言
帖子详情
一定要define吗
ding_suki
2007-06-07 05:42:13
各位,我看到代码里很多#define ......的
#define A 1
#define B 2
...
#define C 1
#define D 2
请问为什么可以重复宏定义一个变量为同一个数?
...全文
400
20
打赏
收藏
一定要define吗
各位,我看到代码里很多#define ......的 #define A 1 #define B 2 ... #define C 1 #define D 2 请问为什么可以重复宏定义一个变量为同一个数?
复制链接
扫一扫
分享
举报
写回复
配置赞助广告
用AI写文章
20 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
lemonmk2
2007-06-09
打赏
举报
回复
同意楼上的!
如果在代码中有多次修改一个数据的地方,#define了会非常方便且安全。
___NULL
2007-06-09
打赏
举报
回复
#define 这个东西很好用
修改程序方便,被多次引用的情况下,也只需要修改一个地方。
dai_weitao
2007-06-09
打赏
举报
回复
方便阅读代码的.
浪客
2007-06-09
打赏
举报
回复
用define便于维护。
比如
#define MAX 255
当你要修改这个数字的时候只需要改这一处就相当于修改了所有使用这个MAX的地方,要不还得挨个找到在修改。
这只是它的作用之一。
milksea
2007-06-09
打赏
举报
回复
为什么要用宏定义,上面的已经说清楚了。补充一点别的。
经常看到熟悉C++的人写一些对C++是对的但对C是不对的东西。注意到在C语言中const变量并不是真正的常量,而只不过是限制程序员写的变量,所以一些整数常量还是应该用宏定义,或如chenyu2202863所说,写成枚举(enum)。
考虑下面的代码:
int buffer[4096];
其中4096是一个magic number,一般地应该定义一个符号常量,以增加可读性,并方便后面的相关代码的修改。使用宏的代码是:
#define BUFFERSIZE 4096
int buffer[BUFFERSIZE];
但由于宏的不安全性,反对宏的人则建议写成:
enum { BUFFERSIZE = 4096 };
int buffer[BUFFERSIZE];
以上两种做法都是习见的,可行的。
但是,在C中,下面的代码是错误的:
const unsigned BufferSize = 4096;
int buffer[BufferSize];
因为前面说过,const变量还是变量,并不是真正的常量。
与之不同的是,在C++中上面的代码就是正确的(这可算是C++对C的改进之一),这点应该引起注意。
星羽
2007-06-09
打赏
举报
回复
inline Matrix4 operator * ( const Matrix4 &m2 ) const
Matrix4 r;
r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
return r;
chenyu2202863
2007-06-09
打赏
举报
回复
当然你还可以用enum{A=1,B=2,C=1,D=2};
justicesun
2007-06-09
打赏
举报
回复
目的是在改的时候更容易点
cgwshxs
2007-06-09
打赏
举报
回复
用define和const定义的是常量哈
millky
2007-06-07
打赏
举报
回复
polarislee的解释完美。是这样的:
1、这个预定义纯粹为了程序的易读性着想的;
2、如果在C++里,这是不科学的方法,应该用const代替#define来进行这方面的预定义,具体原因见effective c++(3rd)条款二。
希望能对你有所帮助!
ding_suki
2007-06-07
打赏
举报
回复
好的,明白点了,谢谢!
freshui
2007-06-07
打赏
举报
回复
定义成啥都无所谓
编译器在预编译的时候把所有A都替换成了1
同理, 所有C也都替换成1了
然后再把替换后的代码交给编译器去编译
这样你定义的A和C对编译器来说, 根本就不知道有这玩意
所以怎么define都无所谓
shubing820904
2007-06-07
打赏
举报
回复
是一个好的习惯!
shubing820904
2007-06-07
打赏
举报
回复
在C++中建议你还是用 CONST 比较好啊!#define是为了避免你重复使用, 加#define
ding_suki
2007-06-07
打赏
举报
回复
我的意思是,为什么定义1既可以宏定义为A,同时定义为C?
ding_suki
2007-06-07
打赏
举报
回复
我是用KEIL C编译,如果我不DEFINE的话就有警告
BaiYangSpirit
2007-06-07
打赏
举报
回复
宏定义,需要的时候就定义了,让别人阅读代码方便罢了
北极猩猩
2007-06-07
打赏
举报
回复
不一定费用#define,推荐使用const
比如
const int A=1;
请问为什么可以重复宏定义一个变量为同一个数?
就像你给两个变量赋值成同一个值是一样的
珍惜生命远离CPP
2007-06-07
打赏
举报
回复
容易记忆,当然这种情况可以完全不需要define
freshui
2007-06-07
打赏
举报
回复
因为用A B C D
很容易让你阅读程序
对计算机来说define不define都一样
山东大学计算机网络实验二-ethernet
河南大学计算机网络实验3
其中以太网帧中Type中包含了协议的类型,从而表明传输的数据报类型,以太类型值为 0x0800 指示了该帧包含了 IPv4 数据报,0x0806 表明指示了该帧包含了 ARP 帧, 0x8100 指示了该帧包含了 IEEE 802.1Q 帧。加深了我对数据链路层以太网帧的传输方式加深了了解,其中帧包含了源MAC地址和目标的MAC地址,并且其中目标MAC地址并不是web服务器的MAC地址,而是网关路由器的MAC地址,通过路由器才会转接到服务器的MAC地址。3:给出2 字节以太类型字段的十六进制的值。
计算机网络 实验二
实作一 熟悉 Ethernet 帧结构使用 Wireshark 任意进行抓包,熟悉 Ethernet 帧的结构,如:目的 MAC、源 MAC、类型、字段等。目的MAC为 80:fa:5b:5f:99:6c源MAC为 00: 74:9c:9f:40:13类型Type为 IPV4(0x0800)✎ 问题你会发现 Wireshark 展现给我们的帧中没有校验字段,请了解一下原因。原因:在大多数硬件/平台上,以太网校验和在传递给Wireshark之前由NIC处理。
计算机网络实验二
一.(数据链路层)使用 Wireshark 任意进行抓包,熟悉 Ethernet 帧的结构 两个方块分别为本机网卡地址和源地址 以太网的帧格式 问题:你会发现 Wireshark 展现给我们的帧中没有校验字段,请了解一下原因。 Wireshark 抓取的包会自动丢弃掉校验字段。 二. ping qige.io (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 icmp 过滤),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址是多少?这个 MAC 地址是谁的? 分别为
【计算机网络】实验报告二:Wireshark实验
Wireshark实验实验准备1.数据链路层1)实作一 熟悉 Ethernet 帧结构2)实作二 了解子网内/外通信时的 MAC 地址3)实作三 掌握 ARP 解析过程2.网络层1)实作一 熟悉 IP 包结构2)实作二 IP 包的分段与重组3)实作三 考察 TTL 事件3.传输层1)实作一 熟悉 TCP 和 UDP 段结构2)实作二 分析 TCP 建立和释放连接4.应用层1)实作一 了解 DNS 解析2)实作二 了解 HTTP 的请求和应答 实验准备 本部分按照数据链路层、网络层、传输层以及应用层进行分类,
C语言
70,040
社区成员
243,245
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章