65.9K
CodeProject 正在变化。 阅读更多。
Home

C & C++ 语言技巧

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (7投票s)

2000 年 3 月 4 日

viewsIcon

87810

更多适用于不使用运行时库的程序员的技巧。

引言

本文收集了一些在 C 和 C++ 中可能实现的有趣结构。虽然这些特性“不错”,但它们可能无法提高代码的可读性,反而会混淆代码。效果因人而异。


玩转 C 栈

栈上的参数在内存中以从左到右的顺序排列,最左边的项目位于最低的内存位置。因此,您可以获取指向函数栈帧的指针,遍历参数列表,甚至将您的栈帧转换为可以传递给其他函数的结构体。

第一个示例演示了如何检索传递给函数的任何变量参数的指针。

int __cdecl printf(char const* pszFmt,...)
{
  char buf[1024];
  return wvsprintf(buf,pszFmt,&pszFmt+1);
}

此示例演示了如何将传递给函数的函数传递给另一个函数。

BOOL InvalidateRect(
  HWND hwnd,
  LONG left,
  LONG top,
  LONG right,
  LONG bottom,
  BOOL fErase)
{
  return InvalidateRect(hwnd,(LPRECT)&left,fErase);
}


构造变长结构体

使用具有可变大小成员的结构体的一种技巧是使用重载的运算符使用 `new` 分配结构体的空间。

struct string {
  int cb; // a data member
  char sz[]; // the string data

  void* operator new(int cb, int cbExtra){
    return new char[cb+cbExtra];
  }
};

现在对比以下代码来创建这样的结构体

  ...
  string* pStr = new(strlen(pszInString)) string;
  ...

使用可变大小的“C”方法如下所示

  ...
  string* = (string*)new char[sizeof(string) + strlen(pszInString)];
  ...


处理大端数据

我一直更喜欢小端数字表示法而不是大端表示法,这就是为什么当我发现 TCP/IP 以及大多数互联网协议(例如 SSL3)使用大端表示法来表示数字时感到难过。以下是我在需要处理从网络上获取的结构体中的非本机数据类型时使用的构造类型。

typedef unsigned char uint8;

struct uint16 {
  uint8 n[2];

  operator unsigned short(){
    return ((unsigned short)n[0] << 8) + n[1];
  }
};

使用像这样的结构体有两个优点

  1. 如果使用了 `typedef unsigned short`,您可能会在没有转换的情况下在某些情况下意外地使用该数字。
  2. 运算符 `unsigned short` 确保可以在需要时将结构体用作普通的无符号短整型。

请通过 电子邮件 发送任何评论或错误报告。有关本文的任何更新,请查看我的网站 此处

© . All rights reserved.