1 00:00:00,000 --> 00:00:02,350 >> [音乐播放] 2 00:00:02,350 --> 00:00:05,444 3 00:00:05,444 --> 00:00:06,360 DOUG LLOYD:好吧。 4 00:00:06,360 --> 00:00:07,770 有种奇怪的话题,对吧? 5 00:00:07,770 --> 00:00:09,050 幻数。 6 00:00:09,050 --> 00:00:12,012 什么母鹿他的意思时,他的 谈到幻数? 7 00:00:12,012 --> 00:00:14,220 嗯,有些节目 我们已经写在CS50 8 00:00:14,220 --> 00:00:16,660 到目前为止,已经有一些怪异 样的数字扔在他们。 9 00:00:16,660 --> 00:00:19,680 也许对于原因,我们不 完全理解现在。 10 00:00:19,680 --> 00:00:23,950 例如,在马里奥问题,我们 皑皑的金字塔的高度在23。 11 00:00:23,950 --> 00:00:26,880 我们明确地说你 不能去高于23。 12 00:00:26,880 --> 00:00:28,702 >> 但什么是23是什么意思? 13 00:00:28,702 --> 00:00:30,410 好吧,如果你读了 仔细SPEC,你 14 00:00:30,410 --> 00:00:32,493 可能已经看到, 因此,我们就封顶在23 15 00:00:32,493 --> 00:00:36,160 是因为标准高度 终端窗口是24。 16 00:00:36,160 --> 00:00:38,860 所以,如果我们有 金字塔比这更高, 17 00:00:38,860 --> 00:00:41,290 它可能会做这种怪异的事情 它跑出画面。 18 00:00:41,290 --> 00:00:45,140 你知道有哪些呢 这意味着在上下文中,对不对? 19 00:00:45,140 --> 00:00:48,880 >> 是23显而易见的含义 以人谁看你的程序 20 00:00:48,880 --> 00:00:51,550 也许有不同的 尺寸终端窗口? 21 00:00:51,550 --> 00:00:52,330 可能不会。 22 00:00:52,330 --> 00:00:53,080 这似乎是,确定。 23 00:00:53,080 --> 00:00:55,005 那么,为什么它仅仅不到23? 24 00:00:55,005 --> 00:00:56,880 在一般情况下,它是一种 实际上是一个坏习惯 25 00:00:56,880 --> 00:00:58,940 写常量到你的代码。 26 00:00:58,940 --> 00:01:02,190 这样,当你真正做 写一个常数到你的代码, 27 00:01:02,190 --> 00:01:05,630 它有时也被称为用 幻数,这是一件好事 28 00:01:05,630 --> 00:01:08,030 我们一般要尽量避免。 29 00:01:08,030 --> 00:01:12,830 >> 例如,让我们一起来看看 在这个简单的功能在这里。 30 00:01:12,830 --> 00:01:15,726 显然没有数据 用C型称为卡或甲板。 31 00:01:15,726 --> 00:01:16,600 所以只要多多包涵。 32 00:01:16,600 --> 00:01:18,910 这是一点点 伪混在这里。 33 00:01:18,910 --> 00:01:21,050 这是一个被调用的函数 处理卡,显然 34 00:01:21,050 --> 00:01:26,570 取甲板作为它的参数,和 将输出给我一张卡。 35 00:01:26,570 --> 00:01:30,990 >> 而我做的东西在这里,我 有运行从0到52的循环, 36 00:01:30,990 --> 00:01:33,394 而我处理一张卡。 37 00:01:33,394 --> 00:01:35,310 好了,我们已经有了一个魔法 在这里数量,正确的。 38 00:01:35,310 --> 00:01:38,790 你看到了什么神奇的数字是? 39 00:01:38,790 --> 00:01:42,280 或者更重要的是,你 看到的问题是什么吗? 40 00:01:42,280 --> 00:01:44,310 特别是如果这 只是其中的一个功能 41 00:01:44,310 --> 00:01:48,030 在一个它自己的文件 包含文件夹 42 00:01:48,030 --> 00:01:49,970 一堆不同 文件,其每一个 43 00:01:49,970 --> 00:01:51,670 做另一件事,以一副扑克牌。 44 00:01:51,670 --> 00:01:57,310 也许它打乱他们,或涉及手 五张牌,而不是一个单一的卡。 45 00:01:57,310 --> 00:01:59,420 >> 你看到什么 问题可能是在这里吗? 46 00:01:59,420 --> 00:02:03,220 你看到一个神奇的数字 我已经注入的代码? 47 00:02:03,220 --> 00:02:04,390 这是52吧。 48 00:02:04,390 --> 00:02:06,440 >> 象,直观的,你可能知道,OK。 49 00:02:06,440 --> 00:02:09,740 就像一个标准的平台 卡中含有52卡。 50 00:02:09,740 --> 00:02:12,570 但是,在我们的程序,它只是 一种漂浮在那里。 51 00:02:12,570 --> 00:02:15,280 这就像突然有一个52。 52 00:02:15,280 --> 00:02:18,290 >> 解决方法之一 问题是要做到这一点。 53 00:02:18,290 --> 00:02:22,724 我们很明确,现在 呼叫甲板大小为52。 54 00:02:22,724 --> 00:02:25,390 它给了它一个更直观一点 这意味着在for循环时, 55 00:02:25,390 --> 00:02:28,650 稍后我们,然后说,我 小于甲板大小。 56 00:02:28,650 --> 00:02:32,666 这似乎只是不是说52好。 57 00:02:32,666 --> 00:02:34,290 现在,这并不实际解决问题。 58 00:02:34,290 --> 00:02:38,460 它确实给一些象征 意到恒定。 59 00:02:38,460 --> 00:02:40,820 但它确实居然有种 引入另一个问题 60 00:02:40,820 --> 00:02:43,770 这可能不会立即显现出来。 61 00:02:43,770 --> 00:02:45,859 即使这个可变 声明globally-- 62 00:02:45,859 --> 00:02:47,650 你还记得是什么 意味着当我们声明 63 00:02:47,650 --> 00:02:50,500 全球范围内对局部变量? 64 00:02:50,500 --> 00:02:53,340 即使我们声明一个变量 全球范围内,如果有什么 65 00:02:53,340 --> 00:02:55,500 在另一个函数 我们的套件功能 66 00:02:55,500 --> 00:02:59,750 该处理卡操作 无意中改变甲板的尺寸, 67 00:02:59,750 --> 00:03:02,727 或者通过增加它 1或减1的。 68 00:03:02,727 --> 00:03:04,060 这可能会带来麻烦,对吧? 69 00:03:04,060 --> 00:03:08,261 特别是当我们正在处理一组 卡在那里洗牌满甲板 70 00:03:08,261 --> 00:03:08,760 是必须的。 71 00:03:08,760 --> 00:03:12,804 如果甲板尺寸减小 由1中,例如,至51 72 00:03:12,804 --> 00:03:14,970 我们没有真正洗牌 所有的卡可能。 73 00:03:14,970 --> 00:03:16,500 我们留给他们的一出。 74 00:03:16,500 --> 00:03:21,680 而该值或许是 预测或不好的演员利用。 75 00:03:21,680 --> 00:03:24,920 >> C提供了什么叫做 预处理指令,其中 76 00:03:24,920 --> 00:03:27,764 也被称为一个宏 创建符号常量。 77 00:03:27,764 --> 00:03:30,180 而事实上,你已把 看到一个预处理指令, 78 00:03:30,180 --> 00:03:32,916 即使你还没有听说过它 所谓在以#include。 79 00:03:32,916 --> 00:03:37,150 这是一个宏观的另一个例子 或预处理指令。 80 00:03:37,150 --> 00:03:41,290 >> 该方法来创建符号常量, 或至一个恒定给出名称 81 00:03:41,290 --> 00:03:43,740 使之具有更 这意味着,如下。 82 00:03:43,740 --> 00:03:47,030 #定义,名称更换。 83 00:03:47,030 --> 00:03:49,140 抛开真的很重要 这里真快。 84 00:03:49,140 --> 00:03:54,180 不要把一个分号 您#定义的末端。 85 00:03:54,180 --> 00:03:57,310 所以这是#定义,名称,更换。 86 00:03:57,310 --> 00:03:59,540 >> 当你的程序编译, 实际发生的事情 87 00:03:59,540 --> 00:04:01,740 是编译器,如果打算 要通过您的代码 88 00:04:01,740 --> 00:04:06,770 更换的每个实例 单词“名称”不管你 89 00:04:06,770 --> 00:04:08,860 把作为替代。 90 00:04:08,860 --> 00:04:13,060 类似地,如果是#包括排序 类似于复制和粘贴, 91 00:04:13,060 --> 00:04:15,700 那么#定义是有点 类似于查找和替换, 92 00:04:15,700 --> 00:04:19,180 如果你曾经使用过该功能的 文字处理程序,例如。 93 00:04:19,180 --> 00:04:26,345 >> 因此,举例来说,如果我 #定义PI为3.14159265, 94 00:04:26,345 --> 00:04:28,720 如果你有更好的数学 倾斜你突然 95 00:04:28,720 --> 00:04:31,640 看到3.14159265飞行 围绕在你的代码, 96 00:04:31,640 --> 00:04:33,517 你可能知道它在谈论圆周率。 97 00:04:33,517 --> 00:04:35,850 但也许我们可以给它一个 多一点象征意义。 98 00:04:35,850 --> 00:04:39,850 我们可以改为说的#define 作为圆周率的数字是一口 99 00:04:39,850 --> 00:04:42,110 我不是要保持 读了个遍。 100 00:04:42,110 --> 00:04:45,560 >> 什么事情发生,然后在 编译的时候是当程序 101 00:04:45,560 --> 00:04:48,530 编译后,第一件事就是 会发生的是它会经过 102 00:04:48,530 --> 00:04:51,520 它将取代每次 它认为资本磷,资金我, 103 00:04:51,520 --> 00:04:55,610 它会用它的字面取代 3.14等等,让你 104 00:04:55,610 --> 00:04:58,090 不必键入它的每一个 时间,而你仍然程序 105 00:04:58,090 --> 00:05:00,631 具有的功能,你 期待,因为你的工作 106 00:05:00,631 --> 00:05:05,090 与操纵,乘, 分割,不管它是圆周率。 107 00:05:05,090 --> 00:05:08,230 >> 你并不限于此 替代只有数字。 108 00:05:08,230 --> 00:05:12,279 例如,我可以#定义 当然,作为字符串CS50。 109 00:05:12,279 --> 00:05:14,070 在这种情况下,当 编译程序, 110 00:05:14,070 --> 00:05:16,236 #定义将通过 代码,替换每次 111 00:05:16,236 --> 00:05:19,900 它认为“课程”的字符串CS50。 112 00:05:19,900 --> 00:05:21,720 >> 你会发现在这里 也是我经常 113 00:05:21,720 --> 00:05:26,090 #定义我的所有定义的符号 常量,可以这么说, 114 00:05:26,090 --> 00:05:28,130 总是全部大写。 115 00:05:28,130 --> 00:05:28,960 这是一个惯例。 116 00:05:28,960 --> 00:05:30,170 它不是必需的。 117 00:05:30,170 --> 00:05:33,900 究其原因一般人会用 当他们#defining全部大写 118 00:05:33,900 --> 00:05:37,590 只是,使其真正清楚, 我的代码这个特定元素 119 00:05:37,590 --> 00:05:38,820 是一个定义的常量。 120 00:05:38,820 --> 00:05:43,730 如果是小写的,它可能是 它可能被混淆的变量。 121 00:05:43,730 --> 00:05:46,120 而这可能 不是一个很好的事情。 122 00:05:46,120 --> 00:05:48,910 >> 因此,这个特殊的 溶液好得多 123 00:05:48,910 --> 00:05:50,550 比任何以往的。 124 00:05:50,550 --> 00:05:59,950 如果我第一次的#define甲板尺寸52,然后 现在我使用的52,或甲板的大小在这里, 125 00:05:59,950 --> 00:06:01,850 很多更直观,安全很多。 126 00:06:01,850 --> 00:06:03,280 你不能操纵一个常数。 127 00:06:03,280 --> 00:06:05,259 你不能说52加再加。 128 00:06:05,259 --> 00:06:06,800 这是不会将其转换为53。 129 00:06:06,800 --> 00:06:09,390 你不能改变52的东西。 130 00:06:09,390 --> 00:06:12,470 >> 你可以改变一个变量 它的值是52, 131 00:06:12,470 --> 00:06:14,870 这是我们收到的第一个补丁。 132 00:06:14,870 --> 00:06:17,000 你可能会增加 该变量为53。 133 00:06:17,000 --> 00:06:21,100 但你不能说52加上加号和 有摇身变成52 53。 134 00:06:21,100 --> 00:06:23,350 52永远是52。 135 00:06:23,350 --> 00:06:28,860 所以你不能在不经意间改变 甲板尺寸在这里通过操纵它, 136 00:06:28,860 --> 00:06:29,940 137 00:06:29,940 --> 00:06:32,390 >> 另一个好的一面 这虽然效果是 138 00:06:32,390 --> 00:06:38,310 这是你知道不 全世界所有国家 139 00:06:38,310 --> 00:06:40,690 使用的大小52一副扑克牌? 140 00:06:40,690 --> 00:06:45,630 例如,它在真正的共同 德国使用的32甲板的尺寸, 141 00:06:45,630 --> 00:06:48,020 他们剥离了一些 的较低值卡。 142 00:06:48,020 --> 00:06:50,960 在这种情况下,我 希望我的口套房 143 00:06:50,960 --> 00:06:55,390 那处理功能 卡操作到德国。 144 00:06:55,390 --> 00:06:59,440 我可以在第一时间,我们 结果显示,得去更换 145 00:06:59,440 --> 00:07:03,570 52在我的代码与32所有实例。 146 00:07:03,570 --> 00:07:07,940 >> 但在这里,如果我#定义甲板尺寸 32,在我的代码的最顶端, 147 00:07:07,940 --> 00:07:11,730 如果我需要去改变它,我可以 随便去改变一件事。 148 00:07:11,730 --> 00:07:15,010 重新编译我的代码,所有的 突然它传播通过。 149 00:07:15,010 --> 00:07:18,850 事实上,我们可以改变甲板 大小以我们想要的任何值。 150 00:07:18,850 --> 00:07:22,500 >> 我可以你感兴趣的 游戏甲板尺寸皮卡? 151 00:07:22,500 --> 00:07:23,430 >> 我是道格·劳埃德。 152 00:07:23,430 --> 00:07:25,840 这是CS50。 153 00:07:25,840 --> 00:07:27,772