初始化时间问题

liyxxx 2010-08-30 01:07:42
共有3个文件
MyClass.h

#ifndef NUM
#define NUM 100
#endif
class MyClass
{
public:
int table[NUM];
void MyRead();
};

MyClass.cpp

#include <iostream>
#include "MyClass.h"
using namespace std;
void MyClass::MyRead()
{
cout<<sizeof(table)<<endl;
}

main.cpp

#define NUM 10
#include "MyClass.h"
main()
{
MyClass mc;
mc.MyRead();
return 0;
}


编译后执行main.exe,为什么最后输出的是400而不是40呢?我的NUM应该是在类之前定义的吧。编译器:g++ 3.4.5
...全文
206 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
fbs216zhou 2010-08-31
  • 打赏
  • 举报
回复
看一下main.cpp昊面的#include 和#define 先后顺序
liyxxx 2010-08-30
  • 打赏
  • 举报
回复
刚才做了个实验,如果程序是这样:
#main.cpp
#define NUM 10

#MyClass.h
#ifndef NUM
#define NUM 100
#endif
编译没有任何问题,NUM=100,说明main.cpp中的NUM对MyClass.h没有影响。
而如果将2个define对换一下,即:
#main.cpp
#ifndef NUM
#define NUM 10
#endif

#MyClass.h
#define NUM 100
结果是编译出错,重复定义。说明main.cpp的NUM还是对MyClass.h有影响的,这让我很迷惑。
哪位高人能解答一下?
fbs216zhou 2010-08-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 liyxxx 的回复:]
我试了一下,果然是楼上说的这种情况!
现在的问题是:既然在不同的文件中#define不能用,那防止重复包含的#ifndef……#define……#endif是怎么实现的呢?
[/Quote]

不是在不同的文件中不能用,而是看有没有包含,你把包含关系理一下,看看在MyClass的实现时,有没有包含进main.cpp里面的那个NUM,在你的程序中是没有的
liyxxx 2010-08-30
  • 打赏
  • 举报
回复
学习了,对这种包含的机制有所了解,但是编译器对于我给出的这种情况竟然没有警告,迷惑。
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
编译器要求,数组的大小在编译时就要是一个确定的值,那么在这之前可以看到的又只有400,所以是400了,运行起来后,数组的大小是不可以动态的改变的
烂番 2010-08-30
  • 打赏
  • 举报
回复
MyClass.h在编译时是不知道其它地方有#define NUM的,所以会重新定义NUM
在main.cpp里展开时,就把main.cpp里的覆盖了

如果MyClass.h在头部#include "xx.h" 而xx.h里定义了NUM,这时MyClass.h是不会重新定义NUM的
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
数组的大小不是编译时就确定了,运行起来是不可以改变的,也就说是不可能改变为40的,我是这么理解的
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 luver 的回复:]
这个一般编译器会出warning,然后以后define的为准

你把这个#define放在 #include后面,就是另一种结果了
[/Quote]
即使放在#include后面,也是400,是没有改变的
liyxxx 2010-08-30
  • 打赏
  • 举报
回复
我试了一下,果然是楼上说的这种情况!
现在的问题是:既然在不同的文件中#define不能用,那防止重复包含的#ifndef……#define……#endif是怎么实现的呢?
cs_yagami 2010-08-30
  • 打赏
  • 举报
回复
define不是static這類型的東西,它就只是替換,不同檔案中,它的作用域只存在於該檔案裡而已。
所以你在MyClass.h裡定義NUM為100,跟main裡定義NUM為10,這兩者是不相甘的。
fbs216zhou 2010-08-30
  • 打赏
  • 举报
回复
在MyClass这个类中,只知道有MyClass.h中那个NUM,根本就无法用main.cpp那个NUM. 看看文件包含方面的内容就会明白.
你可以试一下,如果将MyClass.h中那个NUM去掉,程序编译不过去.
main.cpp中的那个NUM在这种情况下只在本文件中有用.
夏卡罗 2010-08-30
  • 打赏
  • 举报
回复
你可以单步跟踪调试观察NUM值的变化情况,跟踪得到的结果是正确的,也可以发现到底用的是哪个 #define NUM
为最后的初始化。
烂番 2010-08-30
  • 打赏
  • 举报
回复
这个一般编译器会出warning,然后以后define的为准

你把这个#define放在 #include后面,就是另一种结果了
liyxxx 2010-08-30
  • 打赏
  • 举报
回复
难道初始化的顺序不应该是:main.cpp、MyClass.h、Myclass.cpp吗?怀疑是不是我的用法不对,
#ifndef NUM
#define NUM 100
#endif
以至于第一句没起作用。希望高手能答疑。
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
void MyClass::MyRead()
{
cout<<sizeof(table)<<endl;
}
这个操作,你执行的时候,可以看到的就是#define NUM 100;
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
你在MyClass.cpp中用的是#include "MyClass.h"这个文件中的#define NUM 100并不是main中的#define NUM 10

liyxxx 2010-08-30
  • 打赏
  • 举报
回复
看清楚了,我程序中一共出现了2个#define NUM,我想知道的是为什么起作用的是#define NUM 100,而不是#define NUM 10,还是我这种用法不对?
  • 打赏
  • 举报
回复
void MyClass::MyRead()
{
cout<<sizeof(table)<<endl;
}

到这里的时候NUM是100。所以结果是400
在main中sizeof(MyRead)的话就是40了。
maoxing63570 2010-08-30
  • 打赏
  • 举报
回复
100*4=400,一个int为4,100个int为400
第一章 走进linux 1.1 GNU与Linux的成长 1.2 Linux的开发模式和运作机制 1.3走进Linux内核 1.4 分析Linux内核的意义 1.5 Linux内核结构 1.6 Linux内核源代码 1.7 Linux内核源代码分析工具 第二章 Linux运行的硬件基础 2.1 i386的寄存器 2.2 内存地址 2.3 段机制和描述符 2.4 分页机制 2.5 Linux中的分页机制 2.6 Linux中的汇编语言 第三章中断机制 3.1 中断基本知识 3.2中断描述符表的初始化 3.3异常处理 3.4 中断处理 3.5中断的后半部分处理机制 第四章 进程描述 4.1 进程和程序(Process and Program) 4.2 Linux中的进程概述 4.3 task_struct结构描述 4.4 task_struct结构在内存中的存放 4.5 进程组织的方式 4.6 内核线程 4.7 进程的权能 4.8 内核同步 第五章进程调度 5.1 Linux时间系统 5.2 时钟中断 5.3 Linux的调度程序-Schedule( ) 5.4 进程切换 第六章 Linux内存管理 6.1 Linux的内存管理概述 6.2 Linux内存管理的初始化 6.3 内存的分配和回收 6.4 地址映射机制 6.5 请页机制 6.6 交换机制 6.7 缓存和刷新机制 6.8 进程的创建和执行 第七章 进程间通信 7.1 管道 7.2 信号(signal) 7.3 System V 的IPC机制 第八章 虚拟文件系统 8.1 概述 8.2 VFS中的数据结构 8.3 高速缓存 8.4 文件系统的注册、安装与拆卸 8.5 限额机制 8.6 具体文件系统举例 8.7 文件系统的系统调用 8 .8 Linux2.4文件系统的移植问题 第九章 Ext2文件系统 9.1 基本概念 9.2 Ext2的磁盘布局和数据结构 9.3 文件的访问权限和安全 9.4 链接文件 9.5 分配策略 第十章 模块机制 10.1 概述 10.2 实现机制 10.3 模块的装入和卸载 10.4 内核版本 10.5 编写内核模块 第十一章 设备驱动程序 11.1 概述 11.2 设备驱动基础 11.3 块设备驱动程序 11.4 字符设备驱动程序 第十二章 网络 12.1 概述 12.2 网络协议 12.3 套接字(socket) 12.4 套接字缓冲区(sk_buff) 12.5 网络设备接口 第十三章 启动系统 13.1 初始化流程 13.2 初始化的任务 13.3 Linux 的Boot Loarder 13.4 进入操作系统 13.5 main.c中的初始化 13.6 建立init进程 附录: 1 Linux 2.4内核API 2.1 驱动程序的基本函数 2.2 双向循环链表的操作 2.3 基本C库函数 2.4 Linux内存管理中Slab缓冲区 2.5 Linux中的VFS 2.6 Linux的连网 2.7 网络设备支持 2.8 模块支持 2.9 硬件接口 2.10 块设备 2.11 USB 设备

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧