⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c.txt

📁 C语言编程常见问题解答 这个帖子将不断扩充、更新 罗列大部分C语言编程的常见问题 希望各位观众支持帮助 毕竟一人之力太有限
💻 TXT
📖 第 1 页 / 共 5 页
字号:
61: / * Sort strings using your own implementation of quick sort * /
62: void sortStrings (char * array[])
63: {
64:       / * First, determine the length of the array * /
65:       int num
66:
67:       for (num = O; array[num] ; num++ )
68:
69:       myQsort((void * ) array, num)
70: }

--------------------------------------------------------------------------------
 
--  作者:PrOve
--  发布时间:2005-4-6 13:09:06

--  
16.什么是哈希查找?
  哈希查找的本质是先将数据映射成它的哈希值。哈希查找的核心是构造一个哈希函数,它将原来直观、整洁的数据映射为看上去似乎是随机的一些整数。
    哈希查找的产生有这样一种背景——有些数据本身是无法排序的(如图像),有些数据是很难比较的(如图像)。如果数据本身是无法排序的,就不能对它们进行比较查找。如果数据是很难比较的,即使采用折半查找,要比较的次数也是非常多的。因此,哈希查找并不查找数据本身,而是先将数据映射为一个整数(它的哈希值),并将哈希值相同的数据存放在同一个位置一即以哈希值为索引构造一个数组。
    在哈希查找的过程中,只需先将要查找的数据映射为它的哈希值,然后查找具有这个哈希值的数据,这就大大减少了查找次数。如果构造哈希函数的参数经过精心设计,内存空间也足以存放哈希表,查找一个数据元素所需的比较次数基本上就接近于一次。
    影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。解决冲突的方法有以下两种:
    (1) 开放定址法
    如果两个数据元素的哈希值相同,则在哈希表中为后插入的数据元素另外选择一个表项。
当程序查找哈希表时,如果没有在第一个对应的哈希表项中找到符合查找要求的数据元素,程序就会继续往后查找,直到找到一个符合查找要求的数据元素,或者遇到一个空的表项。
    (2) 链地址法
    将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。
    例是一个简单的哈希查找算法程序,你可以将它和本章结尾的有关代码一起编译连接成一个可执行程序。

    例 一个简单的哈希查找算法程序
1: #include<stdlib.h>
2: #include<string.h>
3: #include "list.h"
4: #include "hash.h"
5:
6: #define HASH_SIZE   1024
7:
8: static listnode_t  *hashTable[HASH_SIZE];
9:
10: void insert(const char * s)
11: {
12:     listnode_t  *ele = newNode((void * ) s)
13:     unsigned int  h = hash(s) % HASH_SIZE;
14:
15:     ele->next = hashTable[h]
16:     hashTable[h] = ele;
17: }
18:
19: void print (void)
20: {
21:      int  h;
22:
23:      for (h = 0; h < HASH_SIZE; h++)
24:      {
25:           listnode_t   * lp = hashTalbe[h];
26:
27:           if(lp == NULL)
28:                 continue;
29:            printf("[%d]" , h);
30:            while (lp)
31:            {
32:                  printf("\\t\'%s\'" , lp->u.str)
33:                  lp = ip->next;
34:            }
35:            putchar (\'\\n\');
36:      }
37: }
38:
39: const char *search(const char *s)
40: {
39:       unsigned int   h = hash(s) % HASH_SIZE;
42:       listnode_t * lp = hashTable[h];
43:
44:       while (lp)
45:       {
46:              if (! strcmp (s, lp->u.str))
47:                    return lp->u.str;
48:              lp = lp->next;
49:       }
50:       return NULL;
51: }

--------------------------------------------------------------------------------
 
--  作者:PrOve
--  发布时间:2005-4-6 13:10:33

--  
17.什么是宏(macro)?怎样使用宏?
    宏是一种预处理指令,它提供了一种机制,可以用来替换源代码中的字符串,宏是用“#define"语句定义的,下面是一个宏定义的例子:
    #define VERSION—STAMP "1.02"

    上例中所定义的这种形式的宏通常被称为标识符。在上例中,标识符VERSION_STAMP即代表字符串"1.02"——在编译预处理时,源代码中的每个VERSION_STAMP标识符都将被字符串“1.02”替换掉。
    以下是另一个宏定义的例子:
    #define CUBE(x)((x),(x)*(x))
    上例中定义了一个名为CUBE的宏,它有一个参数x。CUBE宏有自己的宏体,即((x)*(x)*(x))——在编译预处理时,源代码中的每个CUBE(x)宏都将被((x)*(x)*(x))替换掉。
    使用宏有以下几点好处;
    (1)在输入源代码时,可省去许多键入操作。    
    (2)因为宏只需定义一次,但可以多次使用,所以使用宏能增强程序的易读性和可靠性。
    (3)使用宏不需要额外的开销,因为宏所代表的代码只在宏出现的地方展开,因此不会引起程序中的跳转。
    (4)宏的参数对类型不敏感,因此你不必考虑将何种数据类型传递给宏。
    需要注意的是,在宏名和括起参数的括号之间绝对不能有空格。此外,为了避免在翻译宏时产生歧义,宏体也应该用括号括起来。例如,象下例中这样定义CUBE宏是不正确的:
denne CUBE(x)   x * x * x
  对传递给宏的参数也要小心,例如,一种常见的错误就是将自增变量传递给宏,请看下例:
#include <stdio. h>
#include CUBE(x) (x * x * x)
void main (void);
void main (void)
{
    int x, y;
    x = 5;
    y = CUBE( + +x);
    printfC\'y is %d\\n" . y);
}

    在上例中,y究竟等于多少呢?实际上,y既不等于125(5的立方),也不等于336(6* 7*8),而是等于512。因为变量x被作为参数传递给宏时进行了自增运算,所以上例中的CUBE宏实际上是按以下形式展开的:
    y = ((++x) * (++x) * (++x));
    这样,每次引用x时,x都要自增,所以你得到的结果与你预期的结果相差很远,在上例中,由于x被引用了3次,而且又使用了自增运算符,因此,在展开宏的代码时,x实际上为8,你将得到8的立方,而不5的立方。
    上述错误是比较常见的,作者曾亲眼见过有多年C语言编程经验的人犯这种错误。因为在程序中检查这种错误是非常费劲的,所以你要给予充分的注意。你最好试一下上面的例子,亲眼看一下那个令人惊讶的结果值(512)。
    宏也可使用一些特殊的运算符,例如字符串化运算符“#”和。连接运算符“##”。“#”运算符能将宏的参数转换为带双引号的字符串,请看下例:
    define DEBUG_VALUE(v)  printf(#v"is equal to %d.\\n",v)
    你可以在程序中用DEBUG_VALUE宏检查变量的值,请看下例:
    int x=20;
    DEBUG_VALUE(x);
    上述语句将在屏幕上打印"x is equal to 20"。这个例子说明,宏所使用的“#”运算符是一种非常方便的调试工具。

--------------------------------------------------------------------------------
 
--  作者:PrOve
--  发布时间:2005-4-6 13:11:29

--  
18.预处理程序(preprocessor)有什么作用?    
    C语言预处理程序的作用是根据源代码中的预处理指令修改你的源代码。预处理指令是一种命令语句(如#define),它指示预处理程序如何修改源代码。在对程序进行通常的编译处理之前,编译程序会自动运行预处理程序,对程序进行编译预处理,这部分工作对程序员来说是不可见的。
    预处理程序读入所有包含的文件以及待编译的源代码,然后生成源代码的预处理版本。在预处理版本中,宏和常量标识符已全部被相应的代码和值替换掉了。如果源代码中包含条件预处理指令(如#if),那么预处理程序将先判断条件,再相应地修改源代码。
    下面的例子中使用了多种预处理指令:
# include <stdio. h>
# define TRUE 1
# define FALSE (!TRUE)
# define GREATER (a, b) ((a) > (b) ? (TRUE) : (FALSE))
# define PIG-LATIN FALSE
void main (void);
void main (void)
{
    int x, y;
# if PIG_LATIN
    printf("Easeplay enternay ethay aluevay orfay xnay:") ;
    scanf("%d", &x) ;
    printf("Easeplay enternay ethay aluevay orfay ynay:");
    scanf("%d", &y);
#else
    printf(" Please enter the value for x: ");
    scanf("%d", &x);
    printf("Please enter the value for y: ");
    scanf("%d", &y);
# endif
    if (GREATER(x, y) = = TRUE)
    {
# if PIG- LATIN
    printf("xnay islay eatergray anthay ynay!\\n");
#else
    printf {" x is greater than y! \\n" ) ;
# endif
    }
    else
    {
# if PIG_LATIN
    printf ("xnay islay otnay eatergray anthay ynay!\\n");
#else
    printf ("x is not greater than y!\\n");
# endif
    }
}
   上例通过预处理指令定义了3个标识符常量(即TRUE,FALSE和PIG_LATIN)和一个宏(即GREATER(a,b)),并使用了一组条件编译指令。当预处理程序处理上例中的源代码时,它首先读入stdio.h头文件,并解释其中的预处理指令,然后把所有标识符常量和宏用相应的值和代码替换掉,最后判断PIG_LATIN是否为TRUE,并由此决定是使用拉丁文还是
使用英文。
    如果PIG_LATIN为FALSE,则上例的预处理版本将如下所示:
/ * Here is where all the include files
would be expanded. * /
void main (void)
{
    int x, y;
    printf("Please enter the value for X: ");
    scanf("%d", &x);
    printf("Please enter the value for y: ");
    scanf("%d", &y),
    if (((x) > (y) ? (1) : (!1)) == 1)
    {
        printf("x is greater than y!\\n");
    }
    else
    {
        printf{"x is not greater than y!\\n");
    }
}

    多数编译程序都提供了一个命令行选项,或者有一个独立的预处理程序,可以让你只启动预处理程序并将源代码的预处理版本保存到一个文件中。你可以用这种方法查看源代码的预处理版本,这对调试与宏或其它预处理指令有关的错误是比较有用的。

--------------------------------------------------------------------------------
 
--  作者:PrOve
--  发布时间:2005-4-6 13:12:04

--  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -