前言:本篇主要涉及C语言中常用的基本概念、控制结构、函数以及输入输出等方面的知识。
主要涵盖了以下主题:
-
宏定义:
- 符号常量定义和使用。
- 代码替换和宏的基本语法。
- 宏在符号常量定义、代码替换、和条件编译方面的作用。
-
指针:
- 指针的基本概念和使用。
- 指针变量、解引用操作符、以及指针的大小。
-
结构体:
- 结构体的定义和成员访问。
- 使用结构体类型创建结构体变量。
- 结构体指针的使用。
- 嵌套结构体的定义。
- 结构体数组的使用。
- 使用 typedef 简化结构体声明。
-
分支语句(选择结构):
- 基本的if-else分支结构。
- 多分支和else if的使用。
- 与分支相关的应用示例,如学生成绩录取系统。
-
循环语句:
- while循环和for循环的基本用法。
- 死循环和break、continue的应用。
- 循环结构在奇数判断和输出特定范围奇数的应用。
-
输入输出函数:
- getchar()和putchar()的基本用法。
- 输入缓冲区的概念和处理方式。
宏定义
符号常量定义
#define MAX_SIZE 100
代码替换
#define SWAP(x, y) { int temp = x; x = y; y = temp; }
条件编译
#define DEBUG
自定义宏示例
#define ADD(x,y) ((x)+(y))
指针
int main() {
int a = 10;
int* p = &a;
}
结构体
定义结构体
struct Student {
int id;
char name[50];
char sex[10];
char tel[12];
};
使用结构体
struct Student s = {2023001,"张三","男","10086"};
结构体指针
void print(struct Student* ps){
printf("%d %s %s %s\n", ps->id, ps->name, ps->sex, ps->tel);
}
嵌套结构体
struct Address {
char street[50];
char city[50];
int zipCode;
};
struct Person {
char name[50];
int age;
struct Address address;
};
结构体数组
struct Student class[5];
typedef 简化结构体声明
typedef struct {
int hours;
int minutes;
int seconds;
} Time;
分支语句(选择结构)
基本分支
if (grade >= Grade_threshold) {
// code
} else {
// code
}
多分支
if (grade > 380)
// code
else if (grade < 380 && grade > 370)
// code
else if (grade < 370 && grade > 360)
// code
else if (grade < 360)
// code
else
// code
循环语句
while循环
int num = 1;
while (num <= 10) {
// code
num++;
}
for循环
for (num = 0; num <= 100; num++) {
// code
}
死循环
while (1) {
// code
}
break和continue
while (num <= 10) {
if (num == 5) {
break;
}
// code
num++;
}
while (num <= 10) {
num++;
if (num == 5) {
continue;
}
// code
}
输入输出函数
getchar()和putchar()
char c;
printf("Enter a character: ");
c = getchar();
printf("You entered: ");
putchar(c);
输入缓冲区
清理输入缓冲区
getchar();
源代码:
#define 定义标识符常量·:
//#define NUM 100 // 符号常量NUM代表100,在编译阶段NUM会被替换为100
//#define 定义宏:(宏是有参数的):
//在C语言中,`#define`是用来定义宏的预处理指令。宏是一种代码替换的技术,
// 通过定义宏,你可以在程序中使用简单的标识符来表示一组代码,这组代码会在
// 预处理阶段被替换成相应的内容。`#define`的基本语法如下:
//#define 标识符 替换文本
//例如,下面是一个简单的宏定义示例:
//#define PI 3.14159
//在这个例子中,`PI`是一个标识符,它被定义为`3.14159`。
// 在程序中,每次出现`PI`时,都会被替换为`3.14159`。
//宏的作用有以下几个方面:
1. **符号常量定义:** 通过宏定义可以创建符号常量,这样可以在程序中使用
有意义的标识符来代替一些常量值,使代码更易读,也更容易维护。
#define MAX_SIZE 100
这里,`MAX_SIZE`就代表了一个常量值100,方便在程序中使用。
2. **代码替换:** 宏定义还可以用于替换一段代码。例如,你可以定义
一个简单的宏来交换两个变量的值:
#define SWAP(x, y) { int temp = x; x = y; y = temp; }
在程序中使用这个宏可以实现变量交换的功能。
int a = 5, b = 10;
SWAP(a, b);
上述代码在预处理阶段会被替换为:
{ int temp = a; a = b; b = temp; }
3. **条件编译:** 宏定义也经常用于条件编译,通过在编译时根据条件
选择性地包含或排除某些代码块,可以实现不同平台或配置下的代码控制。
#define DEBUG
在调试阶段使用上述宏定义,然后可以通过条件编译选择是否包含调试代码。
这只是宏的一些基础用法,宏在C语言中有更广泛的应用,但也需要注意一些潜
在的问题,比如宏的副作用和作用域等。
自己尝试使用宏定义:
#define ADD(x,y) ((x)+(y)) // 宏定义ADD(x,y),宏体为(x)+(y)
int main()
{
int x = 0, y = 0;
printf("请输入要求和的数:\n");
scanf("%d %d",&x,&y);
int z = ADD(x,y); // 定义变量z来接收结果,使用宏定义替换(x)+(y)
printf("求和结果为:%d",z);
return 0;
}
结果符合预期:
请输入要求和的数:
1 2
求和结果为:3
指针:“内存单元中内存的编号,即地址,存放指针(地址)的变量:指针变量”
int main()
{
int a = 10; // 向内存申请4个字节,存储10
printf("这是变量a:%d",a);
scanf("%d",&a); // &a:取地址,按照地址在内存中找到a
int* p = &a; // 将a的地址指向指针变量p,p就是指针变量
// * 表示p是指针变量,int 说明指针p指向的对象是整型
// “指针变量就是用来存放地址的”
// *:“解引用操作符,*p就是通过p中存放的地址找到所指向的对象,因此,
// *p就是p指向的对象。”
// 指针变量的大小取决于地址的大小
return 0;
}
结构体:
结构体是一种用户自定义的数据类型,用于“将不同类型的数据组合在一起,
形成一个新的数据类型”。以下是关于C语言结构体的一些基本概念和用法:
定义结构体
struct Student { // 结构体:学生
// 结构体成员:
int id; // 学号
char name[50];
char sex[10]; // 性别
char tel[12]; // 电话
};
int main(){
// 使用结构体类型创建结构体变量s:(结构体类型不占空间,创建的变量才申请空间)
// struct Student s
// 给创建的结构体变量赋值(初始化):
struct Student s = {2023001,"张三","男","10086"};
// 通过“结构体对象.成员名”访问结构体成员:
printf("%d %s %s %s\n",s.id,s.name,s.sex,s.tel);
return 0;
}
//2023001 张三 男 10086
// 使用结构体指针访问结构体成员:
void print(struct Student* ps){ // 定义结构体类型指针ps
// 使用“(*指针名).成员名访问结构体成员:
printf("%d %s %s %s\n",(*ps).id,(*ps).name,(*ps).sex,(*ps).tel);
// 使用“->”表示ps指向的对象(Student)的成员:
printf("%d %s %s %s\n",ps->id,ps->name,ps->sex,ps->tel);
}
GPT:
// 使用上面定义好的的结构体“类型”创建结构体变量
struct Student student1;
// 初始化结构体变量
student1.id = 1;
strcpy(student1.name, "John Doe");
student1.gpa = 3.8;
// 结构体作为函数参数
void printStudent(struct Student s) {
printf("ID: %d\n", s.id);
printf("Name: %s\n", s.name);
printf("GPA: %.2f\n", s.gpa);
}
// 调用函数
printStudent(student1);
// 结构体指针
struct Student *ptrStudent = &student1;
// 通过指针访问结构体成员
printf("ID: %d\n", ptrStudent->id);
printf("Name: %s\n", ptrStudent->name);
printf("GPA: %.2f\n", ptrStudent->gpa);
// 嵌套结构体
struct Address {
char street[50];
char city[50];
int zipCode;
};
struct Person {
char name[50];
int age;
struct Address address;
};
// 结构体数组
struct Student class[5];
// 初始化结构体数组
class[0].id = 1;
strcpy(class[0].name, "Alice");
class[0].gpa = 3.5;
// 同样的方式初始化其他数组元素
// 使用 typedef 简化结构体声明(结构体关键字)
typedef struct {
int hours;
int minutes;
int seconds;
} Time;
分支语句(选择结构):
int main(){
int grade = 0; // 初始化初试成绩
int grade_t = 0; // 初始化复试成绩
int Grade_threshold = 388; // 初始化分数线
int Line_for_re_examinatio = 399; // 初始化复试线
printf("考生您好,欢迎来到长安大学研究生录取系统!\n请按照提示输入您的成绩!");
printf("请输入您的初试成绩:");
scanf("%d",&grade);
if (grade >= Grade_threshold)
{
printf("恭喜你成功进入复试!");
}
else
{
printf("很遗憾,您未进入复试。");
}
printf("请输入您的总成绩:\n");
scanf("%d",&grade_t);
if (grade_t >= Line_for_re_examinatio)
{
printf("恭喜你已被长安大学录取!");
}
else
{
printf("很遗憾,您未被录取。");
}
return 0;
}
结果符合预期:
考生您好,欢迎来到长安大学研究生录取系统!
请按照提示输入您的成绩!请输入您的初试成绩:401
恭喜你成功进入复试!请输入您的总成绩:
421
恭喜你已被长安大学录取!
选择结构2:else if:多分支:“可以实现多条件判断”
int main()
{
int grade = 0;
printf("请输入您的成绩:");
scanf("%d",&grade);
if (grade > 380)
printf("苍天不负有心人,恭喜你上岸啦!");
else if (grade < 380 && grade > 370)
printf("加油,还有机会!");
else if (grade < 370 && grade > 360)
printf("希望还是有的。");
else if (grade < 360)
printf("莫等闲,白了少年头,空悲切!");
else
printf("请反省自己,是不是努力了!");
return 0;
}
else 只跟最近的if匹配成对,不是按照缩进匹配:
int main()
{
int a = 0, b = 1;
if (a == 1) // 条件不满足,下面的代码块不执行,直接结束
{ if (b == 2)
printf("hell0\n");
else // 这个else是跟 if (a == 1)匹配的
printf("hi\n");
}
return 0;
}
奇数判断:
int main()
{
int num = 0;
printf("请输入您要判断的整数:");
scanf("%d",&num);
if (num % 2 == 1) // num对2取模,商x余y,若余1,则模为1,则为奇数
// 易错:(num % 2 = 1):把等与写成赋值
printf("这是个奇数");
else
printf("这是个偶数");
return 0;
}
输出1-100之间的奇数:
int main()
{
int num = 0; // 初始化num
for (num = 0; num <= 100; num++) // 生成1-100之间的数
{
if (num % 2 == 1)
printf("%d\n",num);
}
return 0;
}
while循环版本:
int main()
{
int i = 1; // 初始化变量i
while (i <= 100) // 循环条件
{
if (i % 2 == 1) // 判断奇数
printf("%d",i); // 输出奇数
i++; // 一轮判断结束,继续判断下一个数,若不自增,i不会>100,循环无法结束
// 将会一直打印1
}
return 0;
}
循环语句:
while循环:while(表达式){循环体};表达式为真,则进入循环体,直到表达式为假。
int main()
{
while (1) // 非0即为真,这是一个死循环。
{
printf("hhh");
}
return 0;
}
使用while循环打印1-10:
int main(){
int num = 1;
while (num <= 10)
{
printf("%d", num);
num++;
}
return 0;
}
复习break和continue:
int main(){
int num = 1;
while (num <= 10)
{
if (num == 5)
{
break;
}
printf("%d", num);
num++;
}
return 0;
}
1234
int main(){
int num = 1;
while (num <= 10)
{
num++;
if (num == 5)
{
continue;
}
printf("%d", num);
}
return 0;
}
23467891011
getchar()和putchar():
getchar()和putchar()是两个常用的输入输出函数,用于从标准输入读取字符和向标准输出写入字符。它们的作用如下:
- getchar():
getchar()
用于从标准输入(通常是键盘)读取一个字符。- 返回值是读取的字符的ASCII码值,或者在文件结束时返回
EOF
(End of File)。
示例:
#include <stdio.h>
int main() {
char c;
printf("Enter a character: ");
c = getchar(); // 从标准输入读取一个字符
printf("You entered: ");
putchar(c); // 将字符输出到标准输出
return 0;
}
- putchar():
putchar()
用于向标准输出(通常是屏幕)写入一个字符。- 接受一个整数参数,通常是表示字符的ASCII码值。
- 返回写入成功的字符,或者在错误时返回
EOF
。
示例:
#include <stdio.h>
int main() {
char c = 'A';
printf("The character is: ");
putchar(c); // 将字符输出到标准输出
return 0;
}
这些函数在实际编程中经常用于简单的字符输入和输出。请注意,
它们通常在控制台程序中使用,而在图形用户界面(GUI)程序或其他环境中
可能会使用不同的输入输出函数。
在理解 getchar()
和输入缓冲区的关系时,需要了解C语言中的输入缓冲区概念。
输入缓冲区:
输入缓冲区是一个存储用户输入的地方,它存储了键盘输入的字符,等待程序读取。当用户在键盘上输入一串字符,这些字符首先被存储在输入缓冲区中,然后由程序从缓冲区中读取。
与 getchar()
相关的输入缓冲区:
getchar()
函数从标准输入(通常是键盘)读取一个字符,并且它会从输入缓冲区中读取一个字符。这就涉及到一个重要的概念,即缓冲区的使用。
当你调用 getchar()
时,它会检查输入缓冲区。如果输入缓冲区非空(有待读取的字符),getchar()
会直接从缓冲区中读取一个字符并返回。如果输入缓冲区为空,getchar()
会等待用户输入,并且直到用户按下 Enter 键,输入的字符才会被存储到输入缓冲区。然后,getchar()
从输入缓冲区中读取一个字符并返回。
这种行为可能导致一些不直观的结果,特别是当你在程序中组合使用不同的输入函数时。如果在使用 scanf()
或其他输入函数时留下了换行符(Enter 键)在输入缓冲区中,它可能会影响到后续的 getchar()
调用。为了避免这种情况,你可以在使用 getchar()
之前清理输入缓冲区,可以使用 getchar()
或 scanf("%*c")
来处理换行符。
下面是一个简单的例子,演示了 getchar()
与输入缓冲区的交互:
#include <stdio.h>
int main() {
char c;
printf("Enter a character: ");
c = getchar(); // 从输入缓冲区中读取一个字符
printf("You entered: ");
putchar(c); // 将字符输出到标准输出
return 0;
}
在这个例子中,`getchar()` 会等待用户输入,并且用户按下 Enter 键后,输入的字符被读取并存储在变量 `c` 中。
int main() {
char c;
printf("请输入字符: ");
c = getchar(); // 从输入缓冲区中读取一个字符
printf("您的输入为: ");
putchar(c); // 将字符输出到标准输出
return 0;
}
请输入字符: a
您的输入为: a