00:00:00 - Introduction
00:01:01 - Story Time
00:06:03 - Compiling
make本身并不是编译器,实际上是一个自动运行编译器的程序,如c语言的clang
clang -o hello hello.c
src/ $ clang -o hello hello_world.c
/usr/bin/ld: /tmp/hello_world-67f514.o: in function `main':
hello_world.c:(.text+0x1d): undefined reference to `get_string'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
如果使用第三方库,不一定是c语言附带的库,例如cs50的库,那么必须告诉编译器想要使用什么库,不仅包括头文件,还包括附加命令
clang -o hello hello.c -lcs50
make在你不知道的情况使用了-o,和-lcs50
运行clang时(编译),会发生四种不同的事情
preprocessing //预处理就是将#include包含的行转换为文件中的任何底层原型
compiling //编译将源代码转为汇编语言
assembling //汇编将汇编语言转换为机器语言
linking //hello.c stdio.c cs50.c 是分别单独编译的,链接将他们组合为一个最终文件
Clang和GCC是两个广泛使用的编译器,它们都可以编译C、C++、Objective-C等语言的代码,但它们在设计、性能、兼容性和错误报告等方面有一些不同。
设计和目标
- Clang 是基于LLVM(Low Level Virtual Machine)项目的一部分,设计目标是提供一个基于LLVM的C语言族编译器,强调编译速度和内存使用效率,以及生成的代码的性能。Clang设计为易于使用和易于集成到其他项目中,提供了丰富的错误和警告信息,旨在提高开发效率。
- GCC(GNU Compiler Collection)是一个开源编译器集合,支持多种编程语言。GCC最初作为GNU操作系统的一部分开发,目标是提供一个自由软件的编译器。GCC着重于优化和支持多种架构,包括x86、ARM、MIPS等。
性能和优化
- Clang 和 GCC 在性能方面通常相当接近,尽管在不同的测试和不同版本中,一个可能比另一个表现得更好。Clang通常编译速度更快,尤其是对于C++代码,而GCC在某些优化方面可能更先进,尤其是在生成高度优化的代码方面。
错误报告
- Clang 的错误报告通常被认为比GCC更友好和更清晰。Clang致力于提供易于理解的错误消息和诊断信息,包括错误位置和可能的解决方案建议。
- GCC 近年来也在改进其错误消息的清晰度和有用性,但Clang在这方面通常被认为具有优势。
兼容性
- Clang 致力于与GCC兼容,尽量支持GCC的扩展和行为,以便开发者可以无缝迁移代码。
- GCC 作为一个更早期的项目,有自己的扩展和特性,这些在某些情况下可能导致与Clang的兼容性问题。
开发者生态
- Clang 由于其设计和易用性,被许多现代项目和开发环境采用,包括Xcode和许多基于LLVM的工具。
- GCC 长期以来一直是Linux和开源社区的主力编译器,具有广泛的用户基础和成熟的技术支持。
总结
选择Clang还是GCC取决于特定的项目需求、目标平台和开发者偏好。对于追求编译速度和更好的错误报告的项目,Clang可能是更好的选择。对于需要特定优化或在特定架构上运行的项目,GCC可能更合适。两者都是强大的工具,能够满足现代软件开发的需求。
00:28:40 - Debugging
当你没有复杂工具调试时,printf是你的朋友,但是会增加复杂性
更强大的工具:debugger,将会节省大量时间
debug50,可以向cs50 duck询问不理解的概念
00:47:27 - Memory
00:52:37 - scores.c
00:57:39 - Arrays
数组是内存中背靠背的值序列
01:13:59 - Strings
其实就是字符数组,如果一个字节中全为0则意味着字符串在这里结束
\0称为NUL,表示终止字符的0字节
01:33:12 - String Length
#include <stdio.h>
#include <cs50.h>int get_length(string s);
int main() {string name = get_string("your name?");printf("%i\n",get_length(name));}int get_length(string s) {int n = 0;while (s[n] != '\0') {n++;}return n;
}
运用string library
#include <stdio.h>
#include <cs50.h>
#include <string.h>int main() {string name = get_string("your name?");printf("%lu\n",strlen(name));}
01:44:33 - uppercase.c
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <cs50.h>int main() {string s = get_string("Before: ");printf("After: ");for (int i = 0, n = strlen(s); i < n; i++) {printf("%c", toupper(s[i]));}printf("\n");
}
01:50:05 - Command-line Arguments
#include <stdio.h>int main(int argc, string argv[]) {}
argc
和 argv
是在C语言(以及一些其他编程语言,如C++)中用于处理命令行参数的两个变量,它们在程序启动时由操作系统传递给程序。这两个变量通常在程序的主函数main
的参数列表中定义,它们代表了:
-
argc
(Argument Count的缩写)表示命令行参数的数量。这个数量包括程序本身的名称,所以argc
的值至少为1。 -
argv
(Argument Vector的缩写)是一个指向字符串数组的指针,这个数组存储了具体的命令行参数。argv[0]
是程序的名称,argv[1]
是第一个参数,以此类推,直到argv[argc-1]
。argv[argc]
是一个空指针(NULL),用于标识数组的结束。
通过这两个变量,程序可以接收和处理用户在命令行中输入的参数,使程序的行为可以根据这些参数进行调整。例如,用户可以通过命令行参数指定文件路径、配置选项等信息。
简单的示例代码如下:
#include <stdio.h>int main(int argc, char *argv[]) {printf("Program name: %s\n", argv[0]);printf("Number of arguments: %d\n", argc-1);for(int i = 1; i < argc; i++) {printf("Argument %d: %s\n", i, argv[i]);}return 0;
}
在这个例子中,如果程序名为example
,并且被调用时使用了两个参数file.txt
和-option
,那么argc
的值将是3,argv
数组将包含["example", "file.txt", "-option"]
。
01:57:58 - Cowsay
cowsay
是一个在命令行界面上用于生成由ASCII字符画的牛(或其他动物)所“说出”的文本的程序。它通常用于在命令行会话中添加一点幽默或个性化元素。用户可以通过输入一个字符串来创建一个由牛头围绕的文本气泡,好像是这只牛在“说”这段文字。
cowsay
最初是由Tony Monroe以Perl语言编写的,并且随时间发展,它已经被移植到了多种操作系统上。除了默认的牛图案,cowsay
还支持多种其他动物和角色的图案,这些图案通常通过修改程序的配置文件或使用特定的命令行选项来选择。
使用cowsay
非常简单,基本的命令格式如下:
cowsay [options] text
这里的text
是你希望“牛”说的话,[options]
可以是用来改变输出字符画的各种选项,比如选择不同的角色(例如羊、龙、鬼等)。
cowsay
不仅是一个有趣的小工具,也体现了开源社区的幽默感和创意。它可通过各种Linux发行版的包管理器安装,也可在其他操作系统上通过兼容层或移植版本使用。
01:59:44 - Exit Status
我们的程序默认是以0返回值退出
echo $? 可以看到秘密的返回值
#include <stdio.h>
#include <cs50.h>int main(int argc, string argv[]) {if (argc != 2) {printf("missing value in command line\n");return 1;}printf("hello ,%s\n",argv[1]);return 0;
}
02:05:48 - Cryptography
key通常是很多位的
凯撒密码