在头文件中加入#ifdef/#define/#end if,作用是什么
时间: 2024-09-23 18:08:21 浏览: 49
在 C 或 C++ 的头文件中使用 `#ifdef`, `#define`, 和 `#endif` 组合,主要是用来控制宏定义的条件编译,也就是实现针对特定编译环境或配置的代码选择性包含。这种技术的作用主要有以下几点:
1. **避免多次包含**:当一个头文件被其他多个地方包含时,如果里面定义了全局变量或函数,可能会导致重复定义错误。`#ifndef` 可以检查宏是否已经定义,如果没有,则包含头文件的内容;如果有,则跳过该部分内容,防止重复定义。
```c
#ifndef MY_MACRO
#define MY_MACRO
// 包含需要的代码...
#endif
```
2. **启用或禁用功能**:`#define` 宏常用来定义开关,通过设置不同宏值来控制特定功能的开启或关闭。如:
```c
#ifdef ENABLE_DEBUG
// 在调试模式下包含的代码...
#else
// 非调试模式下包含的代码...
#endif
```
3. **兼容不同版本**:对于不同版本的库或编译器,可以使用不同条件来处理兼容性问题。
总之,这些预处理器指令使得开发者可以在不修改已有代码的情况下,根据需求动态地添加、移除或调整头文件中的内容,提高了代码的灵活性和维护性。
相关问题
VC mfc单文档中代码如下void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); for (int i=0;i<points.size();i++){ color=RGB(rand()%256,rand()%256,rand()%256); r=rand()%46+5; br.CreateSolidBrush(color); pDC->SelectObject(&br); pDC->Ellipse(points[i].x-r,points[i].y-r,points[i].x+r,points[i].y+r); br.DeleteObject(); } // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CMyView printing BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMyView diagnostics #ifdef _DEBUG void CMyView::AssertValid() const { CView::AssertValid(); } void CMyView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CMyDoc* CMyView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); return (CMyDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMyView message handlers void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default center=point; r=rand()%46+5;//r=5~50 color=RGB(rand()%256,rand()%256,rand()%256); points.push_back(center); SetTimer(1,200,NULL); CView::OnLButtonDown(nFlags, point); } void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CView::OnLButtonUp(nFlags, point); } void CMyView::rise() { for(int i=0;i<points.size();i++) { points[i].y-=5; if(points[i].y<-r) { points.erase(points.begin()+i); i--; } } } void CMyView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent==1){ RedrawWindow(); rise(); } CView::OnTimer(nIDEvent); },运行效果中圆在上升过程中颜色和大小不停的变换,应怎么修改此代码使得圆在上升过程中的大小和颜色不会变换,完整步骤及代码
要使圆在上升过程中大小和颜色不会变换,可以将颜色和大小的变化单独提取出来,放到循环外面进行定义,然后再在循环内部进行圆的上升操作。具体实现方式如下:
1. 在头文件中定义变量:
```cpp
// 头文件中定义变量
COLORREF color; // 圆的颜色
int r; // 圆的半径
```
2. 在`OnDraw`函数中修改绘制圆的代码:
```cpp
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 绘制圆
for (int i = 0;i < points.size();i++)
{
// 保持颜色和大小不变
color = RGB(0, 0, 255); // 蓝色
r = 20;
// 绘制圆
CPen pen(PS_SOLID, 1, color);
CBrush brush(color);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(points[i].x - r, points[i].y - r, points[i].x + r, points[i].y + r);
}
}
```
在这个代码中,我们将颜色和大小的变化都删除了,直接将颜色设置为蓝色,大小设置为20。这样就可以让圆在上升过程中保持颜色和大小不变了。
完整修改后的代码如下:
MyView.h文件:
```cpp
#pragma once
#include "MyDoc.h"
#include <vector>
class CMyView : public CView
{
protected: // create from serialization only
CMyView() noexcept;
DECLARE_DYNCREATE(CMyView)
// Attributes
public:
CMyDoc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC) override;
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate() override; // called first time after construct
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/) override;
// Implementation
public:
virtual ~CMyView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT_PTR nIDEvent);
void rise();
};
#ifndef _DEBUG // debug version in MyView.cpp
inline CMyDoc* CMyView::GetDocument() const
{ return reinterpret_cast<CMyDoc*>(m_pDocument); }
#endif
```
MyView.cpp文件:
```cpp
#include "pch.h"
#include "framework.h"
#include "My.h"
#include "MyDoc.h"
#include "MyView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
END_MESSAGE_MAP()
// CMyView construction/destruction
CMyView::CMyView() noexcept
{
// TODO: add construction code here
}
CMyView::~CMyView()
{
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
// CMyView drawing
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 绘制圆
for (int i = 0;i < points.size();i++)
{
// 保持颜色和大小不变
color = RGB(0, 0, 255); // 蓝色
r = 20;
// 绘制圆
CPen pen(PS_SOLID, 1, color);
CBrush brush(color);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(points[i].x - r, points[i].y - r, points[i].x + r, points[i].y + r);
}
}
void CMyView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
}
void CMyView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: Add your specialized code here and/or call the base class
}
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
// CMyView message handlers
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
center = point;
r = rand() % 46 + 5;
color = RGB(rand() % 256, rand() % 256, rand() % 256);
points.push_back(center);
SetTimer(1, 200, NULL);
CView::OnLButtonDown(nFlags, point);
}
void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnLButtonUp(nFlags, point);
}
void CMyView::rise()
{
for (int i = 0;i < points.size();i++)
{
points[i].y -= 5;
if (points[i].y < -r)
{
points.erase(points.begin() + i);
i--;
}
}
}
void CMyView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == 1) {
RedrawWindow();
rise();
}
CView::OnTimer(nIDEvent);
}
```
这样修改后,圆在上升过程中的大小和颜色就不会变换了。
linuxC FILE头文件
`<stdio.h>`头文件中定义了`FILE`结构体类型和一系列与文件输入输出相关的函数。`FILE`结构体类型用于表示文件流,其中包含了文件指针、文件状态标志以及缓冲区等信息,它的定义如下:
```c
struct _IO_FILE {
int _flags; // 文件状态标志
char* _IO_read_ptr; // 缓冲区读取指针
char* _IO_read_end; // 缓冲区读取结束位置指针
char* _IO_read_base; // 缓冲区读取起始位置指针
char* _IO_write_base; // 缓冲区写入起始位置指针
char* _IO_write_ptr; // 缓冲区写入指针
char* _IO_write_end; // 缓冲区写入结束位置指针
char* _IO_buf_base; // 缓冲区基地址指针
char* _IO_buf_end; // 缓冲区结束地址指针
char *_IO_save_base; // 存储缓冲区起始位置指针
char *_IO_backup_base;// 存储缓冲区当前位置指针
char *_IO_save_end; // 存储缓冲区结束位置指针
struct _IO_marker *_markers;// 标记缓冲区的指针
struct _IO_FILE *_chain;// 指向链表下一个_FILE结构体指针
int _fileno; // 文件描述符号,代表打开的文件
int _flags2; // 预留字段
__off_t _old_offset; // 上一次读写时候的偏移量
#define __HAVE_COLUMN /* temporary */ // 预留字段
unsigned short _cur_column;// 当前读写指针所在行的位置
signed char _vtable_offset;// 预留字段
char _shortbuf; // 预留字段,用于提高性能
_IO_lock_t *_lock; // 文件锁的指针
#ifdef _IO_USE_OLD_IO_FILE
};
```
常用的文件输入输出函数包括:
- `fopen`:打开文件并返回文件流指针。
- `fclose`:关闭文件。
- `fread`:从文件流中读取数据。
- `fwrite`:向文件流中写入数据。
- `fprintf`:将格式化数据输出到文件流中。
- `fscanf`:从文件流中读取格式化数据。
- `feof`:判断是否到达文件末尾。
- `fseek`:设置文件流的读写位置。
- `ftell`:获取当前读写位置。
- `rewind`:将文件流的读写位置重置为开头。
阅读全文