【CS61c】第二节课:C语言简述(上)

CS61c系列课程学习

本系列博客的分享是基于《CS61c》这门课程进行,主要记录的是我在学习期间的心得和收获。


引言

工欲善其事,必先利其器。——《论语·卫灵公》
我要学计算机体系结构,为什么要学C语言?讲体系结构的课程为什么会在一开始先讲解C语言呢?因为C语言有指针的用法,可以直接操纵内存。而计算机体系结构的一个非常重要的概念,就是内存,在内存中存储数据以及加载数据到内存中。换句话说,C语言是比较底层的,在高级语言中,可以用C语言来窥探体系结构的奥秘。


正文

一、C语言的编译

C语言的编译,是与计算机所选用的体系结构有关的。
就像是用x86编译的C程序,没有办法在RISC-V的架构上运行。

C语言的编译过程:

  • C compilers map C programs directly into architecture-specific machine code (string of 1s and 0s).
  • For C,generally a two part process of compiling .c files to .o files, then linking the o.files into executables.
  • 如图所示:
    在这里插入图片描述

C编译的优势
1、Reasonable compilation time:

  • enhancements in compilation procedure (Makefiles) allow only modified files to be recompiled.

2、Excellent run-time performance:

  • generally much faster than Scheme or Java for comparable code.
  • (because it optimizes for a given architecture)

其实用英文已经可以非常好的表达出 编译的基本概念 了,让我用最经典的三段论总结一下

  • 是什么:C语言程序 映射为 与体系结构相关的机器码(一堆0和1)
  • 怎么做:将.c文件编译成.o文件,然后再将这些.o文件链接起来,组成可执行文件。
  • 为什么: 编译时间合理、运行时性能更好

C语言编译的缺点:

  • 移植困难:在新的指令集架构上需要重构代码
  • 迭代慢:“Change -> Compile -> Run”的更新周期慢

二、C语言的预处理

1、预处理的时机
预处理(C Pre-Processor, CPP),在C语言的编译之前。如图所示:
预处理的时机2、预处理对源代码做什么

  • 用空格取代注释
  • 复制-粘贴 (文本替换)

3、预处理的用法
预处理的命令以#开头,最常用的如下:

#include "file.h"      // 头文件
#include <stdio.h>     // 头文件
#define PI (3.14159)   // 宏
#if / #endif           // 条件编译预处理
  • #include "file.h" 代表,预处理时会优先寻找当前目录下的文件file.h
  • #include <stdio.h> 代表,预处理时可以直接去C语言的库中寻找<stdio.h>
  • #define PI (3.14159) 是定义宏,宏就是最简单的复制粘贴。可以通过宏定义一个常量,也可以通过宏定义一个“函数”
  • #if / #endif 是一对条件编译预处理的关键字。

4、如何看预处理生成什么内容
在编译的时候, 在gcc命令后加上-save-temps
实例分析:

  1. 创建一个main.c文件,代码如下:
#include <stdio.h>
#define PI (3.14159)
int main(){
        printf("PI = %f\n",PI);
        return 0;
}
  1. 执行命令:gcc -o main -save-temps main.c
    -o main 是一个整体,用于产生最终的执行文件,名字为“main”
    -save-temps的意思就是,保存编译产生的所有临时文件
  2. 产生了main main.c main.i main.o main.s这五个文件
    其中,main.i就是预处理之后产生的文件,可以简单看一下。

对于宏的应用,在这里多说一点。

  • 宏可以用来定义一个常数,例如# define PI (3.14159).而在C语言中,
    也有另一种方法定义常数:关键字`const``,这个关键字就表示创建一个变量,但是不要改变他。
  • 宏也可以定义一个函数,宏定义的函数与一般定义的函数有什么区别呢?
    宏定义的函数相当于是复制粘贴,是最简单快捷的文本替换,没有时间开销,编译器都不会看到你定义的宏,在预处理阶段就已经把文本复制过来了。但是普通的函数,在使用的时候会有调用的时间,也就是说,会有额外的时间去花费在函数的调用上。

三、C语言的简单语法

1、main 函数

语法:int main(int argc, char *argv[])

  • argc will contain the number of strings on the command line.
    1. The executable counts as one, plus one for each argument.
    2. 从零开始,可执行文件是argc的第0个元素
  • argv is a pointer to an array containing the arguments as strings.

argcargv的理解

  • argc是在命令行中字符串的数量,可执行文件也算数,计数从0开始。
  • argv是一个指向 包含命令行参数的 数组 的指针。

2、int

在遇到想用int的时候,可以考虑用intN_tintN_t.
(N是一个整数,例如32,即int32_t)。

3、 const

Constant is assigned a typed value once in the declaration; value can’t change during entire execution of program.
例如:const int days_in_week = 7;

  • 在定义变量前面加上const关键字,之后就不能改变这个变量里的值了。

4、enum

Enums: a group of related integer constants.
例如:enum color {RED, GREEN, BLUE};

  • 使用枚举可以让代码变得易读。

5、typedef

Typedef allows you define new types.

typedef uint8_t BYTE;
BYTE b1,b2;

6、struct

Structs are structured groups of variables.

typedef struct {
	int length_in_seconds;
	int year_recorded;
} SONG;

SONG song1;
song1.length_in_seconds =  213;
song1.year_recorded     = 1994;

7、do-while 语法

do {statement} while(expression);

总结

本文根据CS61C的课程内容,根据自己的理解,简要总结了C语言的编译、预处理与简单语法这三部分的内容。由于刚刚学,难免有理解偏差的地方,希望大家批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值