C 语言编程教程

C 语言 - 首页

C 语言基础

C 语言 - 概述 C 语言 - 特性 C 语言 - 发展历史 C 语言 - 环境设置 C 语言 - 程序结构 C 语言 - Hello World C - 编译过程 C - 注释 C - 标记 C - 关键字 C - 标识符 C - 用户输入 C - 基本语法 C - 数据类型 C - 变量 C - 整数提升 C - 类型转换 C - 类型转换 C - 布尔值

C 语言中的常量和文字

C - 常量 C - 字面量 C - 转义序列 C - 格式说明符

C 语言中的运算符

C - 运算符 C - 算术运算符 C - 关系运算符 C - 逻辑运算符 C - 位运算符 C - 赋值运算符 C - 一元运算符 C - 递增和递减运算符 C - 三元运算符 C - sizeof 运算符 C - 运算符优先级 C - 其他运算符

C 语言中的决策

C - 决策 C - if 语句 C - if...else 语句 C - 嵌套 if 语句 C - switch 语句 C - 嵌套 switch 语句

C 语言中的循环

C - 循环 C - While 循环 C - For 循环 C - Do...while 循环 C - 嵌套循环 C - 无限循环 C - Break 语句 C - Continue 语句 C - goto 语句

C 语言中的函数

C - 函数 C - Main 函数 C - 按值调用函数 C - 按引用调用函数 C - 嵌套函数 C - 可变参数函数 C - 用户定义函数 C - 回调函数 C - return 语句 C - 递归

C 语言中的作用域规则

C - 作用域规则 C - 静态变量 C - 全局变量

C 语言中的数组

C - 数组 C - 数组的属性 C - 多维数组 C - 将数组传递给函数 C - 从函数返回数组 C - 可变长度数组

C 语言中的指针

C - 指针 C - 指针和数组 C - 指针的应用 C - 指针运算 C - 指针数组 C - 指向指针的指针 C - 将指针传递给函数 C - 从函数返回指针 C - 函数指针 C - 指向数组的指针 C - 指向结构体的指针 C - 指针链 C - 指针 vs 数组 C - 字符指针和函数 C - NULL 指针 C - void 指针 C - 悬垂指针 C - 解引用指针 C - Near、Far 和 Huge 指针 C - 指针数组的初始化 C - 指针与多维数组

C 语言中的字符串

C - 字符串 C - 字符串数组 C - 特殊字符

C 语言的结构体和联合

C - 结构体 C - 结构体和函数 C - 结构体数组 C - 自引用结构 C - 查找表 C - 点 (.) 运算符 C - 枚举(或 enum) C - 结构填充和打包 C - 嵌套结构 C - 匿名结构和联合 C - 联合 C - Bit 位字段 C - Typedef

C 语言中的文件处理

C - 输入和输出 C - 文件 I/O(文件处理)

C 语言中的预处理器

C - 预处理器 C - #pragma 编译指示 C - 预处理器操作符 C - 宏 C - 头文件

C 语言中的内存管理

C - 内存管理 C - 内存地址 C - 存储类

C 其他主题

C - 错误处理 C - 可变参数 C - 命令执行 C - 数学函数 C - static 静态关键字 C - 随机数生成 C - 命令行参数

C 语言编程资源

C语言问题与解答答案 C语言快速指南 C语言速查表 C语言实用资源 C语言讨论


C 语言 - 速查表

这份 C 语言速查表快速概述了 C 语言概念,从基础到高级。它对学生、开发者以及准备面试的人士都非常有用。阅读这份速查表,您将学习 C 编程语言 的所有基础和高级概念。

C 语言速查表

C 程序的基本结构

C 程序的基本结构 让您了解用 C 语言编写程序所需的基本语句。以下是 C 程序的基本结构 -

// 预处理指令/头文件包含部分
#include <stdio.h>

// 全局声明部分

// main() 函数
int main() {
    // 变量声明部分
    int x, y;
    
    // 其他代码语句部分
    
    // 返回 o
    return 0;
}
// 其他用户定义函数定义部分

#include <stdio.h>

#include 是一个预处理指令,用于在 C 程序中包含头文件。 stdio.h 是一个头文件,其中定义了所有与输入和输出相关的函数。

main() 函数

main() 函数是 C 程序的入口点,程序的执行从 main() 函数开始。

以下是 main() 函数的语法 -

int main() {
   return 0;
}

注释

C 语言中有两种类型的注释:单行注释和多行注释。注释会被编译器忽略。

单行注释

使用 // 编写单行注释。

// 这是单行注释

多行注释

在 C 语言中,在文本前后使用 /* 和 */ 编写多行注释。

/*
这是第 1 行
这是第 2 行
..
*/

打印(printf() 函数)

printf() 函数是一个库函数,用于在控制台输出上打印格式化的文本。无论何时需要打印任何内容,都可以使用 printf()。

示例

printf("Hello world");

用户输入(scanf() 函数)

scanf() 函数用于接收用户的各种类型的输入。

以下是 scanf() 函数的语法 -

scanf("format_specifier", &variable_name);

格式说明符

以下是 printf()scanf() 函数中用于打印/输入特定类型值的 C 格式说明符列表。

格式说明符 类型
%c 字符
%d 有符号整数
%e 或 %E 科学计数法浮点数
%f 浮点值
%g 或 %G 类似于 %e 或 %E
%hi 有符号整数(短整型)
%hu 无符号整数(短整型)
%i 无符号整数
%l 或 %ld 或%li 长整型
%lf 双精度型
%Lf 长整型
%lu 无符号整型或无符号长整型
%lli 或 %lld 长整型
%llu 无符号长整型
%o 八进制表示
%p 指针
%s 字符串
%u 无符号整数
%x 或 %X 十六进制表示

示例

#include <stdio.h>

int main(){

   int age = 18;

   float percent = 67.75;

   printf("Age: %d 
Percent: %f", age, percent);

   return 0;
}

输出

Age: 18 
Percent: 67.750000

数据类型

数据类型指定变量中存储的数据的类型和大小。数据类型分为三类:-

  • 基本数据类型
  • 派生数据类型
  • 用户自定义数据类型

基本数据类型

基本数据类型是 C 语言的内置数据类型,也可用于创建派生数据类型。

数据类型 名称 描述
int 整数 表示整数值
char 字符 表示单个字符
浮点型 浮点型 表示浮点值

派生数据类型

派生数据类型源自基本数据类型。派生数据类型包括:-

  • 数组
  • 指针

用户定义数据类型

用户定义数据类型由程序员根据需求创建,用于处理不同类型的数据。用户定义数据类型包括:-

  • 结构体
  • 联合体
  • 枚举

基本输入和输出

对于C 语言中的基本输入和输出,我们使用 printf()scanf() 函数。

printf() 函数用于在控制台上打印格式化的文本。

printf("Hello world");

scanf() 函数用于接收用户的输入。

scanf("%d", &x); // 整数输入
scanf("%f", &y); // 浮点数输入
scanf("%c", &z); // 字符输入
scanf("%s", name); // 字符串输入

基本输入和输出示例

#include <stdio.h>

int main() {
   int num;

   printf("Input any integer number: ");
   scanf("%d", &num);

   printf("The input is: %d
", num);

   return 0;
} 

输出

Input any integer number: The input is: 0

标识符

C 标识符是用户定义的变量、常量、函数等的名称。以下是定义标识符的规则:

  • 关键字不能用作标识符。
  • 标识符中只能包含字母、下划线 (_) 和数字。
  • 标识符必须以字母或下划线开头。
  • 同一个标识符不能用作两个实体的名称。
  • 标识符应该有意义且具有描述性。

有效标识符示例

age, _name, person1, roll_no

关键字

C 关键字 是 C 编译器中的反转词,用于特定目的,不得用作标识符。

以下是 C 语言中的关键字 -

autodoubleintstruct
breakelselongswitch
caseenumregistertypedef
charexternreturnunion
continueforsignedvoid
doifstaticwhile
defaultgotosizeofvolatile
constfloatshortunsigned

变量

C 变量 是程序用来访问和操作数据的存储区域的名称。

声明变量的语法

data_type variable_name;

转义序列

转义序列是特殊字符后跟转义符(反斜杠 \)。转义序列具有特殊含义,用于打印那些无法正常打印的字符。

以下是 C 语言中的转义序列列表 -

转义序列 含义
\ \ 字符
\' ' 字符
\" " 字符
\? ?字符
\a 提醒或铃声
\b 退格键
\f 换页符
换行符
回车符
水平制表符
\v 垂直制表符
\ooo 一到三位数字的八进制数
\xhh . . . 一位或多位数字的十六进制数

运算符

运算符是用于执行特定数学或逻辑运算的特殊符号。

以下是 C 语言中使用的运算符 -

运算符 符号 描述
赋值运算符 =、+=、-=、<<= 执行赋值运算,即将值赋给变量。
算术运算符 +、-、*、/、% 执行算术运算。
关系运算符 <、>、<=、>=、==、!= 对两个操作数进行比较。
逻辑运算符 &&、||、! 执行逻辑运算,例如逻辑与、或和非。
位运算符 &、^、|、<<、>>、~ 执行按位运算。
三元运算符 ? : 执行条件运算以进行决策。
其他运算符 sizeof、&、*、⇒、. 用于执行各种其他运算。

运算符示例

result = num1 + num2;
if(result >=10){
   printf("Greater than 10.");
}

条件语句

C 语言提供以下条件语句 -

  • if 语句
  • if-else 语句
  • if-else-if 语句
  • 嵌套 if-else 语句
  • switch 语句
  • 三元运算符

if 语句

if 语句由一个布尔表达式后跟一个或多个语句组成。

if 语句的语法为 -

if(boolean_expression) {
    /* 如果布尔表达式为真,则执行语句*/
}

if-else 语句

if-else 语句后面可以跟一个可选的 else 语句,该语句在布尔表达式为 false 时执行。

if 语句的语法为 −

if (Boolean expr){
   Expression;
   . . .
}
else{
   Expression;
   . . .
}

if-else-if 语句

if-else-if 语句也称为阶梯式 if-else。它用于在某个条件不成立时检查多个条件。

if-else-if 语句的语法 -

if(condition1){
}
else if(condition2){
}

else{
}

嵌套 if 语句

通过使用嵌套 if 语句,您可以在一个 if 或 else-if 语句中使用另一个 if 或 else-if 语句。

嵌套 if 语句的语法 -

if (expr1){
   if (expr2){
      block to be executed when 
      expr1 and expr2 are true
   }
   else{
      block to be executed when 
      expr1 is true but expr2 is false
   }        
}

Switch 语句

switch 语句 允许测试变量与值列表的相等性。

switch 语句的语法为 -

switch (Expression){

   // 如果 expr 等于 Value1
   case Value1: 
      Statement1;
      Statement2;
      break;
   
   // 如果 expr 等于 Value2
   case Value2: 
      Statement1;
      Statement2;
      break;
      .
      . 
   // 如果 expr 与上述特定值不同
   default:
      Statement1;
      Statement2;
}

三元运算符

三元运算符 (?:) 也称为条件运算符。它可以替代 if-else 语句。

三元运算符的语法为 -

(条件) ? true_block: false_block;

循环

C 循环 用于按指定次数执行一个或多个语句块,或直到达到特定条件。以下是 C 语言中的循环语句 -

  • while 循环
  • do...while 循环
  • for 循环

while 循环

while 循环 是一个入口控制循环,在执行循环体之前会先检查条件。

while 循环的语法为:-

while(test_condition){
    // 语句;
}

dowhile 循环

dowhile 循环是一个出口控制循环,在检查条件之前会先执行循环体。

dowhile 循环的语法为:-

do{
    // 语句;
}while(test_condition);

for 循环

for 循环也是一种入口控制循环,其中元素(初始化、测试条件和增量)放在一起,用 for 关键字在括号内形成一个 for 循环。

for 循环的语法是 −

for(initialization ; test condition ; increment){
   // 语句;
}

跳转语句

跳转语句用于将程序流程从一个位置转移到另一个位置。以下是 C 语言中的跳转语句 -

  • goto 语句
  • break 语句
  • continue 语句

goto 语句

goto 语句将程序的控制权转移到特定标签。您需要定义一个标签,后跟冒号 (:)。goto 语句可以将程序流程向上或向下转移。

goto 语句的语法为 -

label_name:

//Statement(s)
if(test_condition){
   goto label_name;
}

break 语句

break 语句可与循环和 switch 语句一起使用。break 语句终止循环执行,并将程序的控制权转移到循环体之外。

break 语句的语法为 -

while(condition1){
   . . .
   . . .
   if(condition2)
   break;
      . . .
      . . .
}

continue 语句

continue 语句用于跳过当前迭代中循环内其余语句的执行,并将其转移到下一次循环迭代。

continue 语句的语法为 -

while (expr){
   . . .
   . . .
   if (condition)
      continue;
   . . .
}

用户定义函数

用户定义函数由用户定义,用于执行特定任务,从而实现代码的可重用性和模块化。

用户定义函数示例

#include <stdio.h>

// 函数声明
int add(int, int);

// 函数定义
int add(int a, int b) { return (a + b); }

int main() {
   int num1 = 10, num2 = 10;
   int res_add;

    // 调用函数
    res_add = add(num1, num2);
    
    // 打印结果
   printf("Addition is : %d
", res_add);

   return 0;
}

输出

Addition is : 20

数组

数组是存储在连续内存位置的相似数据类型的数据项的集合。数据项可以是基本数据类型(int、float、char),也可以是用户定义的类型,例如结构体或指针,这些类型可以存储在数组中。

C 数组 可以分为两种类型:-

  • 一维 (1D) 数组 - 一维数组是同一数据类型的数据项的单个列表。
  • 多维数组 - 多维数组(例如二维数组)是数组的数组。

数组的语法

以下是不同类型数组声明的语法:-

type array_name [size1]; // 一维数组
type array_name [size1][size2]; // 二维数组
type array_name [size1][size2][size3]; // 三维数组

一维数组示例

#include <stdio.h>

int main(){
   int numbers[5] = {10, 20, 30, 40, 50};

   int i;  // 循环计数器

   // 打印数组元素
   printf("The array elements are : ");
   for (i = 0; i < 5; i++) {
      printf("%d ", numbers[i]);
   }

   return 0;
}

输出

The array elements are : 10 20 30 40 50 

二维数组示例

#include <stdio.h>

int main () {

   /* 一个 5 行 2 列的数组 */
   int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
   int i, j;
 
   /* 输出每个数组元素的值 */
   for ( i = 0; i < 5; i++ ) {
      for ( j = 0; j < 2; j++ ) {
         printf("a[%d][%d] = %d
", i,j, a[i][j] );
      }
   }
   
   return 0;
}

输出

a[0][0] = 0
a[0][1] = 0
a[1][0] = 1
a[1][1] = 2
a[2][0] = 2
a[2][1] = 4
a[3][0] = 3
a[3][1] = 6
a[4][0] = 4
a[4][1] = 8

字符串

C 字符串 是一个字符序列,即一个 char 数据类型的数组,以 '\0' 表示的"空字符"结尾。要使用 scanf() 和 printf() 函数读取和打印字符串,必须使用 "%s" 格式说明符。

字符串声明

char string_name[size];

读取字符串

scanf("%s", string_name);

打印字符串

printf("%s", string_name);

C 字符串示例

#include <stdio.h>

int main() {
   char name[20];

   printf("Enter a name: ");
   scanf("%s", name);

   printf("You entered: %s", name);

   return 0;
}

字符串函数

C 标准库 string.h 提供了各种处理字符串的函数。以下是 C 字符串函数列表:

序号 函数 描述
1 char *strcat src 指向的字符串附加到 dest 指向的字符串的末尾。
2 char *strncat src 指向的字符串附加到 dest 指向的字符串的末尾,最多 n 个字符。
3 char *strchr( 在参数 str 指向的字符串中搜索字符 c(无符号字符)的第一次出现。
4 int strcmp 比较 str1 指向的字符串和 str2 指向的字符串。
5 int strncmp 最多比较 str1str2 的前 n 个字节。
6 int strcoll 比较字符串 str1str2。结果取决于位置的 LC_COLLATE 设置。
7 char *strcpy src 指向的字符串复制到 dest
8 char *strncpy src 指向的字符串最多 n 个字符复制到 dest
9 size_t strcspn 计算 str1 中完全由 str2 中不存在的字符组成的初始段的长度。
10 char *strerror 在内部数组中搜索错误号 errnum,并返回指向错误消息字符串的指针。
11 size_t strlen 计算字符串 str 的长度,不包括终止空字符。
12 char *strpbrk 在字符串 str1 中查找第一个与 str2 中指定的任意字符匹配的字符。
13 char *strrchr 在参数 str 指向的字符串中搜索字符 c(无符号字符)的最后一次出现。
14 size_t strspn 计算 str1 中完全由 str2 中的字符组成的初始段的长度。
15 char *strstr 查找整个字符串 needle(不包括终止空字符)在字符串 haystack 中的第一次出现。
16 char *strtok 将字符串 str 拆分为一系列由 delim 分隔的标记。
17 size_t strxfrm 将字符串 src 的前 n 个字符转换为当前语言环境,并将它们放入字符串 dest 中。

结构体

C 结构体是不同数据类型的集合。结构体被视为用户定义的数据类型,您可以在其中对不同类型的数据项进行分组。

结构体声明语法

struct struct_name {
   type1 item1;
   type2 item2;
   .
   .
}structure_variable;

结构示例

#include <stdio.h>

struct book{
   char title[10];
   char author[20];
   double price;
   int pages;
};

int main(){
   struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};
   
   printf("Title:  %s 
", book1.title);
   printf("Author: %s 
", book1.author);
   printf("Price:  %lf
", book1.price);
   printf("Pages:  %d 
", book1.pages);
   printf("Size of book struct: %d", sizeof(struct book));
   return 0;
}

输出

Title:  Learn C 
Author: Dennis Ritchie 
Price:  675.500000
Pages:  325 
Size of book struct: 48

联合

C 联合 是一种用户定义的数据类型,允许将一组不同类型的数据项存储在同一内存位置。

联合声明的语法

union [union tag]{
   member definition;
   member definition;
   ...
   member definition;
} [one or more union variables];

联合示例

#include <stdio.h>

union Data{
   int i;
   float f;
};

int main(){
   union Data data;        
   
   data.i = 10;
   data.f = 220.5;
   
   printf("data.i: %d 
", data.i);
   printf("data.f: %f 
", data.f);
   return 0;
}

输出

data.i: 1130135552 
data.f: 220.500000 

枚举 (enums)

C 枚举 (enum) 是一种枚举数据类型,由一组整型常量组成。

枚举声明的语法

enum myenum {val1, val2, val3, val4};

枚举 (enum) 示例

#include <stdio.h>

enum status_codes { OKAY = 1, CANCEL = 0, ALERT = 2 };

int main() {
   // 打印值
   printf("OKAY = %d
", OKAY);
   printf("CANCEL = %d
", CANCEL);
   printf("ALERT = %d
", ALERT);

   return 0;
}

输出

OKAY = 1
CANCEL = 0
ALERT = 2

指针

C 指针 是一种派生数据类型,用于存储另一个变量的地址,也可用于访问和操作存储在该位置的变量数据。

指针声明的语法

data_type *pointer_name;

指针初始化的语法

如果您声明了一个指针,以下是使用另一个变量的地址初始化指针的语法 -

pointer_name = &variable_name;

指针示例

#include <stdio.h>

int main() {
    int x = 10;
    
    // 指针声明和初始化
    int * ptr = & x;
    
    // 打印当前值
    printf("Value of x = %d
", * ptr);

    // 更改值
    * ptr = 20;
    
    // 打印更新后的值
   printf("Value of x = %d
", * ptr);

   return 0;
}

输出

Value of x = 10
Value of x = 20

指针的类型

C 语言中有多种类型的指针。它们是:-

动态内存分配

变量的内存在编译时声明。 C 语言提供了一些动态内存分配函数,允许在运行时为变量分配内存。

动态内存分配函数如下:-

  • malloc()
  • calloc()
  • realloc()
  • free()

malloc() 函数

malloc() 函数分配请求的内存(指定大小的块数),并返回指向该内存的指针。

malloc() 函数的语法如下:-

malloc (size_t size);
calloc() 函数

calloc() 函数

calloc() 函数分配请求的内存(指定大小的块数)并返回 void 指针。 calloc() 函数将分配的内存设置为零。

calloc() 函数的语法为 -

void *calloc(size_t nitems, size_t size)

realloc() 函数

realloc() 函数 尝试调整先前通过调用 malloc() 或 calloc() 函数分配的指针所指向的内存块的大小。

realloc() 函数的语法为 -

void *calloc(size_t nitems, size_t size)

free() 函数

free() 函数会释放先前通过 calloc()、malloc() 或 realloc() 调用分配的内存。

realloc() 函数的语法为:-

void *calloc(size_t nitems, size_t size)

文件处理

文件处理是指对文件执行各种操作,例如创建、写入、读取、删除、移动、重命名文件等。C 语言提供了各种文件处理函数。

文件操作

以下是使用 C 语言文件处理函数可以执行的文件操作 -

  • 创建新文件
  • 打开现有文件
  • 将数据写入文件
  • 将数据附加到文件
  • 从文件读取数据
  • 重命名文件
  • 删除文件
  • 关闭文件

文件处理函数

以下是 C 语言文件处理函数列表 -

函数 描述
fopen() 创建并以各种模式打开文件。
fclose() 关闭文件。
fputc(), fputs(), fprintf() 将数据写入文件。
fgetc(), fgets(), fscanf() 从文件读取数据。
fwrite(), fread() 向二进制文件写入数据或从二进制文件读取数据。
rename() 重命名文件。
remove() 删除文件。

文件处理示例

以下是 C 语言文件处理示例 -

#include <stdio.h>
#include <stdlib.h>

int main() {
   FILE *file;
   char file_name[] = "my_file.txt";
   char write_data[100] = "Tutorials Point";
   char read_data[100];

   // 以写入模式打开文件
   file = fopen("file_name.txt", "w");
   if (file == NULL) {
      printf("Error
");
      return 1;
   }
    // 写入文件
    fprintf(file, "%s", write_data);
    // 关闭文件
    fclose(file);
    
    // 再次以读取模式打开文件
   file = fopen("file_name.txt", "r");
   if (file == NULL) {
      printf("Error.
");
      return 1;
   }

   // 从文件读取数据
   if (fgets(read_data, 100, file) != NULL) {
      // 将其打印在屏幕上
      printf("File's data:
%s
", read_data);
   }
   fclose(file);

   return 0;
}

输出

File's data:
Tutorials Point

预处理器指令

预处理器指令是预编译的一部分,以井号 (#) 字符开头。这些指令指示编译器在开始编译过程之前展开 include 并扩展代码。

以下是预处理器指令列表 -

指令 描述
# Define 替换预处理器宏。
# Include 插入来自另一个文件的特定头文件。
# Undef 取消定义预处理器宏。
#ifdef 如果此宏已定义,则返回 true。
#ifndef 如果此宏未定义,则返回 true。
#if 测试编译时条件是否为真。
#else #if 的替代方案。
#elif #else 和 #if 合二为一语句。
#endif 结束预处理器条件。
#error 在 stderr 上打印错误消息。
#pragma 使用标准化方法向编译器发出特殊命令。

预处理器指令示例

这是 #define 的示例,它是 C 语言中的预处理器指令之一 -

#define MAX_ARRAY_LENGTH 20

标准库

以下是常用库(C 头文件)的列表 -

头文件 用法
stdio.h 提供标准输入和输出函数。
string.h 提供各种字符串操作函数。
math.h 提供数学运算函数。
stdlib.h 提供各种用于内存分配、类型转换等的实用函数。
time.h 提供日期时间相关函数。