引言
1. C语言 是一门计算机语言。
发展历程:机器语言 => 汇编语言 => B 语言 => C语言
计算机语言:人和计算机交流的语言。(C++、Java)
人与人沟通的语言:汉语、英语…
2. C语言 广泛应用于底层开发,例如:Linux 操作系统就是用 C语言 写的。它是一个面向过程的语言,而 C++、Java 是面向对象的语言。
3. 二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为 C语言 制定了一套完整的美国国家标准语法,称为 ANSI-C,作为 C语言 最初的标准。目前最新的标准为 C11.
4. C语言 编译器主要有 Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。其中 Linux 用的是 GCC,VS 系列底层用的是 MSVC.
一、C语言 使用的 IDE
IDE:Integrated Development Environment (集成开发环境)
C 语言常使用的 IDE,为 Visual Studio.
使用 Visual Studio 步骤:
① 创建新项目 => 空项目 => 选择路径创建 => 创建一个 " .c 源文件 "
② 可以在一个项目中,创建多个源文件,之后就可以写代码了。
二、第一个 C语言 程序
#include <stdio.h> int main() { printf("hello world\n"); return 0; }
输出结果:
注意事项:
① main 称为主函数,它本身就是一个函数。此外,我们应该明白:main 函数是一个程序的入口,一个工程中(Project) 有且仅有一个。
② main 前面的 " int " 为主函数的返回类型,和最后面的 " return 0; " 对应了起来。
③ " printf " 称为格式化输出函数,它是由 C语言 官方提供的库函数,如果我们想要使用库函数,就需要在程序的最开始引入对应的头文件,即 " #include <stdio.h> ".
stdio 为标准输入输出的意思。(standard - input - output)
三、C语言 的数据类型
注意: C 语言没有字符串类型。
// 1. 内置数据类型 char // 字符数据类型 short // 短整型 int // 整形 long // 长整型 long long // 更长的整形 float // 单精度浮点数 double // 双精度浮点数 // 2. 自定义类型 struct //结构体 enum //枚举 union // 联合体 ...
程序清单:
#include <stdio.h> int main() { printf("%d\n", sizeof(char)); printf("%d\n", sizeof(short)); printf("%d\n", sizeof(int)); printf("%d\n", sizeof(long)); printf("%d\n", sizeof(long long)); printf("%d\n", sizeof(float)); printf("%d\n", sizeof(double)); return 0; }
输出结果:
注意事项:
① sizeof 是一个操作符,它是用来计算变量(类型)大小的,计算单位是 " 字节 "。
② 计算机的基本单位:bit (比特位):只能由 1 或 0 构成。
byte (字节): 1 byte = 8 bit
KB:1 KB = 1024 byte
MB:1 MB = 1024 KB
GB:1 GB = 1024 MB
TB:1 TB = 1024 GB
…
四、变量与常量
C 语言用变量与常量来描述一些概念。
变量是用来描述变化的数据,常量是用来描述不变的数据。
int age; // 用变量描述年龄 char ch = 'a'; // 用变量描述一个字符 #define NAME JACK // 用常量描述一个人的名字
五、局部变量与全局变量
通俗理解,局部变量就是在大括号内,全局变量就是在大括号外;当局部变量和全局变量重复存在时,大括号内的程序以局部变量为准。
#include <stdio.h> int a = 123; // 全局变量 void test() { printf("%d\n", a); } int main() { int a = 100; // 局部变量 printf("%d\n", a); test(); return 0; }
输出结果:
六、变量的作用域和生命周期
注意事项:
实际上,关于局部变量和全局变量,它们的概念与变量的作用域和生命周期有关。
变量的作用域:一个变量名在一个程序中所能起作用的范围;
变量的生命周期:指的是变量的创建到变量的销毁之间的一个时间段。
① 局部变量的作用域是变量所在的局部范围,一般来说,局部变量的作用域就是它所在的一个函数内部;而全局变量的作用域是整个工程。
② 局部变量的生命周期是从进入作用域生命周期开始,出作用域生命周期结束;全局变量的生命周期是整个程序的生命周期。
③ 一个全局变量不给初始化,默认为0;而一个局部变量不给初始化,默认是随机值(在 VS 编译器下会直接报错)
七、变量的创建与使用
变量的创建,需要在底层开辟内存空间。
int a = 10; // 把 10 赋值给 变量 a
八、常量
常量分为四种:
字面常量、const 修饰的常变量、#define 定义的标识符常量、枚举常量。
1. 字面常量
字面常量很好理解,就是我们平时看到的值。
#include <stdio.h> int main() { 3.1415926; // 字面常量 100; 'a'; return 0; }
2. const 修饰的常变量
被 const 修饰的变量,具有常属性,但本质上被修饰的量依旧是一个变量。
程序清单1
#include <stdio.h> int main() { const int a = 10; // a = 20; // error1 // int arr[a] = { 0 }; // error2 return 0; }
注意事项:
① 在上面代码的注释中,error1 表示 常变量a 不能被修改
② error2 表示在定义一个数组元素数量时,括号中应该填入常量 (暂不考虑变长数组)
程序清单2
#include <stdio.h> int main() { int a = 10; int b = 100; const int* pa = &a; pa = &b; // √ //*pa = 20; // error1 int* const pa2 = &a; *pa2 = 20; // √ //pa2 = &b; // error2 return 0; }
注意事项:
① const 处于 * 号的左边,表示指针 pa 指向的对象不能通过解引用来改变。
② const 处于 * 号的右边,表示指针 pa2 本身地址不可被改变。
3. #define 定义的标识符常量、宏
被 #define 修饰的量作为标识符常量,是我们在 C语言 中最普遍的常量使用方式。此外,#define 也可以定义宏,和函数的功能类似。
注意写法:被 define 修饰的常量或宏,字母应为大写,整个表达式后面不跟逗号。
#include <stdio.h> // define 定义常量 #define MAX 100 #define STR "hello world" // define 定义宏,宏带有参数 #define ADD(x,y) (x+y) int main() { printf("%d\n", MAX); // printf("%d\n", 100); printf("%s\n", STR); // printf("%s\n", "hello world"); int a = 10; int b = 20; int sum = ADD(a, b); // int sum = (a+b); printf("%d\n", sum); return 0; } s
输出结果:
4. 枚举常量
枚举就是一一列举的意思,生活中有些概念可以被我们人为一一列举出来,如:性别、三原色。性别不是男就是女、三原色为 rgb. 所以,C语言 提供了一种自定义类型的方法,称为 enum,即枚举。
#include <stdio.h> enum SEX { MALE, FEMALE }; enum COLOR { RED, GREEN, BLUE }; int main() { // RED = 3; // error printf("%d\n", RED); printf("%d\n", GREEN); printf("%d\n", BLUE); return 0; }
输出结果:
注意事项:
① 注意枚举的写法,枚举大括号内的量称为枚举常量,不能被修改。
② 枚举常量的值默认是从 0 开始,依次向下递增。
九、字符串
#include <stdio.h> #include <string.h> int main() { char arr1[] = "abcdef"; char arr2[] = "abc\0def"; char arr3[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; char arr4[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0'}; printf("%s\n", arr1); printf("%s\n", arr2); printf("%s\n", arr3); printf("%s\n\n", arr4); printf("%d\n", strlen(arr1)); printf("%d\n", strlen(arr2)); printf("%d\n", strlen(arr3)); // 随机值 printf("%d\n", strlen(arr4)); return 0; }
输出结果:
调试窗口:
注意事项:
① 在 C语言中,被双引号括起来是字符串字面值,简称为字符串。同样地,字符串也只能被双引号括起来。
② 字符串的结束标志是一个 \0 的转义字符。在使用格式化输出时,\0 的作用相当于告诉了编译器,\0 是一个停止的标志。在使用 strlen 这个库函数计算字符串的长度时,也是一样的道理,它只计算 \0 之前的长度。
③ 对比 arr1 和 arr3 这两个创建字符数组的方式,可以发现,由于在 C语言 中,内存具有连续性,所以如果没有 \0 作为结束标志,就会导致我们使用 printf / strlen 的时候,一直向后找 \0 这个结束标志。
十、转义字符
转义字符 | 释义 |
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\’ | 表示字符常量单引号 |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠 |
\a | 警告字符,蜂鸣器 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | 将八进制数字转换成十进制数字 (ddd表示1 ~ 3个八进制的数字) |
\xdd | 将十六进制数字转换成十进制数字 (dd表示 2 个十六进制的数字) |
对最后两个转义字符进行验证:
#include <stdio.h> #include <string.h> int main() { printf("%c\n", '\135'); // 1*8^2 + 3*8^1 + 5*8^0 = 93 printf("%c\n", '\x65'); // 6*16^1 + 5*16^0 = 101 printf("%d\n", strlen("\t\628")); // '\t ' + '\62' + '8' (三个字符) return 0; }
输出结果:
注意事项:
① 第一个输出结果,C语言 通过转义字符,是先将 " 八进制 135 " 转换成 " 十进制 93 " 存储到内存中,当我们需要以字符的形式格式化输出 93 时,它再根据 ASCII 码表转换成了对应的符号。第二个输出结果,也是同样的道理。
② 第三个输出结果,strlen 是用来字符串的长度的,由于八进制中只有 0~7 生效,所以上面的 ’ \t\628 ’ 相当于 ’ \t ’ + ’ \62 ’ + ’ 8 ’ 这三个字符组成的。
十一、注释
方式一:不能嵌套注释 /* */ 方式二:可以注释一行也可以注释多行 //
十二、顺序、选择、循环
C语言 的程序设计和我们日常生活息息相关,我们日常生活中,基本上所有的事情都包括了顺序、选择、循环这三个方式。
① 顺序:我们平时写的代码就是自一个方法进入,之后再从此方法出来,这就是顺序执行的结构。
② 选择:if 语句、if - else 语句、if - else if - else 语句…
③ 循环:while 语句、for 语句、do … while 语句…
十三、数组
数组是一组相同类型元素的集合。
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; // 定义一个整形数组,最多放 10 个元素
下面的代码涉及到变长数组的概念,在定义一个数组的时候,可以允许指定数组的大小为一个变量。
#include <stdio.h> int main() { int n = 10; int arr[n]; return 0; }
另外,上面面的代码在 VS 编译器下可能会报错,但实际上是因为 VS 不支持 C99标准。而在 Linux 中使用 GCC 编译器则不会报错。
十四、操作符
// 1. 算数操作符 + - * / % // 2. 移位操作符 >> << // 3. 位操作符 & ^ | // 4. 赋值操作符 = += -= *= /= &= ^= |= >>= <<= // 5. 单目操作符 ! // 逻辑反操作 - // 负值 + // 正值 & // 取地址 sizeof // 操作数的类型长度(以字节为单位) ~ // 对一个数的二进制按位取反 -- // 前置、后置-- ++ // 前置、后置++ * // 间接访问操作符(解引用操作符) (int) // 强制类型转换为int // 6. 关系操作符 > >= < <= != // 用于测试“不相等” == // 用于测试“相等” // 7. 逻辑操作符 && // 逻辑与 || // 逻辑或 // 8. 条件操作符 a ? b : c // 9. 逗号表达式 exp1, exp2, exp3... // 10. 其他操作符 [] // 下标引用操作符 () // 函数调用操作符 . // 结构体变量.成员名 -> // 结构体指针变量->结构体成员