下面我会给大家讲解一下c语言基础语法知识,看完这个大家就可以开始入门c语言了,并且写一些小程序。c语言是一门面向过程的语言,这里不纠结什么是面向过程,记住就好。每个c语言代码组成无非是下面几个部分:
注释(Comments):用于解释代码,提高代码可读性。C 语言支持单行注释 //
和多行注释 /* */
。
c// 这是单行注释
//计算机执行c代码的时候会跳过注释部分,当做没看见
/*
这是
多行
注释
*/
预处理指令(Preprocessor Directives):以 #
开头,用于在编译前进行文本替换。例如,包含头文件、定义常量等。
c#include <stdio.h> //头文件,头文件里面都是函数,也会有变量,可以在当前代码引用头文件中的函数在当前文件使用
#define PI 3.14 //以后所有出现PI的地方会替换成3.14
函数(Functions):C 程序主要是由函数构成的。每个程序都必须有一个 main
函数作为入口点,机器从main函数的第一行代码开始执行。
cint main() {
// 主函数体
return 0;
}
变量(Variables):用于存储和表示数据。在使用之前,需要声明变量的类型。
cint age = 25; // 声明方式, type valueName = value
//type value ; // 这是声明变量,不作赋值
// 声明并初始化就是定义变量,除了特殊情况,建议声明的时候初始化
// 整数初始化为0,不初始化为随机值,会造成未知影响
语句和表达式(Statements and Expressions):C 语句以分号 ;
结尾,表达式是由运算符和操作数组成。
cint sum = 2 + 3; // 表达式
printf("Sum is: %d", sum); // 语句
控制语句(Control Statements):用于控制程序的流程,包括条件语句(if
、else
)、循环语句(for
、while
)、跳转语句(break
、continue
)等。
cif (condition) {
// 条件为真时执行的代码
} else {
// 条件为假时执行的代码
}
for (int i = 0; i < 5; i++) {
// 循环体
}
这些构建块组成了 C 语言程序的基本结构。通过合理组织这些元素,你可以编写出结构清晰、易于维护的 C 代码。接下来我会详细讲解一下这些部分
C 语言有几种基础数据类型,它们分别是:
整型(Integer types):用于表示整数,包括 int
、short
、long
等,可以是有符号或无符号。
cint myInt = 10;
浮点型(Floating-point types):用于表示带有小数的数值,包括 float
和 double
。
cfloat myFloat = 3.14;
字符型(Character type):用于表示单个字符,使用 char
。
cchar myChar = 'A';
短整型、长整型和长长整型:这些是对整型的扩展,用于表示更大范围的整数。
cshort myShort = 5;
long myLong = 1000000L;
无类型(Void type):用于表示没有值的类型,通常在函数返回类型或指针中使用。
c//后面讲解函数
void myFunction() {
// 函数没有返回值
}
这些基础数据类型为你提供了在 C 语言中存储和操作数据的基本工具。
C 语言允许程序员创建自定义的数据类型,这样可以更好地组织和管理数据。自定义类型的主要目的是为了提高代码的可读性、可维护性,并使代码更具有结构化。初学者通常会使用结构体和枚举这两种主要的自定义类型。
结构体是一种用户自定义的数据类型,它允许你将不同类型的数据组合在一起,形成一个更大的数据结构。结构体的每个成员可以是不同的数据类型。
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
结构体表示一个人,具有姓名、年龄和身高等属性。
枚举是一种定义命名常量的方式,它为一组相关的整数赋予了有意义的名字。这样可以提高代码的可读性,使得代码更易于理解。
c// 定义枚举
// 什么时候使用枚举?当我们有一个变量是固定的几个字段,比如星期几,
// 还有,什么课,或者,什么身份,学生老师?
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
// 使用枚举变量
enum Weekday today = Wednesday;
在这个例子中,Weekday
枚举表示一周的天数,通过枚举值,你可以更容易地理解代码的含义。
组织复杂数据:结构体允许将相关数据组合在一起,形成一个逻辑单元,使代码更有条理。
提高可读性:使用自定义类型能够让代码更接近自然语言,增加代码的可读性和理解性。
模块化开发:通过自定义类型,你可以更容易地创建模块化的代码,提高代码的可维护性,降低出错概率。
命名常量:枚举允许你为整数赋予有意义的名字,提高代码的可读性和可维护性。
自定义类型有助于将复杂的数据和概念抽象化,使得代码更易于理解和维护。初学者在学习 C 语言时,应该逐渐掌握如何使用结构体和枚举,提高代码复用性和整体结构的美观,逻辑清晰,写的代码也更容易维护!
数组是一种在 C 语言中用于存储相同类型数据元素的数据结构。它提供了一种有序的、连续的内存分配。上面是书本上的定义,作为初学者,你只要知道,属于就是一组同样的元素,一组int/char...等等:
数组的声明告诉编译器变量的类型和名称,数组的初始化为数组分配内存并为其元素赋值。
c// 声明一个整型数组,包含5个元素,不初始化
int numbers[5];
// 初始化数组
int numbers[] = {1, 2, 3, 4, 5}; //不指定长度,编译器根据后面元素个数推导,相当于 int numbers[5];
通过数组的索引,你可以访问数组中特定位置的元素。注意,数组索引从 0 开始。
cint firstElement = numbers[0]; // 访问数组的第一个元素
int thirdElement = numbers[2]; // 访问数组的第三个元素
在声明数组时,如果初始化了数组元素,可以省略数组的长度,编译器会根据初始化列表自动确定数组长度。
cint 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]);
C 语言支持多维数组,例如二维数组。
cint matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
访问二维数组的元素:
cint element = matrix[1][2]; // 获取第二行第三列的元素
这么理解多维数组,二维数组就是每个元素都是一维数组,三维数组就是每个元素都是二维数组,以此类推。
这部分可以先看完函数回来继续思考
在函数中传递数组时,通常需要传递数组的地址,以便在函数内对数组进行修改。
cvoid 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;
}
字符串在 C 语言中是字符数组,通常以空字符 \0
结尾。
cchar greeting[] = "Hello";
字符串的访问和操作:
cchar firstChar = greeting[0];
printf("Length of string: %lu\n", strlen(greeting));
数组名本身就是指向数组第一个元素的指针。
cint numbers[] = {1, 2, 3, 4, 5};
int *ptr = numbers; // 数组名是指向第一个元素的指针
可以使用 malloc
函数动态分配数组的内存。
cint *dynamicArray = (int *)malloc(5 * sizeof(int));
数组可以包含结构体类型的元素。
cstruct Point {
int x;
int y;
};
struct Point points[3] = {{1, 2}, {3, 4}, {5, 6}};
这些是关于 C 语言数组的基本概念。数组是一种强大的数据结构,所有编程语言都直接或间接提供数组相类似的功能。
在 C 语言中,输入输出主要通过标准库函数 printf
和 scanf
进行。这两个函数使用占位符来指定输出格式和输入格式。占位符表示把当前位置占住,后面有一个变量在这个位置。以下是一些常见的占位符及其用途:
printf
函数(输出)%d
: 用于输出整数。
cint 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
: 用于输出字符。
cchar myChar = 'A';
printf("The character is: %c", myChar);
%s
: 用于输出字符串。
cchar myString[] = "Hello";
printf("The string is: %s", myString);
scanf
函数(输入)%d
: 用于输入整数。
cint number;
scanf("%d", &number);
%f
: 用于输入浮点数。
cfloat pi;
scanf("%f", &pi);
%c
: 用于输入字符。
cchar myChar;
scanf(" %c", &myChar); // 注意空格,防止吸收前一个输入的换行符
%s
: 用于输入字符串。
cchar myString[50];
scanf("%s", myString);
这些占位符允许你以指定的格式输入和输出不同类型的数据。注意在 scanf
函数中,变量前需要加 &
符号,表示取地址,将输入的值存储到相应的变量中。
以上是一些基本的输入输出占位符,对于初学者来说,逐步熟悉和使用它们会帮助你更好地处理输入输出操作。也是我们找出程序错误的利器!
当你需要根据某个条件来执行不同的代码块时,C 语言提供了条件分支的结构,主要有 if
、else if
和 else
。条件分支就是,对应条件下执行对应的代码
if
c#include <stdio.h>
int main() {
int number = 10;
if (number > 0) {
printf("The number is positive.\n");
}
return 0;
}
if
和 else
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 语言中的几种常见循环:
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
的值。
while
循环while
循环在每次迭代前检查条件是否为真,如果为真,则执行循环体。
c#include <stdio.h>
int main() {
int i = 0;
while (i < 5) {
printf("Iteration %d\n", i);
i++;
}
return 0;
}
在这个例子中,while
循环不同于 for
循环,因为它把初始化和更新都放在循环外部。
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
函数接受两个整数参数 a
和 b
,并返回它们的和。在 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 语言中的指针是初学者学习过程中的一项关键任务。指针是一个存储变量地址的变量,它允许直接访问内存位置。这里我觉得初学者不应该着急了解什么是内存什么是地址,只需要了解做什么用就行,以后这些会随着你对编程热爱逐步揭秘!
指针是一个变量,它存储另一个变量的地址。通过指针,你可以直接访问这个地址上存储的数据。指针声明使用 *
符号,如下:
cint *ptr; // 声明一个整型指针
&
取地址运算符 &
用于获取变量的地址。例如:
cint num = 42;
int *ptr = # // 将变量 num 的地址赋给指针 ptr
通过指针,你可以访问存储在特定地址上的值。这通过指针的解引用操作符 *
实现。
cint value = *ptr; // 获取指针 ptr 指向地址上的值
指针和数组之间有着密切的关系。数组名本身就是一个指针,指向数组的第一个元素的地址。
cint arr[5] = {1, 2, 3, 4, 5};
int *arrPtr = arr; // 数组名是指向第一个元素的指针
字符串在 C 语言中是字符数组,可以通过指针操作字符串。
cchar str[] = "Hello";
char *strPtr = str; // 字符数组名是指向第一个字符的指针
指针还可以用于传递函数的地址,实现函数指针。
cint add(int a, int b) {
return a + b;
}
int (*funcPtr)(int, int) = add; // 函数指针指向 add 函数
int result = funcPtr(3, 4); // 通过函数指针调用 add 函数
空指针是指不指向任何有效地址的指针,通常用 NULL
表示。
cint *ptr = NULL; // 空指针
malloc
函数用于在运行时分配内存,并返回指向分配内存的指针。
cint *arr = (int *)malloc(5 * sizeof(int)); // 分配包含 5 个整数的动态数组
指针可以用于操作结构体类型的数据。
cstruct 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 语言文件操作中使用的函数:
fopen
函数原型:
cFILE *fopen(const char *filename, const char *mode);
功能:
FILE
类型的指针。参数:
filename
:要打开的文件的路径和名称。mode
:打开文件的模式,例如 "r"
(读取)、"w"
(写入)等。返回值:
FILE
结构的指针;如果失败,返回 NULL
。fprintf
函数原型:
cint fprintf(FILE *stream, const char *format, ...);
功能:
参数:
stream
:指向 FILE
结构的指针,表示要写入的文件。format
:字符串,包含要写入的文本和格式说明符,类似于 printf
。返回值:
fclose
函数原型:
cint fclose(FILE *stream);
功能:
参数:
stream
:指向 FILE
结构的指针,表示要关闭的文件。返回值:
EOF
。fgets
函数原型:
cchar *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#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;
}
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 许可协议。转载请注明出处!