LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 870|回复: 3

大家来看看这段c语言中的一些用法!!!

[复制链接]
发表于 2006-3-14 22:08:37 | 显示全部楼层 |阅读模式
这个define也太。。。。。

make_ ## 是什么意思
多次出现的##是什么意思,我查不到啊

#define HASH_CODE(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ, KEY_COPY,  \
                  KEY_FREE, NULL_VALUE, VALUE_FREE)                            \
        \
/* HASH_HEADER(HASH, HASH_KEY, HASH_VALUE); */ \
        \
HASH make_ ## HASH(size_t initial_size)        \
{        \
  HASH ht;        \
  ht = (HASH) MALLOC(sizeof(struct HASH ## _table));        \
  ht->tablesize = preferred_size(initial_size);        \
  ht->size = 0;         \
  ht->table = (HASH ## _cell_ptr *)        \
    CALLOC(ht->tablesize, (size_t) sizeof(HASH ## _cell_ptr));        \
  return ht;        \
}           \
        \
size_t HASH ## _size(HASH ht) \
{                             \
  return ht->size;            \
}                             \
        \
          \
static void HASH ## _resize(HASH ht)        \
{        \
  HASH ## _cell_ptr *oldtable = ht->table;        \
  size_t oldtablesize = ht->tablesize;        \
  size_t tablesize = preferred_size(ht->size);        \
  size_t i;        \
  HASH ## _cell_ptr        p, nextp;        \
          \
  ht->tablesize = tablesize;        \
  ht->table = (HASH ## _cell_ptr *)         \
    CALLOC(tablesize, (size_t) sizeof(HASH ## _cell_ptr));        \
          \
  for (i=0; i<oldtablesize; i++)        \
    for (p = oldtable; p; p = nextp) {        \
      nextp = p->next;        \
      p->next = ht->table[p->hashedkey%tablesize];        \
      ht->table[p->hashedkey%tablesize] = p;        \
    }        \
          \
  FREE(oldtable);        \
}        \
        \
HASH ## _cell_ptr HASH ## _find(HASH ht, const HASH_KEY key)         \
{         \
  size_t hashedkey = KEY_HASH(key);        \
  size_t hashedkeymod = hashedkey%ht->tablesize;        \
  HASH ## _cell_ptr p = ht->table[hashedkeymod];        \
          \
  while (p && (p->hashedkey != hashedkey || KEY_NEQ(key, p->key)))        \
    p = p->next;        \
        \
  if (p)         \
    return p;        \
  else {        \
    if (ht->size++ >= HASH_EXPAND_LOAD_FACTOR*ht->tablesize) {        \
      HASH ## _resize(ht);        \
      hashedkeymod = hashedkey%ht->tablesize;        \
    }        \
    p = MALLOC(sizeof(struct HASH ## _cell));        \
    p->hashedkey = hashedkey;        \
    p->key = KEY_COPY(key);        \
    p->value = NULL_VALUE;        \
    p->next = ht->table[hashedkeymod];        \
    ht->table[hashedkeymod] = p;        \
    return p;                        \
}}        \
          \
HASH_VALUE *HASH ## _valuep(HASH ht, const HASH_KEY key)              \
{        \
  return(&(HASH ## _find(ht, key)->value));        \
}        \
        \
HASH_VALUE HASH ## _ref(const HASH ht, const HASH_KEY key)        \
{        \
  size_t hashedkey = KEY_HASH(key);        \
  HASH ## _cell_ptr p = ht->table[hashedkey%ht->tablesize];        \
        \
  while (p && (p->hashedkey != hashedkey || KEY_NEQ(key, p->key)))        \
    p = p->next;        \
        \
  return p ? p->value : NULL_VALUE;        \
}        \
        \
HASH_VALUE HASH ## _set(HASH ht, HASH_KEY key, HASH_VALUE value)        \
{        \
  HASH ## _cell_ptr p = HASH ## _find(ht, key);        \
  HASH_VALUE oldvalue = p->value;                \
  p->value = value;                                \
  return oldvalue;                                \
}        \
        \
HASH_VALUE HASH ## _delete(HASH ht, HASH_KEY key)       \
{       \
  HASH_VALUE oldvalue;  \
  size_t hashedkey = KEY_HASH(key);     \
  HASH ## _cell_ptr     *p  = ht->table + hashedkey%ht->tablesize;      \
        \
  while ( *p &&         \
          ((*p)->hashedkey != hashedkey || KEY_NEQ(key, (*p)->key)) )  \
    p = &((*p)->next); \
        \
  if (*p) {     \
    oldvalue = (*p)->value;     \
    *p = (*p)->next;    \
    KEY_FREE((*p)->key);        \
    FREE(*p);   \
        \
    if (--ht->size < ht->tablesize/HASH_CONTRACT_LOAD_FACTOR)   \
      HASH ## _resize(ht);      \
    return oldvalue;                \
  }                        \
  else                       \
    return NULL_VALUE; \
}                       \
                         \
                                                  \
void free_ ## HASH(HASH ht)                        \
{                                                \
  HASH ## _cell_ptr p, q;                        \
  size_t  i;                                        \
                                                  \
  for (i = 0; i < ht->tablesize; i++)                                        \
    for (p = ht->table; p; p = q) {                                        \
      q = p->next;                                                        \
      KEY_FREE(p->key);                                                        \
      VALUE_FREE(p->value);                                                \
      FREE(p);                                                                \
    }                                                                        \
  FREE(ht->table);                                                        \
  FREE(ht);                                                                \
}                                                                        \
                                                                          \
/*************************************************************************** \
*                                                                         * \
*                           hash iteration                                * \
*                                                                         * \
***************************************************************************/ \
                                                                          \
                                                                          \
HASH ## it HASH ## it_init(HASH ht)                                        \
{                                                                        \
  struct HASH ## it hit = {0, NULL_VALUE, ht, NULL, 0};                        \
  return HASH ## it_next(hit);                                                \
}                                                                        \
                                                                        \
HASH ## it HASH ## it_next(HASH ## it hit0)                                \
{                                                                        \
  if (hit0.next) {                                                        \
    hit0.key = hit0.next->key;                                                \
    hit0.value = hit0.next->value;                                        \
    hit0.next = hit0.next->next;                                        \
    return hit0;                                                        \
  }                                                                        \
  else {                                                                \
    size_t i = hit0.index;                                                \
    size_t tablesize = hit0.ht->tablesize;                                \
    HASH ## _cell_ptr *table = hit0.ht->table;                                \
    while (i < tablesize && !table)                                        \
      i++;                                                                \
    if (i==tablesize) {                                                        \
      hit0.ht = NULL;                                                        \
      return hit0;                                                        \
    }                                                                        \
    else {                                                                \
      hit0.key = table->key;                                                \
      hit0.value = table->value;                                        \
      hit0.next = table->next;                                        \
      hit0.index = i+1;                                                        \
      return hit0;                                                        \
    }}}                                                                        \
                                                                          \
int HASH ## it_ok(HASH ## it hit)                                        \
{                                                                        \
  return hit.ht!=NULL;                                                        \
}

#define HASH_CODE_ADD(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ,    \
                      KEY_COPY, KEY_FREE, NULL_VALUE, VALUE_FREE)       \
                                                                        \
HASH_CODE(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ,                \
                KEY_COPY, KEY_FREE, NULL_VALUE, VALUE_FREE)             \
                                                                        \
HASH_VALUE HASH ## _inc(HASH ht, const HASH_KEY key, HASH_VALUE inc)        \
{                                                                        \
/*  size_t hashedkey = KEY_HASH(key); */        \
  HASH ## _cell_ptr p = HASH ## _find(ht, key);        \
          \
  p->value += inc;        \
  return p->value;        \
}
发表于 2006-3-15 00:29:53 | 显示全部楼层
##就是连接符。你看这段代码

  1. #include <stdio.h>
  2. #define CAT_NUM(NUM1,NUM2) NUM1 ## NUM2

  3. int
  4. main()
  5. {
  6.         printf("%d\n", CAT_NUM(12,34));
  7.         return 0;
  8. }
复制代码


输出结果为 1234
直接用如下写法是会报参数NUM1NUM2未声明的
#define CAT_NUM(NUM1,NUM2) NUM1NUM2
回复 支持 反对

使用道具 举报

发表于 2006-3-15 03:01:27 | 显示全部楼层
nngx, 为什么不用inline来实现阿?
回复 支持 反对

使用道具 举报

发表于 2006-3-15 08:59:54 | 显示全部楼层
inline无法实现##这种功能。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表