# 看看斯坦福大学是如何教学生编程的

```void *ISearch(void *key,  void *base, int n, int elementSize,
int (* Compare)(void *, void *))
{
int i = 0;
void *pTmp = NULL;
for (i = 0; i < n; i++)
{
pTmp = (char *)base + i*elementSize;
if (Compare(key, pTmp) == 0)
{
return pTmp;
}
}
return NULL;
}```

```int _tmain(int argc, _TCHAR* argv[])
{
int nArray[] = {3, 1, 45, 22, 0, 4};
int n = 6;
int key = 22;

int *findPosition = ISearch(&key, nArray, n, sizeof(int),
IntCompare);

if (findPosition == NULL)
{
printf("can not find the key!/n");
}
else
{
printf("find the key %d!/n", *findPosition);
}
return 0;
}```

```int IntCompare(void *element1, void *element2)
{
int *pTmp1 = element1;
int *pTmp2 = element2;

return (*pTmp1 - *pTmp2);
}```

```int _tmain(int argc, _TCHAR* argv[])
{
double nArray[] = {3.01, 1.00, 45.045, 22, 0, 4.1};
int n = 6;
double key = 4.099999;

double *findPosition = ISearch(&key, nArray, n, sizeof(double),
DoubleCompare);

if (findPosition == NULL)
{
printf("can not find the key!/n");
}
else
{
printf("find the key %lf!/n", *findPosition);
}
return 0;
}```

DoubleCompare函数在做一些特殊处理, 因为计算机是不能精确表示浮点数的, 因为计算机用的都是离散化的数据量，只能在一定的精度范围内表示浮点数. 所以我们不能直接用比较运算符直接操作浮点数. 我们可以设定一个阀值，规定两个浮点数的差的绝对值小于这个阀值，就认为两个数相等.

```int DoubleCompare(void *element1, void *element2)
{
double dLimit = 0.000001; //比较阀值,
int nRet = 0;
double *pTmp1 = element1;
double *pTmp2 = element2;

if ( (*pTmp1 - *pTmp2) > dLimit )
{
nRet = 1;
}
else if (((*pTmp1 - *pTmp2) < dLimit) && ((*pTmp1 - *pTmp2) > -dLimit))
{
nRet = 0;
}
else
{
nRet = -1;
}
return nRet;
}```

`char *strArrany[] = {"ab", "Bcddeee", "#*", "fB"};`

```int _tmain(int argc, _TCHAR* argv[])
{
char *strArrany[] = {"ab", "Bcddeee", "#*", "fB"};
int n = 4;
char *strKey = "fB";

char *findPosition = ISearch(&strKey, strArrany, n, sizeof(char *),
StrCompare);

if (findPosition == NULL)
{
printf("can not find the key!/n");
}
else
{
printf("find the key %s!/n", *findPosition);
}
return 0;
}```

```int StrCompare(void *element1, void *element2)
{
char *pTmp1 = *(char **)element1; //要比较的不是查找的元素本身，而是它指向的数据，所以要用两重指钍
char *pTmp2 = *(char **)element2;

return strcmp(pTmp1, pTmp2);
}```

```if (Compare(key, pTmp) == 0)
{
return pTmp;
}```

`void *ISearch(void *key,  void *base, int n, int elementSize, int (* Compare)(void *, void *));`

key指向的实参是什么呢? 在主函数中找到ISearch被调用的地方, 如下:

```char *strKey = "fB";
char **findPosition = ISearch(&strKey, strArrany, n, sizeof(char *),StrCompare);```

strKey本身是一个指向一个字符串常量(“fB”)的指针, 而传到ISearch里的是&strKey,也就是这个指针的地址. 所以, key就是一个指针, 这个指针的指向的值也是是一个指针, 这个指针指向的地址上放的内容是”fB”, 所以key实际上是一个char **的变量,从而element1也就是一个char **的变量. 又加一个”*”,这是通过解引用把指向”fB”的那个地址取出来.

```int StrCompare(void *element1, void *element2)
{
char **pTmp1 = element1; //
char **pTmp2 = element2;

return strcmp(*pTmp1, *pTmp2);
}```

0 条评论

• ### lua执行redis脚本找不到脚本的问题

有个项目，利用redis做统计功能。一向对性能追求极致的我怎么能随便写几条redis的统计语句就应付呢。于是我打算使用lua脚本把用到的几条redis指令封装一...

• ### 一文说透如何同步的方式操作HashMap

很多人都知道HashMap是非线程安全的。比如下面这段代码，多运行几次，基本每次会抛出异常：

• ### 从一个问题来解释下什么是mysql的可重复读

补充解释下这个问题，mysql环境，innodb引擎，事务的隔离级别是可重复读，一个表只有两个字段，然后插入4条数据，希望你构造上图中的一种情况，就是明明upd...

• ### C学习笔记（2）--指针

一、多文件结构总结 1.子源文件里面包含自己对应的头文件 2.无论是何源文件调用库函数，都需要包含该库函数的声明所在的头文件 3.头文件又叫接口文件，.c对数据...

• ### 从零开始学C++之模板（三）：缺省模板参数（借助标准模板容器实现Stack模板）、成员模板、关键字typename

一、缺省模板参数 回顾前面的文章，都是自己管理stack的内存，无论是链栈还是数组栈，能否借助标准模板容器管理呢？答案是肯定的，只需要多传一个模板参数即可，而且...

• ### 程序员C语言快速上手——进阶篇（六）

由上例可验证，数组的内存空间是连在一起的，它的第一个元素地址是0x22fe30，第二个元素的地址是0x22fe34，紧随其后。因为是int数组，每个元素都需要占...

• ### 在线教育平台开发中，如何接入sdk实现小班课

在线教育平台开发过程中，有些功能并不是通过公司一手打造的，而是通过接入第三方实现的，因为相比于重新开发，接入第三方反而更加保险和稳定，接下来，小编将以声网sdk...

• ### 深度解读 | 电信联通合并，到底意味着什么？

最近，关于电信联通合并的传闻此起彼伏，牵动着很多人的神经，也引起了行业内外的广泛关注。

• ### 哈希表问题-LeetCode 146、290、299、300（哈希表，双向链表，最小上升序列）

运用你所掌握的数据结构，设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作：获取数据 get 和 写入数据 put 。