目录
4 解决 error C2146: 语法错误: 缺少“;”(在标识符“PVOID64”的前面)
1 #define定义函数块
C/C++ 语言中,除了可以用 #define 定义一个标识符来表示一个常量,还可以用 #define 定义函数,例如:
//定义常量
#define MAX_VALUE 100 //定义整型变量MAX_VALUE值为100
#define USER_NAME "huge" //定义字符串变量USER_NAME值为"huge"
#define PI 3.1415926 //定义浮点数变量PI值为3.1415926
//定义简单函数
#define MAX(a,b) (a>b)?a:b //取两个数最大值
#define MIN(a,b) (a<b)?a:b //取两个数最小值
//定义复杂多行的函数
#define MACRO(arg1, arg2) do { \
\
stmt1; \
stmt2; \
\
} while(0)
//关键是要在每一个换行的时候加上一个 "\ "
凡是以 #
开头的均为预处理指令,预处理又叫预编译。预编译不是编译,而是编译前的处理。这个操作是在正式编译之前由系统自动完成的。
#define后面定义的内容必须在同一行,而有时是为了让程序便于阅读,从中间进行换行,如果没有符号'\',则我们的换行表示 #define的结束。如果在这里加了'\',也可以说是对"回车"的转义,表示这里有一个回车字符而已,#define并没有结束.而程序编译的时候,编译器会忽略掉这些'\回车'的字符.
使用define定义一个多行的复杂函数
,关键是要在每一个换行的时候加上一个 \
;
2 C++异常处理机制
C++中的异常处理主要依靠三个关键词:try
、catch
和 throw
。
-
try:包裹可能抛出异常的代码块。
-
catch:捕获并处理特定类型的异常。
-
throw:用于抛出异常对象。
try {
// 可能抛出异常的代码
throw std::runtime_error("发生错误");
} catch (const std::exception& e) {
// 处理异常
std::cerr << "捕获到异常: " << e.what() << '\n';
}
#include "stdafx.h"
#include "iostream"
using namespace std;
int test1()
{
try
{
char *p = new char[0x7fffffff]; //抛出异常
}
catch (exception e)
{
cout << e.what() << endl; //捕获异常,然后程序结束
return -1;
}
return 0;
}
int main()
{
printf("%d\n",test1());
return 0;
}
3 常用宏/函数
3.1 判断运行模式(debug、release)
在Debug模式下调试程序时,有可能需要程序执行额外的操作,比如输出值,显示额外信息;但是这些信息在Release模式下是不需要的,这时候可以通过下面的代码来进行干涉。
#ifdef _DEBUG
#else
#endif // _DEBUG
3.2 判断运行环境(win32、win64)
类似地,可以判断是否处于32位模式:
#ifdef WIN32
#else
#endif // WIN32
其中提到的_DEBUG、WIN32不需要自己在代码中定义,已经在VS预处理器中定义好了,可以通过以下推荐查看属性管理器 -> Debug | Win32 -> 右键"属性" -> 通用属性 -> C/C++ -> 预处理器 -> 预处理器定义
3.3 C++调用C库的方法
C++调用C的函数比较简单,直接使用extern "C" {}
告诉编译器用C的规则去调用C函数就可以了。
CAdd.h
//CAdd.h
int cadd(int x, int y);
CAdd.c
//CAdd.c
#include "CAdd.h"
#include <stdio.h>
int cadd(int x, int y) {
printf("from C function.\n");
return (x + y);
}
cppmain.cpp
//cppmain.cpp
#include <stdio.h>
extern "C" {
#include "CAdd.h"
}
int main()
{
int sum = cadd(1, 2);
printf("1+2 = %d\n", sum);
return 0;
}
这里是在include头文件的外面包裹了extern "C" { }
,是告诉编译器以C语言的命名方式去加载这个符号。
还有一种比较常见的方式是在头文件中进行编译声明,如下所示,这样的话,无论C还是C++直接正常include
就可以使用了。
CAdd.h
//CAdd.h
#ifdef __cplusplus
extern "C" {
#endif
int cadd(int x, int y);
#ifdef __cplusplus
}
#endif
3.4 MFC下使用控制台输出调试信息
// 1、使用AllocConsole在MFC程序中调用控制台调试输出
//(1)打开控制台资源,重定向输出流至控制台
AllocConsole();
freopen("CONOUT$", "w+t", stdout); //申请控制台输出支持
//freopen("CONIN$", "r+t", stdin); //申请控制台输入支持
//(2)执行调试信息输出操作
printf("welcome to use console using printf\n"); //在程序的任意位置,如果想输入信息,都可以这样做
std::cout << "welcome to use console using std::cout" << std::endl;
//char ch = getchar(); //读数据
//(3)释放控制台资源,这一句放在程序退出的时候
FreeConsole();
//2、使用重定向cout.rdbuf()将调试输出打印到文件
//(1)C++标准输出流换向(cout.rdbuf()打印到文件)
ofstream fout("d:\\log.txt"); //文件输出流对象
streambuf* pOld = cout.rdbuf(fout.rdbuf());
//(2)在程序的任意位置,如果想输入信息,都可以这样做
std::cout << "welcome to use log_file using std::cout" << std::endl;
//(3)用于恢复 标准输出
cout.rdbuf(pOld);
3.5 Edit控件显示日志信息
void CWriteToolDlg::ShowMessage(char *lpMsg,bool IsAddTime)
{
SYSTEMTIME tm;
GetLocalTime(&tm);
char szTime[30] = {0};
sprintf(szTime, "%02d:%02d:%02d", tm.wHour,tm.wMinute,tm.wSecond);
char message[4096] = {0};
sprintf(message,"[%s] %s",szTime,lpMsg);
CEdit* pMsgInfo = (CEdit*)GetDlgItem(IDC_EDIT_INFO);
pMsgInfo->SetSel(pMsgInfo->GetWindowTextLength(),
pMsgInfo->GetWindowTextLength());
if (IsAddTime)
pMsgInfo->ReplaceSel(message);
else
pMsgInfo->ReplaceSel(lpMsg);
pMsgInfo->ReplaceSel("\r\n");
}
void CWriteToolDlg::ResetMessage()
{
CEdit* pMsgInfo = (CEdit*)GetDlgItem(IDC_EDIT_INFO);
pMsgInfo->SetWindowText("");
pMsgInfo->Invalidate();
}
3.6 以十六进制显示内存数据
#include <stdio.h>
static void display_buffer_hex(unsigned char *buffer, unsigned size)
{
unsigned i, j, k;
for (i=0; i<size; i+=16) {
printf("\n %08x ", i);
for(j=0,k=0; k<16; j++,k++) {
if (i+j < size) {
printf("%02x", buffer[i+j]);
} else {
printf(" ");
}
printf(" ");
}
printf(" ");
for(j=0,k=0; k<16; j++,k++) {
if (i+j < size) {
if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
printf(".");
} else {
printf("%c", buffer[i+j]);
}
}
}
}
printf("\n" );
}
4 解决 error C2146: 语法错误: 缺少“;”(在标识符“PVOID64”的前面)
错误结果如图:
跑程序遇见这个问题,查看错误根源说是PVOID64未定义,查找资料原因说是头文件搜索顺序引起的。
通过添加在stdafx.h的开头,加上以下代码通过编译:
#ifndef POINTER_64
#if !defined(_MAC) && (defined(_M_MRX000) || defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_VER >= 1100) && !(defined(MIDL_PASS) || defined(RC_INVOKED))
#define POINTER_64 __ptr64
typedef unsigned __int64 POINTER_64_INT;
#if defined(_WIN64)
#define POINTER_32 __ptr32
#else
#define POINTER_32
#endif
#else
#if defined(_MAC) && defined(_MAC_INT_64)
#define POINTER_64 __ptr64
typedef unsigned __int64 POINTER_64_INT;
#else
#if (_MSC_VER >= 1300) && !(defined(MIDL_PASS) || defined(RC_INVOKED))
#define POINTER_64 __ptr64
#else
#define POINTER_64
#endif
typedef unsigned long POINTER_64_INT;
#endif
#define POINTER_32
#endif
#endif
5 C++程序只允许运行一个实例
#define _SESSION_MUTEX_ "SESSION_MUTEX"
bool checkMyselfExist() //如果程序已经有一个在运行,则返回true
{
HANDLE hMutex = CreateMutex(NULL, FALSE, _SESSION_MUTEX_ );
if (hMutex && (GetLastError() == ERROR_ALREADY_EXISTS))
{
CloseHandle(hMutex);
hMutex = NULL;
return true;
}
else{
return false;
}
}
int main()
{
if (checkMyselfExist()){
cout << "program has been runnin" << endl;
}
else{
cout << "start running" << endl;
}
system("pause");
return 0;
}