编辑
2023-10-16
后端
00
请注意,本文编写于 572 天前,最后修改于 572 天前,其中某些信息可能已经过时。

目录

基本概念
变量类型
自定义类型
结构体(Structures)
枚举(Enumerations)
为什么要有自定义类型?
数组
1. 数组的声明和初始化
2. 数组的访问
3. 数组的长度
4. 多维数组
5. 数组与函数
6. 字符串
7. 指针与数组
8. 动态内存分配
9. 数组和结构体
输入输出
printf 函数(输出)
分支语句
单一条件 if
多条件 if 和 else
嵌套的条件语句
循环
1. for 循环
2. while 循环
3. do-while 循环
循环控制语句
break 关键字
continue 关键字
函数
函数的定义
函数的声明
函数参数
函数返回值
主函数 main
函数的递归
指针
1. 指针的基本概念
2. 取地址运算符 &
3. 指针的间接引用(解引用)
4. 指针和数组
5. 指针和字符串
6. 指针和函数
7. 空指针
8. 动态内存分配
9. 指针和结构体
文件操作
1. fopen
2. fprintf
3. fclose
4. fgets
注意事项:
面向对象
一些简单的入门C语言程序
九九乘法表
乌托邦文字小游戏
贪吃蛇小游戏

下面我会给大家讲解一下c语言基础语法知识,看完这个大家就可以开始入门c语言了,并且写一些小程序。c语言是一门面向过程的语言,这里不纠结什么是面向过程,记住就好。每个c语言代码组成无非是下面几个部分:

基本概念

  1. 注释(Comments):用于解释代码,提高代码可读性。C 语言支持单行注释 // 和多行注释 /* */

    c
    // 这是单行注释 //计算机执行c代码的时候会跳过注释部分,当做没看见 /* 这是 多行 注释 */
  2. 预处理指令(Preprocessor Directives):以 # 开头,用于在编译前进行文本替换。例如,包含头文件、定义常量等。

    c
    #include <stdio.h> //头文件,头文件里面都是函数,也会有变量,可以在当前代码引用头文件中的函数在当前文件使用 #define PI 3.14 //以后所有出现PI的地方会替换成3.14
  3. 函数(Functions):C 程序主要是由函数构成的。每个程序都必须有一个 main 函数作为入口点,机器从main函数的第一行代码开始执行。

    c
    int main() { // 主函数体 return 0; }
  4. 变量(Variables):用于存储和表示数据。在使用之前,需要声明变量的类型。

    c
    int age = 25; // 声明方式, type valueName = value //type value ; // 这是声明变量,不作赋值 // 声明并初始化就是定义变量,除了特殊情况,建议声明的时候初始化 // 整数初始化为0,不初始化为随机值,会造成未知影响
  5. 语句和表达式(Statements and Expressions):C 语句以分号 ; 结尾,表达式是由运算符和操作数组成。

    c
    int sum = 2 + 3; // 表达式 printf("Sum is: %d", sum); // 语句
  6. 控制语句(Control Statements):用于控制程序的流程,包括条件语句(ifelse)、循环语句(forwhile)、跳转语句(breakcontinue)等。

    c
    if (condition) { // 条件为真时执行的代码 } else { // 条件为假时执行的代码 } for (int i = 0; i < 5; i++) { // 循环体 }

这些构建块组成了 C 语言程序的基本结构。通过合理组织这些元素,你可以编写出结构清晰、易于维护的 C 代码。接下来我会详细讲解一下这些部分

变量类型

C 语言有几种基础数据类型,它们分别是:

  1. 整型(Integer types):用于表示整数,包括 intshortlong 等,可以是有符号或无符号。

    c
    int myInt = 10;
  2. 浮点型(Floating-point types):用于表示带有小数的数值,包括 floatdouble

    c
    float myFloat = 3.14;
  3. 字符型(Character type):用于表示单个字符,使用 char

    c
    char myChar = 'A';
  4. 短整型、长整型和长长整型:这些是对整型的扩展,用于表示更大范围的整数。

    c
    short myShort = 5; long myLong = 1000000L;
  5. 无类型(Void type):用于表示没有值的类型,通常在函数返回类型或指针中使用。

    c
    //后面讲解函数 void myFunction() { // 函数没有返回值 }

这些基础数据类型为你提供了在 C 语言中存储和操作数据的基本工具。

自定义类型

C 语言允许程序员创建自定义的数据类型,这样可以更好地组织和管理数据。自定义类型的主要目的是为了提高代码的可读性、可维护性,并使代码更具有结构化。初学者通常会使用结构体和枚举这两种主要的自定义类型。

结构体(Structures)

结构体是一种用户自定义的数据类型,它允许你将不同类型的数据组合在一起,形成一个更大的数据结构。结构体的每个成员可以是不同的数据类型。

c
// 定义结构体 struct Person { char name[50]; int age; float height; }; // 声明结构体变量并初始化 struct Person person1 = {"John", 25, 1.75}; // 访问结构体成员 printf("Name: %s, Age: %d, Height: %.2f", person1.name, person1.age, person1.height);

使用结构体能够更清晰地表示实体对象,比如在上述例子中,Person 结构体表示一个人,具有姓名、年龄和身高等属性。

枚举(Enumerations)

枚举是一种定义命名常量的方式,它为一组相关的整数赋予了有意义的名字。这样可以提高代码的可读性,使得代码更易于理解。

c
// 定义枚举 // 什么时候使用枚举?当我们有一个变量是固定的几个字段,比如星期几, // 还有,什么课,或者,什么身份,学生老师? enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; // 使用枚举变量 enum Weekday today = Wednesday;

在这个例子中,Weekday 枚举表示一周的天数,通过枚举值,你可以更容易地理解代码的含义。

为什么要有自定义类型?

  1. 组织复杂数据:结构体允许将相关数据组合在一起,形成一个逻辑单元,使代码更有条理。

  2. 提高可读性:使用自定义类型能够让代码更接近自然语言,增加代码的可读性和理解性。

  3. 模块化开发:通过自定义类型,你可以更容易地创建模块化的代码,提高代码的可维护性,降低出错概率。

  4. 命名常量:枚举允许你为整数赋予有意义的名字,提高代码的可读性和可维护性。

自定义类型有助于将复杂的数据和概念抽象化,使得代码更易于理解和维护。初学者在学习 C 语言时,应该逐渐掌握如何使用结构体和枚举,提高代码复用性和整体结构的美观,逻辑清晰,写的代码也更容易维护!

数组

数组是一种在 C 语言中用于存储相同类型数据元素的数据结构。它提供了一种有序的、连续的内存分配。上面是书本上的定义,作为初学者,你只要知道,属于就是一组同样的元素,一组int/char...等等:

1. 数组的声明和初始化

数组的声明告诉编译器变量的类型和名称,数组的初始化为数组分配内存并为其元素赋值。

c
// 声明一个整型数组,包含5个元素,不初始化 int numbers[5]; // 初始化数组 int numbers[] = {1, 2, 3, 4, 5}; //不指定长度,编译器根据后面元素个数推导,相当于 int numbers[5];

2. 数组的访问

通过数组的索引,你可以访问数组中特定位置的元素。注意,数组索引从 0 开始。

c
int firstElement = numbers[0]; // 访问数组的第一个元素 int thirdElement = numbers[2]; // 访问数组的第三个元素

3. 数组的长度

在声明数组时,如果初始化了数组元素,可以省略数组的长度,编译器会根据初始化列表自动确定数组长度。

c
int numbers[] = {1, 2, 3, 4, 5}; // 数组长度为5

如果你想获取数组的长度,可以使用 sizeof 运算符。

c
// sizeof计算的是元素大小, // 我有一个int nums[5],一个int大小4,5个就是20,20/4=5,就得出数组长度 int length = sizeof(numbers) / sizeof(numbers[0]);

4. 多维数组

C 语言支持多维数组,例如二维数组。

c
int matrix[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

访问二维数组的元素:

c
int element = matrix[1][2]; // 获取第二行第三列的元素

这么理解多维数组,二维数组就是每个元素都是一维数组,三维数组就是每个元素都是二维数组,以此类推。

5. 数组与函数

这部分可以先看完函数回来继续思考

在函数中传递数组时,通常需要传递数组的地址,以便在函数内对数组进行修改。

c
void modifyArray(int arr[], int length) { for (int i = 0; i < length; i++) { arr[i] *= 2; } } int main() { int numbers[] = {1, 2, 3, 4, 5}; int length = sizeof(numbers) / sizeof(numbers[0]); modifyArray(numbers, length); // 现在 numbers 变成了 {2, 4, 6, 8, 10} return 0; }

6. 字符串

字符串在 C 语言中是字符数组,通常以空字符 \0 结尾。

c
char greeting[] = "Hello";

字符串的访问和操作:

c
char firstChar = greeting[0]; printf("Length of string: %lu\n", strlen(greeting));

7. 指针与数组

数组名本身就是指向数组第一个元素的指针。

c
int numbers[] = {1, 2, 3, 4, 5}; int *ptr = numbers; // 数组名是指向第一个元素的指针

8. 动态内存分配

可以使用 malloc 函数动态分配数组的内存。

c
int *dynamicArray = (int *)malloc(5 * sizeof(int));

9. 数组和结构体

数组可以包含结构体类型的元素。

c
struct Point { int x; int y; }; struct Point points[3] = {{1, 2}, {3, 4}, {5, 6}};

这些是关于 C 语言数组的基本概念。数组是一种强大的数据结构,所有编程语言都直接或间接提供数组相类似的功能。

输入输出

在 C 语言中,输入输出主要通过标准库函数 printfscanf 进行。这两个函数使用占位符来指定输出格式和输入格式。占位符表示把当前位置占住,后面有一个变量在这个位置。以下是一些常见的占位符及其用途:

printf 函数(输出)

  • %d: 用于输出整数。

    c
    int number = 10; printf("The number is: %d", number);
  • %f: 用于输出浮点数。

    c
    %.2f表示保留两位小数,类似%.3f %.4f float pi = 3.14; printf("The value of pi is: %f", pi);
  • %c: 用于输出字符。

    c
    char myChar = 'A'; printf("The character is: %c", myChar);
  • %s: 用于输出字符串。

    c
    char myString[] = "Hello"; printf("The string is: %s", myString);

scanf 函数(输入)

  • %d: 用于输入整数。

    c
    int number; scanf("%d", &number);
  • %f: 用于输入浮点数。

    c
    float pi; scanf("%f", &pi);
  • %c: 用于输入字符。

    c
    char myChar; scanf(" %c", &myChar); // 注意空格,防止吸收前一个输入的换行符
  • %s: 用于输入字符串。

    c
    char myString[50]; scanf("%s", myString);

这些占位符允许你以指定的格式输入和输出不同类型的数据。注意在 scanf 函数中,变量前需要加 & 符号,表示取地址,将输入的值存储到相应的变量中。

以上是一些基本的输入输出占位符,对于初学者来说,逐步熟悉和使用它们会帮助你更好地处理输入输出操作。也是我们找出程序错误的利器!

分支语句

当你需要根据某个条件来执行不同的代码块时,C 语言提供了条件分支的结构,主要有 ifelse ifelse。条件分支就是,对应条件下执行对应的代码

单一条件 if

c
#include <stdio.h> int main() { int number = 10; if (number > 0) { printf("The number is positive.\n"); } return 0; }

多条件 ifelse

c
#include <stdio.h> int main() { int number = 0; if (number > 0) { printf("The number is positive.\n"); } else if (number < 0) { printf("The number is negative.\n"); } else { printf("The number is zero.\n"); } return 0; }

嵌套的条件语句

c
#include <stdio.h> int main() { int x = 10, y = 20; // 0为真,其他的都是假/NULL值也是假,NULL是指针的空值 // NULL就是,#define NULL 0 if (x > y) { printf("x is greater than y.\n"); } else if (x < y) { printf("x is less than y.\n"); } else { printf("x is equal to y.\n"); } return 0; }

在这些示例中,条件语句根据不同的情况执行相应的代码块。 if 语句用于检查一个条件是否为真,else if 用于检查多个条件,而 else 用于处理所有其他情况。

请注意,条件表达式后面的代码块用花括号 {} 括起来。这是为了确保条件语句只应用于一个语句,但在某些情况下,可以省略花括号,特别是如果只有一条语句。

条件分支结构使程序能够根据不同情况采取不同的行动,是控制程序流程的重要工具。

if地狱,就是非常多的if else 在同一个代码块,这样的代码难以维护,丑陋。

当你有多个条件需要比较时,C 语言提供了 switch 语句,它允许你根据表达式的值跳转到匹配的分支。以下是一个简单的 switch 语句的示例:

c
#include <stdio.h> int main() { int day = 3; // case后面常常是函数的执行,这样我们就把所有的逻辑抽象出函数, //并通过switch控制跳转,这样代码清晰优雅,大大增高了代码的可维护性。 switch (day) { case 1: printf("Monday\n"); break; case 2: printf("Tuesday\n"); break; case 3: printf("Wednesday\n"); break; case 4: printf("Thursday\n"); break; case 5: printf("Friday\n"); break; case 6: printf("Saturday\n"); break; case 7: printf("Sunday\n"); break; default: printf("Invalid day\n"); } return 0; }

在这个例子中,switch 语句根据变量 day 的值跳转到相应的 case 分支。如果没有匹配的 case,可以使用 default 分支处理默认情况。

每个 case 后面都需要用 break 语句来终止 switch 语句,以避免进入下一个 case。如果省略 break,程序会继续执行后面的 case,这可能导致不符合预期的结果。

switch 语句对于处理多个值相同的情况是非常有用的,而且它在执行时可以比一系列嵌套的 if-else 语句更有效率。

记住!一定要记得写break!

循环

C 语言提供了几种循环结构,用于多次执行相同的代码块。以下是 C 语言中的几种常见循环:

1. for 循环

for 循环是一种最常用的循环,它允许你在指定的条件下重复执行一段代码。

c
#include <stdio.h> int main() { for (int i = 0; i < 5; i++) { printf("Iteration %d\n", i); } return 0; }

这个例子中,for 循环初始化了一个变量 i,在每次迭代中检查条件 i < 5,执行循环体,然后更新 i 的值。

2. while 循环

while 循环在每次迭代前检查条件是否为真,如果为真,则执行循环体。

c
#include <stdio.h> int main() { int i = 0; while (i < 5) { printf("Iteration %d\n", i); i++; } return 0; }

在这个例子中,while 循环不同于 for 循环,因为它把初始化和更新都放在循环外部。

3. do-while 循环

do-while 循环是一种至少执行一次循环体的循环,因为它先执行一次循环体,然后在检查条件是否为真。

c
#include <stdio.h> int main() { int i = 0; do { printf("Iteration %d\n", i); i++; } while (i < 5); return 0; }

do-while 循环适用于无论条件如何,都至少希望执行循环体一次的情况。

循环控制语句

在循环中,有一些控制语句可以改变循环的执行流程,如 break(跳出循环)、continue(跳过本次循环,进入下一次迭代)等。

break 关键字

break 关键字用于立即终止循环,跳出循环体。在下面的例子中,循环会一直执行直到 i 的值达到 3。

c
#include <stdio.h> int main() { for (int i = 0; i < 5; i++) { if (i == 3) { printf("Break out of the loop when i is 3.\n"); break; } printf("Iteration %d\n", i); } return 0; }

continue 关键字

continue 关键字用于跳过当前循环的剩余部分,直接进入下一次迭代。在下面的例子中,当 i 的值为 2 时,会跳过 printf 语句,直接进入下一次迭代。

c
#include <stdio.h> int main() { for (int i = 0; i < 5; i++) { if (i == 2) { printf("Skip printing when i is 2.\n"); continue; } printf("Iteration %d\n", i); } return 0; }

这两个关键字通常用于处理特殊情况,例如在搜索算法中找到目标值时,可以使用 break 跳出循环,而在某些条件下,可以使用 continue 跳过某次迭代。

函数

终于到了函数的讲解了,函数是一种可重用的代码块,用于执行特定的任务。函数提高了代码的模块化,使得程序更易于理解和维护。

函数的定义

在 C 语言中,函数的定义包括函数的返回类型、函数名、参数列表和函数体。下面是一个简单的函数定义示例:

c
#include <stdio.h> // 函数的定义 int add(int a, int b) { int sum = a + b; return sum; } int main() { // 函数的调用 int result = add(3, 4); printf("Sum: %d\n", result); return 0; }

这个例子中,add 函数接受两个整数参数 ab,并返回它们的和。在 main 函数中,我们调用了 add 函数,并将结果打印出来。

函数的声明

在函数的定义之前,可以使用函数声明告诉编译器函数的存在。函数声明包括函数的返回类型、函数名和参数列表。

c
#include <stdio.h> // 函数声明 int add(int a, int b); int main() { int result = add(3, 4); printf("Sum: %d\n", result); return 0; } // 函数的定义 int add(int a, int b) { int sum = a + b; return sum; }

函数声明的目的是在使用函数之前告诉编译器该函数的原型,以便正确编译调用该函数的代码。

函数参数

函数的参数是在调用函数时传递给函数的值。参数允许函数接受外部数据,以便在函数内部执行操作。函数可以有零个或多个参数。

c
#include <stdio.h> // 函数定义 void greet(char name[]) { printf("Hello, %s!\n", name); } int main() { // 函数调用 greet("Alice"); greet("Bob"); return 0; }

在这个例子中,greet 函数接受一个字符串参数 name,并向其打印问候语。main 函数调用 greet 函数两次,每次传递不同的名字。

函数返回值

函数可以返回一个值给调用者。返回值的类型在函数定义中指定,并且可以是任何合法的 C 数据类型。

c
#include <stdio.h> // 函数定义 int square(int x) { return x * x; } int main() { // 函数调用 int result = square(5); printf("Square: %d\n", result); return 0; }

在这个例子中,square 函数接受一个整数参数 x,返回 x 的平方。main 函数调用 square 函数,并将结果打印出来。

主函数 main

在 C 语言程序中,main 函数是程序的入口点。程序从 main 函数开始执行,当 main 函数执行完毕时,程序结束。

c
#include <stdio.h> // 主函数 int main() { // 在这里编写程序代码 return 0; // 表示程序成功结束 }

函数的递归

C 语言支持函数的递归,即函数调用自身。递归是一种强大的编程技巧,用于解决问题,如计算阶乘、斐波那契数列等。

c
#include <stdio.h> // 递归函数计算阶乘 int factorial(int n) { if (n == 0 || n == 1) { return 1; } else { return n * factorial(n - 1); } } int main() { int result = factorial(5); printf("Factorial: %d\n", result); return 0; }

在这个例子中,factorial 函数使用递归计算阶乘。递归函数必须包含终止条件,以防止无限递归。

我们应该把可重用的逻辑抽象成函数,函数不应过长,需要分解成小函数,这将大大提高代码的可维护性。

指针

指针可以说是老生常谈,人人都说c语言精髓部分就是指针,理解 C 语言中的指针是初学者学习过程中的一项关键任务。指针是一个存储变量地址的变量,它允许直接访问内存位置。这里我觉得初学者不应该着急了解什么是内存什么是地址,只需要了解做什么用就行,以后这些会随着你对编程热爱逐步揭秘!

1. 指针的基本概念

指针是一个变量,它存储另一个变量的地址。通过指针,你可以直接访问这个地址上存储的数据。指针声明使用 * 符号,如下:

c
int *ptr; // 声明一个整型指针

2. 取地址运算符 &

取地址运算符 & 用于获取变量的地址。例如:

c
int num = 42; int *ptr = &num; // 将变量 num 的地址赋给指针 ptr

3. 指针的间接引用(解引用)

通过指针,你可以访问存储在特定地址上的值。这通过指针的解引用操作符 * 实现。

c
int value = *ptr; // 获取指针 ptr 指向地址上的值

4. 指针和数组

指针和数组之间有着密切的关系。数组名本身就是一个指针,指向数组的第一个元素的地址。

c
int arr[5] = {1, 2, 3, 4, 5}; int *arrPtr = arr; // 数组名是指向第一个元素的指针

5. 指针和字符串

字符串在 C 语言中是字符数组,可以通过指针操作字符串。

c
char str[] = "Hello"; char *strPtr = str; // 字符数组名是指向第一个字符的指针

6. 指针和函数

指针还可以用于传递函数的地址,实现函数指针。

c
int add(int a, int b) { return a + b; } int (*funcPtr)(int, int) = add; // 函数指针指向 add 函数 int result = funcPtr(3, 4); // 通过函数指针调用 add 函数

7. 空指针

空指针是指不指向任何有效地址的指针,通常用 NULL 表示。

c
int *ptr = NULL; // 空指针

8. 动态内存分配

malloc 函数用于在运行时分配内存,并返回指向分配内存的指针。

c
int *arr = (int *)malloc(5 * sizeof(int)); // 分配包含 5 个整数的动态数组

9. 指针和结构体

指针可以用于操作结构体类型的数据。

c
struct Point { int x; int y; }; struct Point p1 = {10, 20}; struct Point *ptr = &p1; // 结构体指针

听了这么多,是不是有点概念了,抽象一下,指针就是一个僚机,你可以请求他去盯着你的crash,你不好意思,一直通过僚机来了解你的crash生活习惯,喜欢的人,爱好!当然,你以后接触更多指针的知识,功能,会发现,并不是这么简单,指针也是计算机基础概念,他会伴随着你学习其他编程语言,你对指针的理解也会越来越深入!

文件操作

文件操作是 C 语言中一项基本的任务,让我们从简单的文件读写开始。以下是一个简单的例子,演示如何打开文件、写入内容、关闭文件,然后再读取文件内容。

c
#include <stdio.h> int main() { // 文件写入 FILE *fileWrite = fopen("example.txt", "w"); // 打开文件(写入模式) if (fileWrite == NULL) { perror("Error opening file for writing"); return 1; // 退出程序 } fprintf(fileWrite, "Hello, this is a sample text.\n"); fprintf(fileWrite, "This is another line in the file.\n"); fclose(fileWrite); // 关闭文件 // 文件读取 FILE *fileRead = fopen("example.txt", "r"); // 打开文件(读取模式) if (fileRead == NULL) { perror("Error opening file for reading"); return 1; // 退出程序 } // 逐行读取文件内容 char line[100]; while (fgets(line, sizeof(line), fileRead) != NULL) { printf("%s", line); } fclose(fileRead); // 关闭文件 return 0; // 程序执行成功 }

这个例子演示了如何使用 fopen 打开文件,使用 fprintf 写入内容,使用 fclose 关闭文件。然后,使用 fopen 再次打开文件,使用 fgets 逐行读取文件内容,最后使用 fclose 关闭文件。

让我们逐个讲解这几个在 C 语言文件操作中使用的函数:

1. fopen

函数原型:

c
FILE *fopen(const char *filename, const char *mode);

功能:

  • 用于打开一个文件,并返回一个指向 FILE 类型的指针。

参数:

  • filename:要打开的文件的路径和名称。
  • mode:打开文件的模式,例如 "r"(读取)、"w"(写入)等。

返回值:

  • 如果成功,返回一个指向 FILE 结构的指针;如果失败,返回 NULL

2. fprintf

函数原型:

c
int fprintf(FILE *stream, const char *format, ...);

功能:

  • 将格式化的数据写入文件。

参数:

  • stream:指向 FILE 结构的指针,表示要写入的文件。
  • format:字符串,包含要写入的文本和格式说明符,类似于 printf

返回值:

  • 返回成功写入的字符数,如果出错,则返回负数。

3. fclose

函数原型:

c
int fclose(FILE *stream);

功能:

  • 用于关闭文件。

参数:

  • stream:指向 FILE 结构的指针,表示要关闭的文件。

返回值:

  • 如果成功,返回 0;如果出错,返回 EOF

4. fgets

函数原型:

c
char *fgets(char *str, int n, FILE *stream);

功能:

  • 从文件中读取一行字符串。

参数:

  • str:用于存储读取的字符串的字符数组。
  • n:要读取的字符数的最大值。
  • stream:指向 FILE 结构的指针,表示要读取的文件。

返回值:

  • 如果成功,返回 str;如果出错或到达文件末尾,返回 NULL

注意事项:

  • 这里只是简单介绍了这些函数的基本用法,实际应用可能需要更多的错误处理和特殊情况的考虑。
  • 文件的打开和关闭是一对操作,不要忘记关闭已经打开的文件,以避免资源泄漏。

在实际应用中,你可能需要更多的错误处理和更复杂的文件操作,例如二进制文件读写、定位文件指针、文件截断等。但这个简单的例子足够帮助你理解 C 语言中的基本文件操作。更多有趣的文件操作手法等待你去探索!

面向对象

什么是面向对象?面向对象是一种高级抽象手法,我们把所有的服务对象抽象出属性方法,通过属性和方法操作对象,比如学生,具有学号姓名等属性,他们也可以做一些操作,比如背书,或者吃饭,这些是方法。

在 C 语言中,并没有内建的面向对象(Object-Oriented Programming, OOP)支持,如类、继承和多态等。然而,你可以使用结构体和函数指针等技术来实现一些面向对象的概念。

c
#include <stdio.h> // 定义一个结构体表示“对象” typedef struct { int x; int y; void (*display)(void *); // 函数指针,用于显示对象信息 } Point; // 定义一个函数,用于显示 Point 对象信息 void displayPoint(void *obj) { Point *point = (Point *)obj; printf("Point at (%d, %d)\n", point->x, point->y); } // 创建 Point 对象的构造函数 Point createPoint(int x, int y) { Point point = {x, y, displayPoint}; return point; } int main() { // 创建 Point 对象 Point p1 = createPoint(3, 4); // 调用对象的 display 方法 p1.display(&p1); return 0; }

我们使用结构体 Point 来表示一个“点”对象,通过函数指针 display 实现了一个显示对象信息的方法。createPoint 函数充当构造函数,用于创建并初始化 Point 对象。

这种方法是模拟了一些面向对象的思想,但并不具备真正的封装、继承和多态等特性。对于更复杂的面向对象编程,一般会选择使用支持 OOP 的编程语言,如 C++ 或 Java。在这些语言中,你可以更自然地定义类、实现继承和多态等概念。

在演示一个例子

我们将创建一个 Animal 结构体表示动物:

c
#include <stdio.h> // 定义 Animal 结构体 typedef struct { char name[50]; int age; void (*makeSound)(void *); // 函数指针,用于模拟动物发声 } Animal; // 创建动物的构造函数 Animal createAnimal(const char *name, int age, void (*makeSound)(void *)) { Animal animal; snprintf(animal.name, sizeof(animal.name), "%s", name); animal.age = age; animal.makeSound = makeSound; return animal; } // 函数指针,用于模拟狗的叫声 void dogSound(void *obj) { Animal *dog = (Animal *)obj; printf("%s says Woof!\n", dog->name); } // 函数指针,用于模拟猫的叫声 void catSound(void *obj) { Animal *cat = (Animal *)obj; printf("%s says Meow!\n", cat->name); } int main() { // 创建狗和猫对象 Animal dog = createAnimal("Buddy", 3, dogSound); Animal cat = createAnimal("Whiskers", 2, catSound); // 调用对象的 makeSound 方法 dog.makeSound(&dog); cat.makeSound(&cat); return 0; }

我们定义了一个 Animal 结构体,其中包含动物的名称、年龄和一个函数指针,用于模拟动物发声。我们创建了两个动物对象,狗和猫,每个都有自己的名字、年龄和发声方法。通过调用对象的 makeSound 方法,我们可以模拟它们发声。

这只是一种简单的模拟,而不是真正的面向对象编程。在真正的面向对象语言中,你可以更自然地定义类、使用封装、继承和多态等特性。感兴趣的同学可以继续学习cpp,还有java等面向对象语言。

一些简单的入门C语言程序

九九乘法表

c
#include <stdio.h> int main() { int i, j; for (i = 1; i <= 9; i++) { for (j = 1; j <= i; j++) { printf("%d * %d = %d\t", j, i, i * j); } printf("\n"); } return 0; }

image.png

乌托邦文字小游戏

c
#include <stdio.h> #include <stdlib.h> #include <string.h> void displayIntro() { printf("欢迎来到乌托邦!\n"); printf("乌托邦是一个理想的社会,每个人都快乐、和谐、平等。\n"); printf("你将扮演一位新来的居民,决定你在乌托邦中的行动和发展。\n"); printf("现在,请告诉我你的名字:\n"); } void playGame(char* playerName) { int happiness = 100; int harmony = 100; int equality = 100; int reputation = 0; printf("\n欢迎,%s!你的乌托邦之旅开始了。\n", playerName); while (1) { printf("\n乌托邦指标:\n"); printf("快乐度:%d\n", happiness); printf("和谐度:%d\n", harmony); printf("平等度:%d\n", equality); printf("声望:%d\n", reputation); printf("\n请选择你的下一步行动:\n"); printf("1. 参加社区活动\n"); printf("2. 参与公益事业\n"); printf("3. 参与政府决策\n"); printf("4. 探索禁忌之地\n"); printf("5. 退出游戏\n"); int choice; scanf("%d", &choice); switch (choice) { case 1: happiness += 10; harmony += 5; equality -= 5; reputation += 5; printf("\n你参加了社区活动,获得了快乐和声望。\n"); break; case 2: happiness += 5; harmony += 10; equality -= 5; reputation += 5; printf("\n你参与了公益事业,获得了和谐和声望。\n"); break; case 3: happiness += 5; harmony += 5; equality += 10; reputation += 10; printf("\n你参与了政府决策,获得了平等和声望。\n"); break; case 4: happiness -= 20; harmony -= 20; equality -= 20; reputation -= 10; printf("\n你决定探索禁忌之地...\n"); printf("你发现了乌托邦底下隐藏的黑暗面。\n"); printf("乌托邦的真相让你感到震惊和绝望。\n"); printf("你的心灵受到了巨大的冲击,指标急剧下降。\n"); return; case 5: printf("\n游戏结束。谢谢你的参与!\n"); return; default: printf("\n无效的选择,请重新选择。\n"); continue; } // 更新指标范围 if (happiness > 100) happiness = 100; if (happiness < 0) happiness = 0; if (harmony > 100) harmony = 100; if (harmony < 0) harmony = 0; if (equality > 100) equality = 100; if (equality < 0) equality = 0; if (reputation < 0) reputation = 0; } } int main() { char playerName[100]; displayIntro(); scanf("%s", playerName); playGame(playerName); return 0; }

贪吃蛇小游戏

c
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <stdbool.h> #include <windows.h> #define WIDTH 20 #define HEIGHT 20 int score = 0; int tailLength = 0; int tailX[WIDTH * HEIGHT]; int tailY[WIDTH * HEIGHT]; int fruitX, fruitY; int headX, headY; int dirX, dirY; bool gameOver = false; void Setup() { score = 0; tailLength = 0; headX = WIDTH / 2; headY = HEIGHT / 2; dirX = 0; dirY = 0; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; } void Draw() { system("cls"); for (int i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { if (x == 0) printf("#"); if (x == headX && y == headY) printf("O"); else if (x == fruitX && y == fruitY) printf("F"); else { bool isTail = false; for (int i = 0; i < tailLength; i++) { if (x == tailX[i] && y == tailY[i]) { printf("o"); isTail = true; break; } } if (!isTail) printf(" "); } if (x == WIDTH - 1) printf("#"); } printf("\n"); } for (int i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); printf("Score: %d\n", score); } void Input() { if (_kbhit()) { char input = _getch(); switch (input) { case 'a': dirX = -1; dirY = 0; break; case 'd': dirX = 1; dirY = 0; break; case 'w': dirX = 0; dirY = -1; break; case 's': dirX = 0; dirY = 1; break; case 'x': gameOver = true; break; } } } void Logic() { int prevX = tailX[0]; int prevY = tailY[0]; int tempX, tempY; tailX[0] = headX; tailY[0] = headY; for (int i = 1; i < tailLength; i++) { tempX = tailX[i]; tempY = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = tempX; prevY = tempY; } headX += dirX; headY += dirY; if (headX < 0 || headX >= WIDTH || headY < 0 || headY >= HEIGHT) gameOver = true; for (int i = 0; i < tailLength; i++) { if (tailX[i] == headX && tailY[i] == headY) gameOver = true; } if (headX == fruitX && headY == fruitY) { score += 10; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; tailLength++; } } int main() { Setup(); while (!gameOver) { Draw(); Input(); Logic(); Sleep(10); // 控制游戏速度,可根据需要进行调整 } printf("Game Over!\n"); printf("Your Score: %d\n", score); return 0; }

希望这几个程序能让你c语言功底更进一步!!!创作不易,欢迎点赞收藏!点个关注吧~

本文作者:yowayimono

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!