目录
1. 基本语法:变量、数据类型、运算符、表达式、控制流结构(if-else、for、while、do-while等)、函数
2. 指针:指针的基本概念、指针和数组、指针和字符串、指针和函数指针
3. 数组和字符串:数组的定义、初始化和访问、多维数组、字符串的定义、操作和处理
4. 结构体和联合体:结构体的定义及访问、结构体数组、结构体嵌套、联合体的定义及使用
5. 内存管理:堆和栈内存的分配与释放、动态内存分配(malloc、realloc、calloc、free)
6. 文件操作:打开、关闭、读、写文件、标准I/O函数(printf、scanf、fopen、fclose、fread等)
8. 数据结构和算法:链表、树、图、排序算法(冒泡、选择、插入、快排、归并等)
以下是C语言的一些主要知识点:
1. 基本语法:变量、数据类型、运算符、表达式、控制流结构(if-else、for、while、do-while等)、函数
1.1变量
C语言的变量是程序中用来存储数据的一个名称,它们是程序运行时动态的。以下是一些关于C语言变量的知识点:
1. 变量命名规则:C语言变量名由字母(大小写敏感)、数字和下划线组成,必须以字母或下划线开头,不能使用C语言关键字作为变量名。
2. 变量定义:在C语言中,可以通过定义变量来声明变量的类型、名称和初始值(可选)。例如,int a = 10; 定义了一个整型变量a并赋初值为10。
3. 变量类型:C语言支持多种变量类型,包括基本类型(int、float、double、char等)、复合类型(数组、结构体、共用体等)和指针类型等。
4. 变量作用域:变量的作用域指的是变量在程序中可以被访问的范围。C语言中,变量可以是全局变量或局部变量,全局变量在程序任何地方都可以被访问,局部变量只能在定义它的函数中被访问。
5. 变量存储类别:存储类别是指变量在内存中的存储位置和生命周期。C语言中有4种存储类别:自动存储类别(auto)、寄存器存储类别(register)、静态存储类别(static)和外部存储类别(extern)。
6. 常量:常量是指在程序中固定不变的值,C语言中有数字型常量(整型、实型)、字符型常量和字符串型常量等多种类型。
以上是关于C语言变量的一些知识点,需要注意的是,变量的定义和使用需要遵循C语言的语法规则,否则会导致编译错误。
1.2数据类型
C语言中的基本数据类型有以下几种:
1. 整型 整型是最基本的数据类型之一,包括有符号和无符号两种类型。其中,有符号整型可表示正数、负数和零,而无符号整型只能表示非负数(零和正整数)。 C语言中的整型变量的关键字是`int`,其占用的存储空间取决于编译器和操作系统,但通常为2或4个字节。另外,还有`short int`和`long int`类型,分别比`int`短和长,分别占用2字节和4字节的存储空间。 例如:
int a = 10;
unsigned int b = 20;
short int c = 30;
long int d = 40;
2. 实型 实型包括两种类型:单精度浮点数(float)和双精度浮点数(double),分别用于表示单精度和双精度浮点数,需要使用`float`和`double`关键字来定义。 在C语言中,float类型占用4字节的存储空间,而double类型占用8字节的存储空间。 例如:
float f = 3.14;
double d = 1.23456;
3. 字符型 字符型用于表示字符类型的数据,使用`char`关键字定义。注意,虽然字符型语法上是一个整型,但它占用的存储空间只有1个字节。 例如:
char ch = 'A';
4. 布尔型 C语言中没有直接定义布尔型,但通过标准库中的stdbool.h头文件,可以使用_Bool类型,其定义了真(true)和假(false)两种值。有些编译器也可以通过`bool`类型来实现。 例如:
#include <stdbool.h>
_Bool b = true;
bool b2 = false;
总之,C语言数据类型非常重要,它们帮助程序员更好地理解和操作数据,合理选择数据类型是非常重要的,不仅可以更好地利用计算机的空间和速度,还可以更好地保证代码的安全和正确性。
1.3运算符
在C语言中,运算符用于对数据进行操作和计算。以下是C语言中常用的运算符及其用法:
1. 算术运算符 算术运算符用于执行基本算术操作,如加、减、乘、除和模(取余)。
例如:
int a = 10;
int b = 3;
int sum = a + b; // 13
int diff = a - b; // 7
int product = a * b; // 30
int quotient = a / b; // 3
int remainder = a % b;//1
2. 关系运算符 关系运算符是用于比较两个值之间的关系的运算符,返回结果为“真”或“假”。
运算符 | 描述 | 示例 |
== | 相等 | 5==3 |
!= | 不等 | 5!=3 |
> | 大于 | 5>3 |
< | 小于 | 5<3 |
>= | 大于等于 | 5>=3 |
<= | 小于等于 | 5<=3 |
例如:
int a = 10;
int b = 3;
int result1 = a == b; // 0
int result2 = a > b; // 1
int result3 = a <= b; // 0
3. 逻辑运算符 逻辑运算符通常用于将多个关系表达式组合起来形成更复杂的逻辑表达式,返回结果为“真”或“假”。
运算符 | 描述 | 示例 |
! | 非 | !(5==3) |
&& | 并且,当且仅当都为真 | (5>3) && (10<20) |
|| | 或者,当且仅当一个为真 | (5>3) ||(10>20) |
例如:
int a = 10;
int b = 3;
int result1 = !(a == b); // 1
int result2 = (a > b) && (a < 20); // 1
int result3 = (a < b) || (a > 20); // 0
4. 自增和自减运算符 自增运算符(`++`)和自减运算符(`--`)分别用于将变量的值增加和减少1。
运算符 | 描述 | 示例 |
++ | 自增,加1 | a = 5; a++; |
-- | 自减,减1 | b = 5; b--; |
例如: int a = 5;
int b = 5;
a++;
b--;
printf("a=%d, b=%d\n", a, b); // a=6, b=4
5. 赋值运算符 赋值运算符(`=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|= `)用于将一个值赋给变量。
例如: int a = 5;
a += 3; // 相当于 a = a + 3;
a *= 2; // 相当于 a = a * 2;
总之,在C语言中,运算符是非常基础和重要的知识点,熟练掌握和合理运用这些运算符能够有效地优化代码和提高程序的执行效率。
1.4表达式
在C语言中,表达式是由操作数、操作符和括号组成的语法结构。以下是C语言中常用的表达式和其组成部分的相关知识点:
1. 算术表达式 算术表达式由算术运算符和操作数组成。操作数可以是变量、常量或其他表达式。
例如: int a = 5;
int b = 3;
int result = (a + b) * 2 / 2 - 4; // 6
2. 关系表达式 关系表达式由关系运算符和操作数组成。关系运算符用于比较两个值之间的关系,返回结果为“真”或“假”。
例如: int a = 5;
int b = 3;
int result = (a > b); // 1
3. 逻辑表达式 逻辑表达式由逻辑运算符和操作数组成。逻辑运算符用于将多个关系表达式组合起来形成更复杂的逻辑表达式,返回结果为“真”或“假”。
例如: int a = 5;
int b = 3;
int result = (a > b) && (a < 10); // 1
4. 条件表达式 条件表达式也称为三元运算符。它由三个操作数组成,即一个条件表达式、一个真表达式和一个假表达式。
例如: int a = 5;
int b = 3;
int result = (a > b) ? a : b; // 5
5. 位运算表达式 位运算表达式用于操作二进制位。它由位运算符和操作数组成。常见的位运算符有按位与(&)、按位或(|)、按位异或(^)、左移(<<)和右移(>>)。
例如: int a = 5;
int b = 3;
int result = a & b; // 1
6. 函数调用表达式 函数调用表达式由函数名、参数和括号组成。参数是传递给函数的值列表。
例如: int add(int a, int b)
{
return a + b;
}
int result = add(5, 3); // 8
总之,在C语言中,表达式是非常基础和重要的知识点。
1.5控制流结构
在C语言中,控制流结构有三种类型:顺序结构、选择结构和循环结构。以下是它们的说明:
1. 顺序结构 顺序结构是程序中最基本的结构类型,它按照代码书写的顺序依次执行语句。
例如: int a = 5;
int b = 3;
int sum = a + b;
2. 选择结构 选择结构可以根据条件的不同,选择不同的代码块进行执行。常用的选择结构有:if语句和switch语句。 if语句只有当指定条件为真时才执行其中的语句块,否则跳过该语句块。
例如: int x = 10;
if (x > 5)
{
printf("x is greater than 5\n");
}
switch语句根据表达式的值,选择执行不同的代码块。
例如: int x = 3;
switch (x) {
case 1:
printf("x is 1\n");
break;
case 2:
printf("x is 2\n");
break;
default:
printf("x is not 1 or 2\n");
break;
}
3. 循环结构 循环结构是一种重复执行代码块的结构,当满足指定条件时,重复执行语句块直到条件不为真为止。常用的循环结构有:while循环、do-while循环和for循环。 while循环在指定条件为真时执行循环体内的语句,并反复执行循环体,直到条件不为真为止。
例如: int x = 1;
while (x < 5)
{
printf("x is %d\n", x);
x++;
}
do-while循环与while循环类似,不同的是它会首先执行一次循环体,然后再判断循环条件是否成立。
例如: int x = 1;
do
{
printf("x is %d\n", x); x++;
}
while (x < 5);
for循环是一种循环结构,可以在执行循环时控制循环的次数和变化。
例如: for (int i = 0; i < 5; i++)
{
printf("i is %d\n", i);
}
以上是C语言中常用的控制流结构,开发者可以根据需要选择不同的控制流结构,达到灵活控制程序执行流程的目的。
1.6函数
在C语言中,函数是一段可重复使用的代码块,它执行特定的任务并返回一个值。以下是C语言中函数相关的知识点:
1. 函数的声明和定义 在使用函数之前,需要先进行函数的声明或者定义。 声明只需要函数名称、参数和返回值类型。
例如: int add(int a, int b);
定义是函数的具体实现,包括函数名称、参数、返回类型和函数体。
例如: int add(int a, int b)
{
return a + b;
}
2. 函数的调用 使用函数需要在代码中调用该函数,调用函数时需要指定函数名称和参数(如果有的话)。
例如: int result = add(5, 3);
3. 函数的参数 函数的参数用于向函数内部传递数据。 在C语言中,参数可以是值参数或者指针参数。 值参数是指将数据的值传递给函数。 指针参数是指将数据的地址传递给函数,该函数可以在函数内部直接操作原始变量的值。
2. 指针:
C语言中,指针是一个非常重要的概念,它是指向内存地址的变量。指针提供了一种强大的方式,可以访问和操作内存中的数据。以下是C语言指针相关的知识点:
1. 指针的基本概念: 指针是一个变量,它存储了一个地址。可以使用星号(`*`)来声明指针变量,星号表示该变量是一个指针。可以使用取地址符(`&`)获取变量的地址,也可以使用星号(`*`)访问指针所指向的变量。
例如: int a = 5;
int *ptr;
ptr = &a;
printf("%d\n", *ptr); // 5
2. 指针和数组 :数组是一组由同种数据类型组成的有序集合,可以使用指针来操作数组。指针可以作为数组的名称使用,或者指向数组的第一个元素。
例如: int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;
printf("%d\n", *ptr); // 1
printf("%d\n", *(ptr+2)); // 3
3. 指针和字符串: 字符串是由字符数组表示的一组字符,使用指针可以方便地操作字符串。
例如: char str[6] = "hello";
char *ptr = str;
while (*ptr)
{
printf("%c", *ptr); ptr++;
}
4. 指针和函数指针: 函数指针是指向函数的指针变量。可以使用函数指针来访问和调用函数。
例如:
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*ptr)(int, int);
ptr = add;
printf("%d\n", ptr(5, 3)); // 8
return 0;
}
总之,在C语言中,指针是非常重要的概念,熟练掌握指针的使用能够让程序员更加清晰地访问和操作内存中的数据,进而提高代码的运行效率和可靠性。
3. 数组和字符串:
在C语言中,数组和字符串都是非常重要的概念。以下是C语言数组和字符串相关的知识点:
1. 数组的定义、初始化和访问 数组是由相同类型的元素组成的集合,使用数组可以方便地对一组数据进行处理。数组定义时需要指定数组名称、元素类型和元素个数。数组的初始化可以在定义时进行,也可以在之后进行。
例如: int arr[5] = {1, 2, 3, 4, 5};
数组的元素可以通过下标进行访问,下标从0开始计数。
例如: printf("%d\n", arr[2]); // 3
2. 多维数组 多维数组是由多个一维数组组成的,可以使用多个下标对数组元素进行访问。多维数组的定义需要指定数组名称、元素类型和每个维度的大小。
例如:
int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
printf("%d\n", arr[1][2]); // 7
3. 字符串的定义、操作和处理 字符串是由字符数组表示的一组字符,字符串以空字符`\0`作为结束符。可以使用字符串常量或字符数组来定义字符串,可以使用字符串库函数进行字符串的操作和处理。
例如:
char str1[] = "hello";
char str2[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
printf("%s\n", str1); // hello
printf("%s\n", str2); // hello
int len = strlen(str1); // 5
char *ptr = strchr(str1, 'l'); // 指向第一个'l'
总之,在C语言中,数组和字符串是非常基础且重要的知识点,程序员需要熟练掌握数组和字符串的定义、初始化和访问,以及多维数组和字符串的操作和处理方法,才能写出高效、可靠的代码。
4. 结构体和联合体(共用体):
在C语言中,结构体和联合体都是用于定义复杂数据类型的工具,以下是C语言结构体和联合体相关知识点:
1. 结构体的定义及访问 结构体是由多个不同类型的元素组成的集合。结构体定义时需要指定结构体名称和多个成员变量,每个成员变量可以是不同的数据类型。
例如:
struct student
{
char name[20];
int age;
float score;
};
结构体的元素可以使用`.`操作符进行访问。
例如:
struct student stu;
strcpy(stu.name, "Tom");
stu.age = 20;
stu.score = 80.5f;
2. 结构体数组 结构体数组是指多个结构体元素组成的数组。结构体数组的定义方式与一般数组相同,只不过每个元素是一个结构体。
例如:
struct student stu_arr[3] =
{
{"Tom", 20, 80.5f},
{"Jack", 22, 75.0f},
{"Lucy", 19, 90.0f}
};
3. 结构体嵌套 结构体中可以嵌套其他结构体。嵌套结构体的定义方式与一般变量定义方式相同,只不过嵌套结构体需要使用结构体名称来访问。
例如:
struct date { int year; int month; int day; };
struct student { char name[20]; int age; float score; struct date birth; };
4. 联合体的定义及使用 联合体是一种特殊的数据类型,它允许将不同类型的数据存储在同一段内存中。联合体的定义方式与结构体相似,但是联合体中的所有成员共享同一段内存。
例如:
union data { int i; float f; char str[10]; };
可以使用`.`操作符或者`->`操作符来访问联合体的成员。
例如:
union data d;
d.i = 10;
printf("%d\n", d.i); // 10
d.f = 3.14f;
printf("%f\n", d.f); // 3.14
strcpy(d.str, "hello");
printf("%s\n", d.str); // hello
总之,在C语言中,结构体和联合体都是非常重要的概念,程序员需要熟练掌握结构体和联合体的定义和访问方式,以及结构体数组、结构体嵌套和联合体的使用方法,才能写出高效、可靠的代码。
5. 内存管理:堆和栈内存的分配与释放、动态内存分配(malloc、realloc、calloc、free)
在C语言中,内存管理是一个非常重要的概念。在程序运行过程中,需要使用内存来存储变量、数组、结构体等数据类型,C语言提供了堆和栈两种内存管理方式以及动态内存分配函数来进行内存分配和释放。
1. 堆和栈内存的分配与释放 - 栈内存:由编译器自动管理,存储局部变量和函数调用的参数和返回值等。栈的使用遵循先进后出的原则,栈空间大小是有限的,当栈空间用尽时,程序崩溃。
void func(int n)
{
int arr[n]; // ...
}
堆内存:由程序员手动管理,存储全局变量、静态变量和需要动态分配内存的数据,堆空间大小相比栈更大,但使用不当会导致内存泄露等问题。
int *ptr = (int *)malloc(sizeof(int));
2. 动态内存分配函数 C语言提供了四个动态内存分配函数来进行堆内存分配和释放,这些函数包含在<stblib.h>头文件中。 malloc():用于在堆中分配指定大小的内存空间,返回指向这段内存空间的指针。
int *ptr = (int *)malloc(sizeof(int));
realloc():用于在堆中重新调整已分配内存的大小,可以扩大或缩小内存空间。
int *ptr = (int *)malloc(sizeof(int));
ptr = (int *)realloc(ptr, sizeof(int) * 2);
calloc():与malloc()类似,但是calloc()会对内存进行清零操作,将每个字节都初始化为0。
int *ptr = (int *)calloc(2, sizeof(int));
free():用于释放堆中之前分配的内存空间,避免内存泄露。
free(ptr);
除了动态内存分配函数外,还可以使用数组和结构体等方式在堆中分配内存。
总之,在C语言中,程序员需要熟练掌握堆和栈内存的分配和释放方法,以及动态内存分配函数的使用方法,才能编写高效、可靠的代码。同时,需要注意在进行内存管理时,要注意避免内存泄漏或者使用未初始化的内存,以提高程序的运行效率和可靠性。
6. 文件操作:
在C语言中,文件操作是一种非常重要的概念,它可以用于读取和写入文件,存储和读取数据等。以下是C语言文件操作相关的知识点:
1. 打开和关闭文件 在进行文件操作之前,需要先打开文件。C语言提供了fopen()函数来打开文件,其中需要指定文件名和打开方式(读取、写入、追加等)。同样,文件操作完成之后,需要使用fclose()函数来关闭文件。
例如: FILE *fp; fp = fopen("test.txt", "w"); // ... fclose(fp);
2. 读取和写入文件 C语言提供了多个函数来进行文件读取和写入操作,其中包括标准I/O函数和文件I/O函数。 标准I/O函数: 与控制台的输入输出类似,C语言提供了printf()和scanf()函数,可以用于标准的文件读取和写入操作。
例如:
FILE *fp; int a = 123;
char str[20] = "hello";
fp = fopen("test.txt", "w");
fprintf(fp, "%d %s\n", a, str);
fclose(fp);
文件I/O函数: 文件I/O函数需要指定文件指针和缓冲区大小等参数,用于进行底层的文件读取和写入操作。包括fread()、fwrite()等函数。
例如:
FILE *fp;
int a = 123;
fp = fopen("test.txt", "wb");
fwrite(&a, sizeof(int), 1, fp);
fclose(fp);
fp = fopen("test.txt", "rb");
fread(&a, sizeof(int), 1, fp);
fclose(fp);
总之,在C语言中,文件操作是一个非常重要的知识点,程序员需要熟练掌握打开和关闭文件、读取和写入文件的方法,并且要注意文件指针位置、文件大小、文件读取和写入长度等问题,以提高程序的运行效率和可靠性。同时,使用文件时也需要注意保护文件的安全性和完整性,避免因文件操作错误导致数据丢失等问题。
7. 预处理器:宏定义、条件编译、头文件包含等
目录
1. 基本语法:变量、数据类型、运算符、表达式、控制流结构(if-else、for、while、do-while等)、函数
5. 内存管理:堆和栈内存的分配与释放、动态内存分配(malloc、realloc、calloc、free)
8. 数据结构和算法:链表、树、图、排序算法(冒泡、选择、插入、快排、归并等)
在C语言中,预处理器是一个非常重要的概念,它是在源代码编译之前进行的一系列处理操作,包括宏定义、条件编译、头文件包含等。以下是C语言预处理器相关的知识点:
1. 宏定义 宏定义是一种预处理器指令,可以让程序员定义常量、函数、表达式等。宏定义使用`#define`关键字来表示,需要指定宏名称和宏替换内容。
例如:
#define PI 3.14
#define MAX(a, b) ((a) > (b) ? (a) : (b))
2. 条件编译 条件编译是一种预处理器技术,可以让程序员根据条件选择性地编译部分代码。条件编译使用`#if`、`#elif`、`#else`和`#endif`等关键字操作。
例如:
#define A
#ifdef A // ...
#else // ...
#endif
3. 头文件包含 头文件包含是一种预处理器指令,可以让程序员将其他文件中定义的函数、变量和宏定义包含到当前文件中。头文件包含使用`#include`关键字,并指定文件名或文件路径。
例如:
#include <stdio.h>
总之,在C语言中,预处理器是编写高质量代码的重要工具,程序员需要熟练掌握宏定义、条件编译、头文件包含等知识点,以提高代码效率和可靠性。同时,还需要注意预处理器技术的使用方法,避免使用不当导致程序错误或性能问题。
8. 数据结构和算法:链表、树、图、排序算法(冒泡、选择、插入、快排、归并等)
在C语言中,数据结构和算法是编写高效程序的重要组成部分,以下是C语言数据结构和算法相关的知识点:
1. 链表 链表是由多个节点(元素)组成的线性结构,每个节点包含数据和指向下一个节点的指针。链表的操作包括链表的遍历、插入和删除等。
2. 树 树是一种非常常见的数据结构,由根节点和多个子树构成,每个子树也是一棵树。树的操作包括树的遍历、搜索、插入和删除等。
3. 图 图是由节点和边组成的结构,每个节点包含数据和指向其他节点的边。图的操作包括节点的遍历、搜索、关键路径查找等。
4. 排序算法 排序算法是一种重要的算法,它可以对一组数据进行排序。常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序和归并排序等。
冒泡排序:通过不断比较相邻两个元素的大小,将较大(小)的元素逐渐向后(前)移动到正确的位置。
选择排序:通过在未排定部分中选出最小元素,放在已排定部分的末尾,从而逐渐将数据排序。 - 插入排序:通过将一个元素插入到已经排好序的部分中的正确位置,逐渐将数据排序。
快速排序:通过分区来排序,取一个数作为基数,将比基数大的数放置在基数右边,将比基数小的数放置在基数左边,递归执行此操作直到排序完成。
归并排序:通过将数据分成更小的有序序列,然后合并成一个大的有序序列,逐渐将数据排序。 总之,在C语言中,算法和数据结构是编写高质量代码的重要组成部分,程序员需要熟练掌握链表、树、图和排序算法等知识点,并且要掌握这些数据结构和算法的实现方法和使用技巧,以提高程序的性能和可维护性。
下面是C语言链表、树、图,以及排序算法的示例代码:
1. 链表示例代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} Node;
void add_node(Node **head, int val)
{
Node *new_node = (Node *)malloc(sizeof(Node));
new_node->data = val;
new_node->next = NULL;
if (*head == NULL)
{
*head = new_node;
}
else
{
Node *temp = *head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new_node;
}
}
void print_list(Node *head)
{
while (head != NULL)
{ printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
int main()
{
Node *head = NULL;
add_node(&head, 1);
add_node(&head, 2);
add_node(&head, 3);
print_list(head);
return 0;
}
2. 树示例代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{ int data;
struct node *left;
struct node *right;
} Node;
Node *create_node(int val)
{
Node *new_node = (Node *)malloc(sizeof(Node));
new_node->data = val;
new_node->left = NULL;
new_node->right = NULL;
return new_node;
}
void inorder_traversal(Node *root)
{
if (root != NULL)
{
inorder_traversal(root->left);
printf("%d ", root->data);
inorder_traversal(root->right);
}
}
int main()
{
Node *root = create_node(4);
root->left = create_node(2);
root->right = create_node(6);
root->left->left = create_node(1);
root->left->right = create_node(3);
root->right->left = create_node(5);
root->right->right = create_node(7);
inorder_traversal(root);
return 0;
}
3. 图示例代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct node {
int data;
struct node *next;
} Node;
void add_edge(Node **adj, int u, int v) {
Node *new_node = (Node *)malloc(sizeof(Node));
new_node->data = v;
new_node->next = adj[u];
adj[u] = new_node;
new_node = (Node *)malloc(sizeof(Node));
new_node->data = u;
new_node->next = adj[v];
adj[v] = new_node;
}
void dfs(Node **adj, int visited[], int u) {
Node *temp = adj[u];
visited[u] = 1;
printf("%d ", u);
while (temp != NULL) {
int v = temp->data;
if (visited[v] == 0) {
dfs(adj, visited, v);
}
temp = temp->next;
}
}
int main() {
int n = 5, m = 6;
Node *adj[MAX];
for (int i = 0; i < MAX; i++) {
adj[i] = NULL;
}
以上只是C语言的一些主要知识点,如果您想深入学习C语言,建议阅读相关的教材或参加相关的课程。