为什么不设置无穷大为0x7fffffff而是0x3f3f3f3f

把INF设置为0x3f3f3f3f的理由:

0x7fffffff不能满足“无穷大加一个有穷的数依然是无穷大”这个条件,它会变成了一个很小的负数。

更进一步的,如果有一个数能够满足“无穷大加无穷大依然是无穷大”,那么就更好了!

而INF=0x3f3f3f3f,这个值的设置真的很精妙!

0x3f3f3f3f的十进制是1061109567,是10^9级别的(和0x7fffffff一个数量级),而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。

另一方面,由于一般的数据都不会大于10^9,所以当我们把无穷大加上一个数据时,它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”),事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围,所以0x3f3f3f3f还满足了我们“无穷大加无穷大还是无穷大”的需求。

最后,0x3f3f3f3f还能给我们带来一个意想不到的额外好处:

如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a)),方便又高效,但是当我们想将某个数组全部赋值为无穷大时,就不能使用memset函数而得自己写循环了,因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0(一般我们只有赋值为-1和0的时候才使用它)。现在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是0x3f!所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。

所以在通常的场合下,0x3f3f3f3f真的是一个非常棒的选择!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXV 100 // 最大顶点数 #define INF 0x3f3f3f // 无穷大 char vertex[MAXV][20]; // 顶点名称 int matrix[MAXV][MAXV]; // 邻接矩阵 int visited[MAXV]; // 标记数组,用于深度遍历 int queue[MAXV]; // 队列,用于广度遍历 int front = 0; // 队首指针 int rear = 0; // 队尾指针 struct Edge { int start; // 起点在vertex数组中的下标 int end; // 终点在vertex数组中的下标 int weight; // 权值 }; void createGraph(int m, int n) { int i,j; // 输入顶点名称 for (i = 0; i < m; i++) { scanf("%s", vertex[i]); } // 初始化邻接矩阵 memset(matrix, INF, sizeof(matrix)); // 输入边的信息 for (i = 0; i < n; i++) { char start[20], end[20]; int weight; scanf("%s %s %d", start, end, &weight); int u = -1, v = -1; for (j = 0; j < m; j++) { if (strcmp(start, vertex[j]) == 0) { u = j; } if (strcmp(end, vertex[j]) == 0) { v = j; } if (u != -1 && v != -1) { break; } } matrix[u][v] = matrix[v][u] = weight; } } void dfs(int u) { int v; visited[u] = 1; printf("%s ", vertex[u]); for (v = 0; v < MAXV; v++) { if (matrix[u][v] != INF && visited[v] == 0) { dfs(v); } } } void bfs(int u, int m) { int v,w; printf("%s ", vertex[u]); visited[u] = 1; queue[rear++] = u; while (front != rear) { v = queue[front++]; for (w = 0; w < m; w++) { if (matrix[v][w] != INF && visited[w] == 0) { printf("%s ", vertex[w]); visited[w] = 1; queue[rear++] = w; } } } } int main() { int m, n,i; scanf("%d %d", &m, &n); createGraph(m, n); memset(visited, 0, sizeof(visited)); char start[20]; scanf("%s", start); int u = -1; for (i = 0; i < m; i++) { if (strcmp(start, vertex[i]) == 0) { u = i; break; } } dfs(u); printf("\n"); memset(visited, 0, sizeof(visited)); front = rear = 0; bfs(u, m); printf("\n"); return 0; }看看这段代码有没有问题,并给出修改后的代码
05-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值