还没有笔记
选中页面文字后点击「高亮」按钮添加
COMS W3157
Dr. Borowski
C语言的语法与Java有一些相似之处
学习C语言就像学习机器的真正工作方式。
Java隐藏细节,而C语言则对程序的运作方式提供完全控制。
C语言是过程式语言,而非面向对象语言。
在C语言中,内存管理是程序员的工作。
```
/* Every C program needs an entry point -- the main
function */
// Function return type, name, arguments
int main(int argc, char **argv) {
return 0; // Every statement ends with ";"
}
```
上述程序的输出是什么?
```
/* Every C program needs an entry point -- the main
function */
// Function return type, name, arguments
int main(int argc, char **argv) {
return 0; // Every statement ends with ";"
}
```
上述程序的输出是什么?
没有输出。
```
/* Every C program needs an entry point -- the main
function */
// Function return type, name, arguments
int main(int argc, char **argv) {
printf("Hello, world!\n"); // a simple print statement
// very similar to printing in Java
return 0;
}
```
上述程序的输出是什么?
```
/* Every C program needs an entry point -- the main
function */
// Function return type, name, arguments
int main(int argc, char **argv) {
printf("Hello, world!\n"); // a simple print statement
// very similar to printing in Java
return 0;
}
```
上述程序的输出是什么?
Hello, world!
```
/* Every C program needs an entry point -- the main
function */
// Function return type, name, arguments
int main(int argc, char **argv) {
return 0;
printf("Hello World!\n");
}
```
上述程序的输出是什么?
提示:思考一下这页幻灯片与上一页有什么不同。
/ 每个C程序都需要一个入口点——main函数 /
// 函数返回类型、名称、参数
int main(int argc, char **argv) { return 0; printf("Hello World! \n"); } 没有输出;return 语句在 printf 语句之前!
上述程序的输出是什么?
提示:思考一下这页幻灯片与上一页有什么不同。
```
int main(int argc, char **argv) {
// declare variable: type name (with letters, digits, "_")
char var0;
// first character should be alphabet or underscore
int var_1;
// variable names are case sensitive
float Var_1;
var0 = '0'; // assignment statement
return 0;
}
```
与Java一样,C语言定义了 char、short、int 和 long 类型,但它也包括 long long。
C语言还具有 float 和 double 类型——带浮点精度的数字。
一般来说,可以保证:
char <= short <= int <= long <= long long
在我们的Linux系统上:
| char: | 1 | byte | long: |
| :--- | :--- | :--- | :--- |
| short: | 2 | 8 bytes | |
| int: | 4 | bytes | long long: |
| float: | 4 bytes | double: | 8 bytes |
整型可以声明为 unsigned。例如,int x; 创建一个取值范围在 $\left[-2^{31}, 2^{31}-1\right]$ 的变量,而 unsigned int x; 创建一个取值范围在 $\left[0,2^{32}-1\right]$ 的变量。
我们使用二进制补码表示来存储有符号变量。
二进制加法
| 0 | 0 | 1 | 1 | |
| ---: | ---: | ---: | ---: | ---: |
| +0 | +1 | +0 | +1 | |
| -- | --- | --- | --- | |
| 0 | 1 | 1 | 10 | | | $1+1=0$,但 |
| :--- |
| 你需要 |
| 进位1, |
| 因为 $10_{2}=2_{10}$。 |
1011
$+\quad 1011$
------
?
111
1011
+ 1011
------
0110
111
1011
+ 1011
------
10110
假设我们有一个有符号 char,如下:
char c = -5;
值 -5 是如何存储在 8 位中的?
00000101 -> 11111010
11111011 <- 这就是有符号 char 中的 -5。
假设我们有一个有符号 char,如下:
char c = -1;
值 -1 是如何存储在 8 位中的?
00000001 -> 11111110
11111111 <- 这就是有符号 char 中的 -1。
假设你有一个二进制数 11101111,并且你知道它被存储为一个(有符号)char。它是哪个数字?
最左边的位是符号位。1表示负数,0表示非负数。
因为它是一个负数,所以再遵循相同的 3 步过程。

11101111 等价于 -00010001,或者说 -17。
表达式可以包含运算符,运算符对一个或多个操作数执行操作。
相等和关系运算符是二元运算符,这意味着它们需要两个操作数。
&& - 逻辑与
|| - 逻辑或
! - 逻辑非
逻辑运算符只考虑它们的操作数是零还是非零。
逻辑与和逻辑或也被称为短路运算符。如果表达式的最终结果仅通过评估第一个操作数就能确定,那么第二个操作数就永远不会被评估。
| P | Q | $\mathrm{P} \& \& \mathrm{Q}$ |
| :---: | :---: | :---: |
| T | T | T |
| T | F | F |
| F | T | F |
| F | F | F |
当 P 为假时,整个表达式自动为假。
| P | Q | P | I |
| :---: | :---: | :---: | :---: |
| T | T | Q | |
| T | F | T | |
| F | T | T | |
| F | F | F | |
当 P 为真时,整个表达式自动为真。
& - 位与
| - 位或
~ - 位非
^ - 位异或
位运算符在数据的二进制表示中的位上工作。
对于接下来的几页幻灯片,请考虑以下代码:
char a = 11; // 00001011 in binary
char b = 5; // 00000101 in binary
为什么有用:
为什么有用:在不改变其他位的情况下,打开(设置)值中的特定位。
为什么有用:当你需要位逆或翻转每个位时非常有用。
为什么有用:翻转位或检测差异——甚至可以用于在没有临时变量的情况下交换两个值。
如果使用位异或交换2个变量,我们不需要临时变量。假设 a=11,b=5。
这些运算符允许我们将位向左或向右“移动”。
a = a << 1;
这些运算符允许我们将位向左或向右“移动”。
这个操作数决定了所有位向左移动的位数。
这些运算符允许我们将位向左或向右“移动”。
a = a << 1;
乘以 $2^{1}$

这些运算符允许我们将位向左或向右“移动”。
a = a << 1;
乘以 $2^{1}$
这个操作数决定了所有位向右移动的位数。
00001011 // = a (11)
>> 2
---------
>> 2 =
int division by $2^{2}$
| 字面量类型 | 字面量示例 | C语言中的变量定义示例 |
| :--- | :--- | :--- |
| 十进制 | 85 | int dec = 85; |
| 八进制 | 0213 | int oct = 0213; |
| 十六进制 | 0x4b | int hex = 0x4b; |
| int | 30 | int a = 30; |
| unsigned int | 30u | unsigned int ua = 30; |
| long | 30l | long b = 30; |
| unsigned long | 30ul | unsigned long ub = 30; |
| double | 3.14159 | double d = 3.14159; |
| | 314159e-5L | double sd = 314159e-5L; |
| float | 210.5f | float f = 210.5f; |
| char | 'c' | char c = 'c'; |
| string (char ) | "abcd" | char s = "abcd"; |
要声明八进制数,我们必须以 0 开头;否则,编译器会认为它是一个十进制数。
我们可以使用 argc 和 argv 遍历命令行参数。
```
#include
int main(int argc, char *argv[]) {
```
我们将在下节课深入探讨!
```
for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
}
```
```
Example Run: ./program apple banana
Output: Argument 0: ./program
Argument 1: apple
Argument 2: banana
```
atoi 允许你将字符串转换为整数。
```
#include
#include
int main() {
char str[] = "42";
int num = atoi(str);
printf("The number is %d\n", num);
return 0;
}
```
将字符串 "42" 转换为整数 42。
printf 允许你打印格式化字符串。
```
#include
int main() {
int var1 = 15;
double var2 = 0.179;
printf("var1 is %d and var2 is %lf\n", var1, var2);
return 0;
}
```
将 var1 is 15 and var2 is 0.179000 打印到标准输出。
成功返回时,printf 返回打印的字节数(不包括用于结束字符串输出的空字节),失败时返回负数。
scanf 允许你扫描(读取)格式化的用户输入。
```
#include
int main() {
int age;
printf("Enter your age: ");
scanf("%d", &age);
R
printf("You entered %d\n", age);
return 0;
}
```
从标准输入读取并将值存储到 age 中。
putc 允许你向文件或输出流写入1个字符。
```
#include
int main() {
char ch = 'A';
putc(ch, stdout);
return 0;
}
```
将字符 A 打印到标准输出。