这是用户在 2024-9-18 23:25 为 https://cs50.harvard.edu/x/2024/notes/2/ 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

Lecture 2 第二讲

Welcome! 欢迎您!

  • In our previous session, we learned about C, a text-based programming language.
    在我们之前的课程中,我们学习了 C 语言,一种文本编程语言。
  • This week, we are going to take a deeper look at additional building-blocks that will support our goals of learning more about programming from the bottom up.
    本周,我们将更深入地探讨一些额外的基础要素,以支持我们从头学习编程的目标。
  • Fundamentally, in addition to the essentials of programming, this course is about problem-solving. Accordingly, we will also focus further on how to approach computer science problems.
    从根本上说,除了编程的基本知识,这门课程还侧重于解决问题的方法。因此,我们还将进一步探讨如何处理计算机科学中的各种问题。

Compiling 编译中

  • Encryption is the act of hiding plain text from prying eyes. decrypting, then, is the act of taking an encrypted piece of text and returning it to a human-readable form.
    加密是指将明文隐藏起来,防止他人查看。解密则是将加密后的文本还原成人类可以理解的文字。
  • An encrypted piece of text may look like the following:
    一段加密的文本可能呈现如下形式:

    encryption

  • Recall that last week you learned about a compiler, a specialized computer program that converts source code into machine code that can be understood by a computer.
    还记得上周你学习的编译器吗?它是一个专门的计算机程序,可以将源代码转换成计算机可以理解的机器代码。
  • For example, you might have a computer program that looks like this:
    例如,你可能有一个像这样的计算机程序:

    #include <stdio.h>
    
    int main(void)
    {
        printf("hello, world\n");
    }
    
  • A compiler will take the above code and turn it into the following machine code:
    编译器会将上面的代码转换成下面的机器代码:

    machine code

  • VS Code, the programming environment provided to you as a CS50 student, utilizes a compiler called clang or c language.
    作为 CS50 学生提供的编程环境,VS Code 使用名为 clang 的编译器或 C 语言。
  • If you were to type make hello, it runs a command that executes clang to create an output file that you can run as a user.
    如果你输入 make hello ,它会执行一个命令,通过 clang 创建一个你可以以用户身份运行的输出文件。
  • VS Code has been pre-programmed such that make will run numerous command line arguments along with clang for your convenience as a user.
    VS Code 已经预先编程,以便 make 可以运行大量的命令行参数和 clang,方便您使用。
  • Consider the following code:
    请考虑以下代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string name = get_string("What's your name? ");
        printf("hello, %s\n", name);
    }
    
  • You can attempt to enter into the terminal window: clang -o hello hello.c. You will be met by an error that indicates that clang does not know where to find the cs50.h library.
    您可以在终端窗口中输入: clang -o hello hello.c 。您会遇到一个错误,提示 clang 找不到 cs50.h 库。
  • Attempting again to compile this code, run the following command in the terminal window: clang -o hello hello.c -lcs50. This will enable the compiler to access the cs50.h library.
    再次尝试编译此代码,在终端窗口中运行以下命令: clang -o hello hello.c -lcs50 。这将允许编译器访问 cs50.h 库。
  • Running in the terminal window ./hello, your program will run as intended.
    在终端窗口 ./hello 中运行,您的程序将按预期运行。
  • While the above is offered as an illustration, such that you can understand more deeply the process and concept of compiling code, using make in CS50 is perfectly fine and the expectation!
    虽然以上内容仅作为一种示例,帮助您更深入地理解编译代码的过程和概念,但在 CS50 中使用 make 是完全可以接受的,并且是我们的期望!
  • Compiling involves major steps, including the following:
    编译过程包括几个主要步骤,如下所示:
    • First, preprocessing is where the header files in your code, designated by a # (such as #include <cs50.h>) are effectively copied and pasted into your file. During this step, the code from cs50.h is copied into your program. Similarly, just as your code contains #include <stdio.h>, code contained within stdio.h somewhere on your computer is copied to your program. This step can be visualized as follows:
      首先,预处理阶段会将代码中由 # 指定的头文件(例如 #include <cs50.h> )复制粘贴到您的文件中。在这个过程中,来自 cs50.h 的代码会被复制到您的程序中。类似地,就像您的代码包含 #include <stdio.h> 一样,计算机中某个位置的 stdio.h 中包含的代码也会被复制到您的程序中。这个过程可以可视化如下:

      string get_string(string prompt);
      int printf(string format, ...);
      
      int main(void)
      {
          string name = get_string("What's your name? ");
          printf("hello, %s\n", name);
      }
      
    • Second, compiling is where your program is converted into assembly code. This step can be visualized as follows:
      第二步,编译是将程序转换为汇编代码的过程,可以将这个步骤想象成如下:

      compiling

    • Third, assembling involves the compiler converting your assembly code into machine code. This step can be visualized as follows:
      第三步,组装过程是指编译器将您的汇编代码转换为机器代码。这个过程可以形象地理解为:

      assembling

    • Finally, during the linking step, code from your included libraries are converted also into machine code and combined with your code. The final executable file is then outputted.
      最后,在链接阶段,您所包含的库的代码也会被转换成机器代码,并与您的代码合并,生成最终的可执行文件。

      linking

Debugging 故障排除

  • Everyone will make mistakes while coding.
    每个人在编码时都会出现错误。
  • Consider the following image from last week:
    请看上周的这张图片:

    mario

  • Further, consider the following code that has a bug purposely inserted within it:
    此外,请考虑以下代码,代码中故意插入了一个错误

    #include <stdio.h>
    
    int main(void)
    {
        for (int i = 0; i <= 3; i++)
        {
            printf("#\n");
        }
    }
    
  • Type code buggy0.c into the terminal window and write the above code.
    在终端窗口中输入 code buggy0.c 并运行上面的代码。
  • Running this code, four bricks appear instead of the intended three.
    运行这段代码时,出现了四块砖,而不是预期的三块。
  • printf is a very useful way of debugging your code. You could modify your code as follows:
    使用 printf 是调试代码的一种非常有效的方法。您可以尝试以下代码修改:

    #include <stdio.h>
    
    int main(void)
    {
        for (int i = 0; i <= 3; i++)
        {
            printf("i is %i\n", i);
            printf("#\n");
        }
    }
    
  • Running this code, you will see numerous statements, including i is 0, i is 1, i is 2, and i is 3. Seeing this, you might realize that Further code needs to be corrected as follows:
    运行这段代码,你会看到很多语句,包括 i is 0i is 1i is 2i is 3 。 看到这些,你可能意识到需要进一步修正代码,如下:

    #include <stdio.h>
    
    int main(void)
    {
        for (int i = 0; i < 3; i++)
        {
            printf("#\n");
        }
    }
    

    Notice the <= has been replaced with <.
    请注意, <= 已经被 < 替换了。

  • This code can be further improved as follows:
    这段代码可以进一步改进如下:

    #include <cs50.h>
    #include <stdio.h>
    
    void print_column(int height);
    
    int main(void)
    {
        int h = get_int("Height: ");
        print_column(h);
    }
    
    void print_column(int height)
    {
        for (int i = 0; i <= height; i++)
        {
            printf("#\n");
        }
    }
    

    Notice that compiling and running this code still results in a bug.
    请注意,编译和运行这段代码仍会出现错误。

  • To address this bug, we will use a new tool at our disposal.
    为了解决这个 bug,我们将使用一个新的工具。
  • A second tool in debugging is called a debugger, a software tool created by programmers to help track down bugs in code.
    第二种调试工具称为调试器,这是一种由程序员开发的软件工具,用于帮助找到代码中的错误。
  • In VS Code, a preconfigured debugger has been provided to you.
    VS Code 为您提供了一个预配置的调试器。
  • To utilize this debugger, first set a breakpoint by clicking to the left of a line of your code, just to the left of the line number. When you click there, you will see a red dot appearing. Imagine this as a stop sign, asking the compiler to pause such that you can consider what’s happening in this part of your code.
    要使用这个调试器,首先在代码行左侧的数字左侧点击设置断点。点击后,你将会看到一个红色的点出现。把它想象成一个停止标志,它要求编译器暂停,以便你可以查看代码这一部分正在发生的事情。

    break point

  • Second, run debug50 ./buggy0. You will notice that after the debugger comes to life that a line of your code will illuminate in a gold-like color. Quite literally, the code has paused at this line of code. Notice in the top left corner how all local variables are being displayed, including h, which has a current does not have a value. At the top of your window, you can click the step over button and it will keep moving through your code. Notice how the value of h increases.
    接下来,运行 debug50 ./buggy0 。你会发现调试器启动后,代码中的一行会以金色高亮显示。代码实际上在这行代码处暂停了。注意左上角显示的所有局部变量,包括 h ,它目前没有值。在窗口顶部,你可以点击 step over 按钮,它会继续执行你的代码。注意 h 的值是如何增加的。
  • While this tool will not show you where your bug is, it will help you slow down and see how your code is running step by step. You can use step into as a way to look further into the details of your buggy code.
    虽然这个工具不会直接指出错误所在,但它可以帮助你放慢速度,逐行查看代码的运行过程。你可以使用 step into 来更深入地分析有问题的代码部分。
  • A final form of debugging is called rubber duck debugging. When you are having challenges with your code, consider how speaking out loud to, quite literally, a rubber duck about the code problem. If you’d rather not talk to a small plastic duck, you are welcome to speak to a human near you! They need not understand how to program: Speaking with them is an opportunity for you to speak about your code.
    一种最终的调试方法被称为橡皮鸭调试。当你在代码中遇到困难时,可以尝试大声和一只橡皮鸭讨论代码问题。如果你不想和小塑料鸭聊,也可以和身边的人交谈!他们不必懂编程:与他们交流是你分享代码的好机会。

Arrays 数组类型

  • In Week 0, we talked about data types such as bool, int, char, string, etc.
    在第 0 周,我们讨论了诸如 boolintcharstring 等数据类型。
  • Each data type requires a certain amount of system resources:
    每种数据类型都需要消耗一定的系统资源:
    • bool 1 byte  bool 1 字节
    • int 4 bytes  int 4 个字节
    • long 8 bytes  long 8 个字节
    • float 4 bytes  float 4 个字节
    • double 8 bytes  double 8 个字节
    • char 1 byte  char 1 个字节
    • string ? bytes 如果 string 不为空,则为字节
  • Inside of your computer, you have a finite amount of memory available.
    你电脑内部可用的内存是有限的。

    memory

  • Physically, on the memory of your computer, you can imagine how specific types of data are stored on your computer. You might imagine that a char, which only requires 1 byte of memory, may look as follows:
    在你的计算机内存中,你可以想象特定类型的数据是如何存储的。你可以想象一个 char ,它只需要 1 字节的内存,可能如下所示:

    1 byte

  • Similarly, an int, which requires 4 bytes might look as follows:
    类似地,一个 int 需要 4 个字节,可能会如下所示:

    4 bytes

  • We can create a program that explores these concepts. Inside your terminal, type code scores.c and write code as follows:
    我们可以创建一个程序来探索这些概念。在你的终端中,输入 code scores.c ,然后编写以下代码:

    #include <stdio.h>
    
    int main(void)
    {
        // Scores
        int score1 = 72;
        int score2 = 73;
        int score3 = 33;
    
        // Print average
        printf("Average: %f\n", (score1 + score2 + score3) / 3.0);
    }
    

    Notice that the number on the right is a floating point value of 3.0, such that the calculation is rendered as a floating point value in the end.
    请注意,右侧的数字是一个浮点值 3.0 ,因此最终的计算结果也是一个浮点值。

  • Running make scores, the program runs.
    正在运行 make scores ,程序正在执行。
  • You can imagine how these variables are stored in memory:
    你可以想象这些变量是如何在内存中存储的:

    scores in memory

  • Arrays are a way of storing data back-to-back in memory such that this data is easily accessible.
    数组是一种在内存中以紧凑方式存储数据的方式,这样可以方便地访问这些数据。
  • int scores[3] is a way of telling the compiler to provide you three back-to-back places in memory of size int to store three scores. Considering our program, you can revise your code as follows:
    int scores[3] 是一种指示编译器为您提供三个连续的内存空间,每个大小为 int ,以存储三个 scores 的方式。考虑到我们的程序,您可以按如下方式修改代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Get scores
        int scores[3];
        scores[0] = get_int("Score: ");
        scores[1] = get_int("Score: ");
        scores[2] = get_int("Score: ");
    
        // Print average
        printf("Average: %f\n", (scores[0] + scores[1] + scores[2]) / 3.0);
    }
    

    Notice that score[0] examines the value at this location of memory by indexing into the array called scores at location 0 to see what value is stored there.
    注意 score[0] 通过访问数组 scores 的位置 0 ,使用 indexing into 方法来检查该内存位置的值,以查看存储在那里的值。

  • You can see how while the above code works, there is still an opportunity for improving our code. Revise your code as follows:
    你可以看到,尽管上述代码可以正常运行,但我们仍有改进的空间。请按照以下方式调整你的代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Get scores
        int scores[3];
        for (int i = 0; i < 3; i++)
        {
            scores[i] = get_int("Score: ");
        }
    
        // Print average
        printf("Average: %f\n", (scores[0] + scores[1] + scores[2]) / 3.0);
    }
    

    Notice how we index into scores by using scores[i] where i is supplied by the for loop.
    请注意,我们通过使用 scores[i] 来索引 scores ,其中 ifor 循环提供。

  • We can simplify or abstract away the calculation of the average. Modify your code as follows:
    我们可以简化或抽象计算平均值的过程。请按如下方式修改你的代码:

    #include <cs50.h>
    #include <stdio.h>
    
    // Constant
    const int N = 3;
    
    // Prototype
    float average(int length, int array[]);
    
    int main(void)
    {
        // Get scores
        int scores[N];
        for (int i = 0; i < N; i++)
        {
            scores[i] = get_int("Score: ");
        }
    
        // Print average
        printf("Average: %f\n", average(N, scores));
    }
    
    float average(int length, int array[])
    {
        // Calculate average
        int sum = 0;
        for (int i = 0; i < length; i++)
        {
            sum += array[i];
        }
        return sum / (float) length;
    }
    

    Notice that a new function called average is declared. Further, notice that a const or constant value of N is declared. Most importantly, notice how the average function takes int array[], which means that the compiler passes an array to this function.
    请注意,声明了一个名为 average 的新函数。此外,还声明了一个 const 或常量值 N 。最重要的是,注意到 average 函数接受 int array[] ,这表示编译器会将一个数组传递给这个函数。

  • Not only can arrays be containers: They can be passed between functions.
    数组不仅可以作为容器,还可以作为参数传递给函数。

Strings 字符串内容

  • A string is simply an array of variables of type char: an array of characters.
    一个 string 实际上就是一个由 char 类型变量组成的数组,也就是字符数组。
  • Considering the following image, you can see how a string is an array of characters that begins with the first character and ends with a special character called a NUL character:
    考虑以下图片,您可以看到字符串是一个由字符组成的数组,它以第一个字符开始,以一个称为 NUL character 的特殊字符结束

    hi with terminator

  • Imagining this in decimal, your array would look like the following:
    如果用十进制表示,你的数组看起来会像这样:

    hi with decimal

  • Implementing this in your own code, type code hi.c in the terminal window and write code as follows:
    要在您的代码中实现此功能,请在终端窗口输入 code hi.c ,并按照以下方式编写代码:

    #include <stdio.h>
    
    int main(void)
    {
        char c1 = 'H';
        char c2 = 'I';
        char c3 = '!';
    
        printf("%c%c%c\n", c1, c2, c3);
    }
    

    Notice that this will output a string of characters.
    请注意,这将生成一串字符。

  • Similarly, make the following modification to your code:
    同样,请对您的代码进行以下修改:

    #include <stdio.h>
    
    int main(void)
    {
        char c1 = 'H';
        char c2 = 'I';
        char c3 = '!';
    
        printf("%i %i %i\n", c1, c2, c3);
    }
    

    Notice that that ASCII codes are printed by replacing %c with %i.
    请注意,ASCII 代码是通过将 %c 替换为 %i 来打印出来的。

  • To further understand how a string works, revise your code as follows:
    为了更好地理解 string 的工作机制,请将代码修改如下:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string s = "HI!";
        printf("%c%c%c\n", s[0], s[1], s[2]);
    }
    

    Notice how the printf statement presents three values from our array called s.
    请注意,这个 printf 语句展示了我们名为 s 的数组中的三个值。

  • As before, we can replace %c with %i as follows:
    和之前一样,我们可以用 %i 替换 %c ,如下所示:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string s = "HI!";
        printf("%i %i %i %i\n", s[0], s[1], s[2], s[3]);
    }
    

    Notice that this prints the string’s ASCII codes, including NUL.
    请注意,这会显示字符串的 ASCII 编码,包括 NUL。

  • Let’s imagine we want to say both HI! and BYE!. Modify your code as follows:
    假设我们想要同时表达 HI!BYE! ,请将您的代码修改如下:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string s = "HI!";
        string t = "BYE!";
    
        printf("%s\n", s);
        printf("%s\n", t);
    }
    

    Notice that two strings are declared and used in this example.
    请注意,这个例子中声明并使用了两个字符串。

  • You can visualize this as follow:
    你可以这样进行可视化:

    hi and bye

  • We can further improve this code. Modify your code as follows:
    我们可以进一步改进这段代码。请按照以下方式修改您的代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string words[2];
    
        words[0] = "HI!";
        words[1] = "BYE!";
    
        printf("%s\n", words[0]);
        printf("%s\n", words[1]);
    }
    

    Notice that both strings are stored within a single array of type string.
    请注意,这两个字符串都存储在一个类型为 string 的数组中。

String Length 字符串的长度

  • A common problem within programming, and perhaps C more specifically, is to discover the length of an array. How could we implement this in code? Type code length.c in the terminal window and code as follows:
    在编程中,尤其是在 C 语言中,常见的一个问题是如何确定数组的长度。我们应该如何在代码中实现这一点呢?请在终端窗口输入 code length.c ,并按如下方式编写代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Prompt for user's name
        string name = get_string("Name: ");
    
        // Count number of characters up until '\0' (aka NUL)
        int n = 0;
        while (name[n] != '\0')
        {
            n++;
        }
        printf("%i\n", n);
    }
    

    Notice that this code loops until the NUL character is found.
    请注意,这段代码会一直循环,直到找到 NUL 字符为止。

  • This code can ben improved by abstracting away the counting as follows:
    这段代码可以通过将计数抽象化来进行改进:

    #include <cs50.h>
    #include <stdio.h>
    
    int string_length(string s);
    
    int main(void)
    {
        // Prompt for user's name
        string name = get_string("Name: ");
        int length = string_length(name);
        printf("%i\n", length);
    }
    
    int string_length(string s)
    {
        // Count number of characters up until '\0' (aka NUL)
        int n = 0;
        while (s[n] != '\0')
        {
            n++;
        }
        return n;
    }
    
  • Since this is such a common problem within programming, other programmers have created code in the string.h library to find the length of a string. You can find the length of a string by modifying your code as follows:
    由于这是编程中常见的难题,其他程序员已经在 string.h 库中编写了代码来查找字符串的长度。您可以通过以下方式修改代码来查找字符串的长度:

    #include <cs50.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        // Prompt for user's name
        string name = get_string("Name: ");
        int length = strlen(name);
        printf("%i\n", length);
    }
    

    Notice that this code uses the string.h library, declared at the top of the file. Further, it uses a function from that library called strlen, which calculates the length of the string passed to it.
    请注意,这段代码使用了在文件开头声明的 string.h 库。此外,它还使用该库中的一个名为 strlen 的函数,该函数可以计算传入字符串的长度。

  • ctype.h is another library that is quite useful. Imagine we wanted to create a program that converted all lowercase characters to uppercase ones. In the terminal window type code uppercase.c and write code as follows:
    ctype.h 是另一个非常实用的库。想象一下,我们想要创建一个将所有小写字母转换为大写字母的程序。在终端窗口中输入 code uppercase.c ,然后按照下面的方式编写代码:

    #include <cs50.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        string s = get_string("Before: ");
        printf("After:  ");
        for (int i = 0, n = strlen(s); i < n; i++)
        {
            if (s[i] >= 'a' && s[i] <= 'z')
            {
                printf("%c", s[i] - 32);
            }
            else
            {
                printf("%c", s[i]);
            }
        }
        printf("\n");
    }
    

    Notice that this code iterates through each value in the string. The program looks at each character. If the character is lowercase, it subtracts the value 32 from it to convert it to uppercase.
    请注意,这段代码会遍历字符串中的每个字符。程序检查每个字符。如果字符是小写字母,它会减去 32,将其转换为大写字母。

  • Recalling our previous work from last week, you might remember this ASCII values chart:
    回想一下我们上周的工作,你可能还记得那个 ASCII 值表:

    ascii

  • When a lowercase character has 32 subtracted from it, it results in an uppercase version of that same character.
    当一个小写字母减去 32 后,得到的是该字母的大写形式。
  • While the program does what we want, there is an easier way using the ctype.h library. Modify your program as follows:
    尽管这个程序能够完成我们想要的功能,但使用 ctype.h 库可以更简单。请按照以下方式修改您的程序:

    #include <cs50.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        string s = get_string("Before: ");
        printf("After:  ");
        for (int i = 0, n = strlen(s); i < n; i++)
        {
            if (islower(s[i]))
            {
                printf("%c", toupper(s[i]));
            }
            else
            {
                printf("%c", s[i]);
            }
        }
        printf("\n");
    }
    

    Notice that the program iterates through each character of the string. The toupper function is passed s[i]. Each character (if lowercase) is converted to uppercase.
    请注意,这个程序会遍历字符串中的每个字符。 toupper 函数会接收 s[i] 。每个字符(如果是小写字母)将被转换为大写字母。

  • It’s worth mentioning that toupper automatically knows to uppercase only lowercase characters. Hence, your code can be simplified as follows:
    值得注意的是, toupper 会自动将小写字母转换为大写字母,而不会影响其他字符。因此,您可以简化代码如下:

    #include <cs50.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        string s = get_string("Before: ");
        printf("After:  ");
        for (int i = 0, n = strlen(s); i < n; i++)
        {
            printf("%c", toupper(s[i]));
        }
        printf("\n");
    }
    

    Notice that this code uppercases a string using the ctype library.
    请注意,这段代码使用 ctype 库将字符串转化为大写。

  • You can read about all the capabilities of the ctype library on the Manual Pages.
    您可以在手册页中查看 ctype 库的所有功能。

Command-Line Arguments 命令行选项

  • Command-line arguments are those arguments that are passed to your program at the command line. For example, all those statements you typed after clang are considered command line arguments. You can use these arguments in your own programs!
    Command-line arguments 是在命令行中传递给您程序的参数。例如,您在 clang 之后输入的所有内容都被视为命令行参数。您可以在自己的程序中使用这些参数!
  • In your terminal window, type code greet.c and write code as follows:
    在您的终端窗口中,输入 code greet.c ,然后编写以下代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string answer = get_string("What's your name? ");
        printf("hello, %s\n", answer);
    }
    

    Notice that this says hello to the user.
    请注意,这里向用户显示的是 hello

  • Still, would it not be nice to be able to take arguments before the program even runs? Modify your code as follows:
    不过,能在程序运行之前接受参数岂不是很好吗?请按照以下方式修改你的代码:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(int argc, string argv[])
    {
        if (argc == 2)
        {
            printf("hello, %s\n", argv[1]);
        }
        else
        {
            printf("hello, world\n");
        }
    }
    

    Notice that this program knows both argc, the number of command line arguments, and argv which is an array of the characters passed as arguments at the command line.
    请注意,此程序同时了解 argc ,即命令行参数的数量,以及 argv ,它是一个包含命令行中传递的参数字符的数组。

  • Therefore, using the syntax of this program, executing ./greet David would result in the program saying hello, David.
    因此,按照这个程序的语法,执行 ./greet David 将会使得程序输出 hello, David

Exit Status 退出状态码

  • When a program ends, a special exit code is provided to the computer.
    当程序结束时,计算机会收到一个特殊的退出代码。
  • When a program exits without error, a status code of 0 is provided the computer. Often, when an error occurs that results in the program ending, a status of 1 is provided by the computer.
    当程序正常退出时,计算机会返回状态码 0 。通常,当程序因错误而结束时,计算机会返回状态码 1
  • You could write a program as follows that illustrates this by typing code status.c and writing code as follows:
    你可以编写一个程序来展示这一点,方法是输入 code status.c 并按照下面的代码进行编写:

    #include <cs50.h>
    #include <stdio.h>
    
    int main(int argc, string argv[])
    {
        if (argc != 2)
        {
            printf("Missing command-line argument\n");
            return 1;
        }
        printf("hello, %s\n", argv[1]);
        return 0;
    }
    

    Notice that if you fail to provide ./status David, you will get an exit status of 1. However, if you do provide ./status David, you will get an exit status of 0.
    请注意,如果您未提供 ./status David ,您将收到 1 的退出状态。但是,如果您提供了 ./status David ,您将收到 0 的退出状态。

  • You can imagine how you might use portions of the above program to check if a user provided the correct number of command-line arguments.
    你可以想象如何利用上述程序的部分来检查用户是否提供了正确的命令行参数数量。

Cryptography 密码学

  • Cryptography is the art of ciphering and deciphering a message.
    密码学是将信息进行加密和解密的艺术。
  • plaintext and a key are provided to a cipher, resulting in ciphered text.
    plaintext 和一个 key 被提供给 cipher ,因此生成了加密文本。

    cryptography

  • The key is a special argument passed to the cipher along with the plaintext. The cipher uses the key to make decisions about how to implement its cipher algorithm.
    密钥是一个特殊的参数,与明文一起传递给密码算法。密码算法使用密钥来决定如何执行其加密算法。

Summing Up 概括

In this lesson, you learned more details about compiling and how data is stored within a computer. Specifically, you learned…
本节课你将更深入地了解编译过程以及数据在计算机中的存储方式。具体而言,你将学习…

  • Generally, how a compiler works.
    编译器通常是如何运作的。
  • How to debug your code using four methods.
    如何通过四种方法调试代码。
  • How to utilize arrays within your code.
    如何在代码中有效地使用数组。
  • How arrays store data in back to back portions of memory.
    数组如何在内存中以连续的方式存储数据。
  • How strings are simply arrays of characters.
    字符串本质上是字符的数组。
  • How to interact with arrays in your code.
    如何在代码中操作数组。
  • How command-line arguments can be passed to your programs.
    如何将命令行参数传递到您的程序中。
  • The basic building-blocks of cryptography.
    密码学的基本组成部分。

See you next time!
下次见!