前言:最近通过MIT OCW的6.087Practial Programming in C来复习C语言,对照了下6.087的课程设置与C Programming Language的章节结构,感觉两者的顺序差不多,但6.087为了使学习曲线更平滑,将一些比较难的内容分为两个或多个章节,并将难点放到后面,从而使学习过程更为轻松。这里是6.087的链接:http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-087-practical-programming-in-c-january-iap-2010/
Lec1Introduction. Writing, compiling, and debugging C programs. Hello world.
C features:
• Few keywords
• Structures, unions – compound data types
• Pointers – memory, arrays
• External standard library – I/O, other facilities
• Compiles to native code
• Macro preprocessor
习惯了面向对象中类型的万能和强大,回到C中的类型不禁产生一种反蹼归真的感觉。一切皆是数,整型自不必说,字符也是数,字符串就是一串数,浮点数的内部表示应该也是用整型数字。除此之外,最重要的是万能的指针,也是数,而且可以进行指针运算。似乎可以从C看到图灵机的经典模型。
C语言提供了基本的控制指令:
- statement group( {} )
- desicion making( if-else )
- conditional switch ( switch-case )
- loop with termination at top( for, while)
- loop with termination at bottom(do...while)
- early loop exit( break )
C语言中函数的返回类型可以是:
- basic types
- unions
- structures
- pointers
C语言中最常见的变量是自动变量(automatic variable),这种变量在每次调用时就重新创建,存在于栈中。
C语言的变量作用域有三种:
- 局部变量,函数内可用
- 外部变量,但只在一个文件内可用
- 外部变量,整个程序都可用
Inherently unsafe:
• No range checking
• Limited type safety at compile time
• No type checking at runtim
与Java、C++等面向对象的语言相比,C语言中的类型比较弱,早期这些类型都是可以混合进行运算。我认为C中的类型是由编译器来控制,因此编译后类型信息就没什么作用了。而Java、C#这些运行在虚拟机中的语言,在运行时其类型信息仍保留在中间码中,可以发挥一定的作用,如反射机制。
Using GDB
Some useful commands:
• break linenumber – create breakpoint at specified line
• break file:linenumber – create breakpoint at line infile
• run – run program
• c – continue execution
• next – execute next line
• step – execute next line or step into function
• quit – quit gdb
• print expression – print current value of the specifiedexpression
• help command – in-program help
GDB是用于调试C程序的,上面是GDB常用的命令,入门时记住这些命令就足够了。对于内存相关的调试,可以使用Valgrind。
.C文件的结构
/* Begin with comments about file contents */
Insert #include statements and preprocessordefinitions
Function prototypes and variable declarations
Define main() function
{
Function body
}
Define other function
{
Function body
}
上面是一个标准C程序的结构,首先将所需的其它文件尤其是库文件包含进来,并进行宏定义。将进行预处理操作的宏放到文件的最前面是很自然的事情,将include命令放到最前面,应该是为了使编译器在开始编译程序时就获得相关库或文件的信息,放到前面也是很合理的。我觉得include放到最前面,接下来是宏定义这种方式比较好,因为include命令独立性最好,放到前面就不用理他了,如果将include放到宏与程序之间,会增大程序员需要控制的代码行数。
变量声明
• Must declare variables before use
• Variable declaration:
int n;
float phi;
• int - integer data type
• float - floating-point data type
• Many other types (more next lecture. . . )
变量在声明后系统并不会在内存中给其分配空间,我认为声明只有在编译期间才有作用,编译器内部有一个有关各个变量的表,记录变量名称和类型。这样在编译时就可以进行类型检查,从而提前发现错误。
变量初始化
• Uninitialized, variable assumes a default value
• Variables initialized via assignment operator:
n = 3;
• Can also initialize at declaration:
float phi = 1.6180339887;
• Can declare/initialize multiple variables at once:
int a, b, c = 0, d = 4;
我认为,当有操作符作用于自动变量时,自动变量才会进栈,如果不对栈中的变量显示赋值,那么这个变量的值就是分配给它的那段内存的值,一般会清0。
操作符的执行序
• Order of operations:
Operator Evaluation direction
+,- (sign) right-to-left
*,/,% left-to-right
+,- left-to-right
=,+=,-=,*=,/=,%= right-to-left
• Use parentheses to override order of evaluation
操作符的执行顺序一般都是从左至右,只有单目运算符、三目运算符和赋值运算符的运算顺序是从右至左。这种执行序的不同会对编译器的编写造成一定麻烦,但所有的二目运算符都是从左到右,其它的都是从右到左,这么理解的话倒也不是很难实现。
Fucntion prototypes
• Functions also must be declared before use
• Declaration called function prototype
• Function prototypes:
int factorial ( int ); or int factorial ( int n);
• Prototypes for many common functions in header files for
C Standard Library
• General form:
return_type function_name(arg1,arg2,...);
• Arguments: local variables, values passed from caller
• Return value: single value returned to caller when function exits
• void – signifies no return value/arguments
int rand(void);
函数在使用前也必须声明,一个完整的函数声明应该包括返回类型、函数名和参数列表,函数签名应该包括返回类型和参数列表中参数的个数,参数类表中参数的类型和顺序是否包含在函数签名中我不清楚。我认为C这种弱类型的语言不应该将类型作为函数签名的一部分,Java和C#这些强类型的语言倒是可以,但没有考证过。
C中void和NULL有很大的区别。void仅在声明时使用,内存中并没有void这么一个变量,而NULL则是一个用户定义的常量,可以作为返回值返回。
The Main() Function
• main(): entry point for C program
• Simplest version: no inputs, outputs 0 when successful,and nonzero to signal some error
int main(void);
• Two-argument form of main(): access command-linearguments
int main(int argc, char ∗∗argv);
• More on the char **argv notation later this week. . .
万事开头难,定义一个起点是困难的。main函数是C语言中的程序入口,是程序的起点。argc至少为1,因为函数名自身也是一个参数,即*argv。
Function Definitions
Function declaration
{
declare variables;
program statements;
}
• Must match prototype (if there is one)
• variable names don’t have to match
• no semicolon at end
• Curly braces define a block – region of code
• Variables declared in a block exist only in that block
• Variable declarations before any other statements
“Functions break large computing tasks into smaller ones, and enable people to build on waht others have done instead of starting over from scratch” --C Programming Language, 2nd edition.
上面是K&R中对函数的说明,函数的主要作用是封装和重用。有时候感觉C的风格很简洁,如果把函数看作返回类型的一个普通变量的话,C程序就是一堆数在进行计算。因为字符实际上也是数字,所有的变量本质上都是数字,所以其核心就是运算符对变量的计算,我认为。
函数中定义的变量是局部变量,只在函数内部使用。
More about strings
• Strings stored as character array
• Null-terminated (last character in array is ’\0’ null)
• Not written explicitly in string literals• Preprocessor macros begin with # character
#include <stdio.h>
• Special characters specified using \ (escape character):
• \\ – backslash, \’ – apostrophe, \” – quotation mark
• \b, \t, \r, \n – backspace, tab, carriage return, linefeed
• \ooo, \xhh – octal and hexadecimal ASCII character
codes, e.g. \x41 – ’A’, \060 – ’0’
C中并没有字符串这种类型,我想这是为了简洁,毕竟字符串本质上就是多个字符而已。C中的基本类型都可以方便的用一个数字表示,而字符串做不到这一点,我想这也是为什么C中不将字符串设为基本类型的一个重要原因。
Preprocessor Macros
• Preprocessor macros begin with # character
#include <stdio.h>
• #define can take arguments and be treated like a function
#define add3(x,y,z) (( x)+(y)+(z))
• parentheses ensure order of operations
• compiler performs inline replacement; not suitable forrecursion
Conditional preprocessor macros
• #if , #ifdef, #ifndef, #else, # elif , #endif
conditional preprocessor macros, can control which linesare compiled
• evaluated before code itself is compiled, so conditions mustbe preprocessor defines or literals
• the gcc option -Dname=value sets a preprocessor definethat can be used
• Used in header files to ensure declarations happen onlyonce
• #pragma
preprocessor directive
• #error, #warning
trigger a custom compiler error/warning
• #undef msg
remove the definition of msg at compile time
C中宏的工作原理其实比较简单,尤其是使用最多的define,就是做个替换。但C中宏似乎也是容易出问题的地方,因为它是在编译器编译之前运行的,因此编译时很难发现宏的错误。我觉得在写程序时要少用宏,但因为很多源代码(如linux)中大量使用宏,因此对宏还是要有些了解,至少要读懂。
Summary
Topics covered:
• How to edit, compile, and debug C programs
• C programming fundamentals:
• comments
• preprocessor macros, including #include
• the main() function
• declaring and initializing variables, scope
• using puts() – calling a function and passing an argument
• returning from a function
分享到:
相关推荐
lec1.ppt lec10.ppt lec11.ppt lec12.ppt lec13.ppt lec14.ppt lec15.ppt lec16.ppt lec17.ppt lec18.ppt lec19.ppt lec2.ppt lec20.ppt lec21.ppt lec22.ppt lec23.ppt lec24.ppt lec25.ppt lec3.ppt lec4.ppt lec5...
LEC法,全称为Ladder of Events, Consequences(事件概率及其后果严重度)法,是一种在工业安全领域广泛应用的风险评估方法。此方法主要用于量化风险,通过考虑三个关键因素:发生事故的可能性(Likelihood)、暴露...
Lec1-Introduction.pdf.zip
In the previous lecture, we leant about impedance spectroscopy. Electrochemical impedance spectroscopy is the technique where the cell or electrode impedance is platted versus frequency. Thus, the ...
【Leader统帅LEC5001-Q7热水器安装与使用详解】 Leader统帅品牌的LEC5001-Q7热水器是一款家用挂墙式电热水器,其安装过程严谨且关键,需遵循安全规范,确保用户安全使用。以下是安装和使用的主要步骤及注意事项: ...
【Leader统帅LEC6001-20X1热水器】的说明书主要涵盖了热水器的安装、使用、维护和安全注意事项。以下是对这些知识点的详细解释: 1. **安装步骤**: - 安装前应根据机器型号选择合适的挂墙架,并在墙上钻孔固定...
【MIT-6.0001】是麻省理工学院(MIT)开设的一门入门级计算机科学课程,名为“Introduction to Computer Science and Programming in Python”。这门课程旨在为初学者提供计算机科学的基础知识,并教授使用Python...
【Leader统帅LEC6002-WB5金热水器安装及使用注意事项】 1. **挂墙式安装**:热水器必须采用挂墙式安装,确保挂墙架牢固地挂在膨胀挂钩和螺栓上,以保证安装的安全性。挂架上部的两个孔用于主要支撑,下部的孔用于...
1. 动态规划算法设计基础: 动态规划是算法设计中一种基本技术,它特别适用于具有最优子结构性质的优化问题。所谓最优子结构,指的是原问题可以被划分为若干较小的子问题,并且通过合并子问题的最优解来获得原问题...
1. **火灾引发条件**:火灾的发生需要可燃物、氧化剂和点火源三者同时存在并相互作用,这是基本的消防安全知识。 2. **药剂种类**:笛音剂是一种能产生哨音效果的药剂,用于烟花爆竹的制作中。 3. **准运证检查**...
《Cadence Conformal LEC学习手册:从基础到高级》 本手册主要关注Cadence Encounter Conformal LEC(逻辑等价检查器),这是一种用于ASIC设计的形式验证工具。形式验证是一种利用数学证明方法来检查设计属性的系统...
1. **风险定义**:风险是生产安全事故发生的可能性与潜在后果的结合,包括人身伤害、健康损害和财产损失。风险辨识是识别企业内所有存在的风险,了解其特性。 2. **风险评价方法**:常用的风险评价方法有作业条件...
6. **财务监控**:强化账务处理的准确性,定期审计以发现并纠正问题。 7. **信息系统支持**:利用信息技术实现采购流程的自动化和透明化,减少人为错误。 采购业务的内部控制对于防范风险、保护企业资产、提高经营...
1. **风险分级管控**:这是安全生产标准化体系的重要组成部分,通过对风险点进行分级,根据危险程度和可能造成的后果来确定风险等级,分为1、2、3、4级,1级代表最高风险。 2. **隐患排查治理**:与风险分级管控...
1. **路基处理**: - 地下水位高且有重载交通的路面,为了防止地下水影响路基稳定性,常设置垫层,以隔绝地下水,选项B正确。 - 级配砾石或天然砂砾作为基层时,其压实度要求高,通常应大于93%,选项B正确。 2. *...
【Leader统帅LEC6.6U小厨宝说明书】提供了详尽的使用和安装指南,以确保用户安全、有效地使用该产品。以下是其中的关键知识点: 1. **电源要求**:这款热水器使用交流220V/50Hz电源,需要独立插座并确保可靠接地。...
标题中的"Unix&Linux.rar_CSHELL_batch_gcc_lec-RTOS_RTlinux_societyf6x"揭示了这个压缩包文件包含了一系列与Unix和Linux操作系统、C Shell(cshell)、批处理编程(batch file programming)、GCC编译器、实时操作...
Lec 00 Introduction and Course Overview Lec 01 Bezier Curves and Splines Assignment 0 Lec 02 Curves Properties and Conversion, Surface Representation Lec 03 Coordinates and Transformations Lec 04 ...
6. **安全生产条例**:《山东省安全生产条例》要求企业建立安全生产风险分级管控制度,对风险点进行定期排查,确定风险等级。 7. **风险告知卡**:对于存在安全生产风险的岗位,企业需设置告知卡,明示岗位的主要...