编程痛点-指针和数组

指针和数组到底什么情况?🫤

      
#include< stdio.h>
void value(int* a)
{
	printf("%d", *a);
}
int main()
{
	int a = 10;
	value(&a);
}
/*
这段代码结果不重要,重要的是今天写一段代码的时候
脑袋突然想不通
value接受的是int *的参数
也就是接受的是地址
但是int *又可以是数组,一维数组
那到底是数组还是地址?
后来仔细捣鼓了一下
int * a中的a是指针变量,既不是数组也不是地址
指针变量就是个变量,是变量存有值,值就是地址
无论是数组也好,单个数的地址也罢
传的都是地址就够了,函数也不在意是什么东西
只要是一个地址就行
*/
      
		
#include< stdio.h> void value(int* a) { for(int i=0;i<10;i++) printf("%d",*(a+i)); } int main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; value(a); } //输出结果12345678910 /* * 我想表达的是数组名是一个指针常量 * 但是当传给形参以后,函数内部使用的就不是指针常量了 * 是形参是指针变量 */

解决思路和难点

这里是描述解决思路的




编程痛点-const位置

🫤

      
#include< stdio.h>
int main()
{
	int long a = 10;
	long int b = 10;
	printf("%d,%d",a,b);

	unsigned int c=10;
	int unsigned d = 10;
	printf(",%d,%d", c, d);
}
/*以上程序结果是10,10,10,10
* 没错long在前和在后是一样的
*/

const int* p;
int const* p;
//同理首先这两个是一个意思

//接下来看
int* const p;
const int * p;
//第一个修饰的是p,p是指针
//保持的内容是地址,也就是说保存的地址不能变了
//通俗讲就变成了指针常量
//也就是说p = & a;这种是不给通过了
/*
第二个修饰的是*p
记住
const int * p;
int const * p;
是一个意思
*p是解引用,也就是地址上存放的数据
也就是说
*p = 10;这样不给通过了
*/
//我知道你想说什么
const int* const p;//是的。双重枷锁
      
		

解决思路和难点

这里是描述解决思路的




文件编程-基础的搬运工

🤨将一个txt文本内容搬运到另一个文本当中

      
#include < stdio.h>
#include< string.h>

//VS2022 WIN11环境测试
int main()
{
	errno_t err1,err2;// 错误处理的类型定义,它是一个整数类型
	const char* filename1 = "C:/Users/16201/Desktop/input_1..txt";//定义文件地址,是常量
	const char* filename2 = "C:/Users/16201/Desktop/output_1.txt";
	FILE* p1 = NULL;//初始化文件指针
	FILE* p2 = NULL;
	err1 = fopen_s(&p1,filename1,"r");//当文件打开成功的时候,返回0
	err2 = fopen_s(&p2,filename2, "w");//之所以不使用fopen是因为已经被抛弃了,是不安全的函数
	if (err1 == 0)
	{
		printf("文件打开成功\n");
	}
	else {
		printf("文件打开失败\n");
		return 1;//打开失败就结束程序
	}
	if (err2 == 0)
	{
		printf("文件打开成功\n");
	}
	else {
		printf("文件打开失败\n");
		return 1;
	}
	char ch = 0;//定义一个字符变量,用于每次的读取缓冲区的一个字符
	while (1)
	{
		ch = fgetc(p1);//获取缓冲区的一个字符
		if (ch == EOF)//如果读到了文件末尾就结束
		{
			break;//结束了
		}
		fputc(ch, p2);//将字符依次存入目标文件
	}
	printf("成功");
	fclose(p1);//一定要关闭文件
	fclose(p2);
	p1 = NULL;
	p2 = NULL;
	return 0;
}

      
		

解决思路和难点

这里是描述解决思路的

文件编程-基础

      
#include< stdio.h>
#include< string.h>
int main()
{
	char buff[255];
	const char* filename = "C:/Users/16201/desktop/test1.txt";
	FILE* fp = NULL;
	fp = fopen(filename, "w+");//第二个一定是双引号,而不是单引号
	fprintf(fp, "this is test for fprintf\n");//将文本输入到文本文件中
	//printf是从后向前输出,输入输出是相对于计算机内存而言
	fputs("this is test for fputs\n",fp);//将文本输入到文本文件中
	//puts是从前向后输出
	fclose(fp);
	fp = NULL;
	fp = fopen(filename, "r+");
	char c = fgetc(fp);
	putc(c,stdout);
	fscanf(fp, "%s", buff);//遇到回车或者空格停止读取
	//scanf是从前向后输入,文件可以看作是另一种形式的键盘
	printf("%s ",buff);
	fgets(buff, 255, fp);//遇到换行符或者结尾,就停止,并在末尾添加换行符
	//get是从后向前输入
	//fgets和fputs的文件指针都位于最后
	//fprintf和fscanf文件指针都位于最前
	printf("%s ",buff);
	fclose(fp);
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-文本文件的读写

某学校需要对学生信息进行管理,学生信息包括学号、姓名、年龄和成绩。请用C语言编写程序,定义一个学生信息的结构体,并实现以下功能:
从文本文件中读取学生信息,并存储在结构体数组中。
允许用户通过学号查询学生信息,并显示在控制台上。
用户可以输入一个学生信息,程序将其添加到结构体数组中,并更新文本文件。
计算并输出所有学生的平均成绩。
	
      
/*
某学校需要对学生信息进行管理,学生信息包括学号、姓名、年龄和成绩。请用C语言编写程序,定义一个学生信息的结构体,并实现以下功能:
从文本文件中读取学生信息,并存储在结构体数组中。
允许用户通过学号查询学生信息,并显示在控制台上。
用户可以输入一个学生信息,程序将其添加到结构体数组中,并更新文本文件。
计算并输出所有学生的平均成绩。
*/
#include< stdio.h>
#include< stdlib.h>
#include< string.h>
#define MAX_STUDENTS 100
#define MAX_NAME_LEN 50
typedef struct {
	int id;
	char name[MAX_NAME_LEN];
	int age;
	int score;
}Student;
//从文件中读取学生信息
int readStudent(Student student[], const char* filename)
{
	FILE* fp = fopen(filename, "r");
	if (!fp)//fopen打开失败返回NULL指针,所以!NULL就是真
	{
		perror("文件打开失败\n");
		return 0;
	}
	int count = 0;
	while (fscanf(fp, "%d %s %d %f", &student[count].id, student[count].name, &student[count].age, &student[count].score) != EOF)
	{
		count++;
	}
	fclose(fp);
	return count;
}
//显示学生信息
void displayStudent(const Student* student)
{
	printf("ID: %d,Name: %s,Age: %d,Score: %.2f\n", student->id, student->name, student->age, student->score);
}
//添加学生信息
void addStudent(Student student[], int* count, const char* filename)
{
	int id, age;
	float score;
	char name[MAX_NAME_LEN];
	printf("plase input you ID,Name,Age,Score:空格分割\n");
	scanf("%d %s %d %f",&id,name,&age,&score);
	student[*count].id = id;
	strcpy(student[*count].name, name);
	student[*count].age = age;
	student[*count].score = score;
	(*count)++;
	FILE* fp = fopen(filename, "a");
	if (!fp)
	{
		perror("打开文件失败\n");
		return;
	}
	fprintf(fp, "%d %s %d %.2f\n", id, name, age, score);
	fclose(fp);
}
//计算平均成绩
float calculateAverageScore(Student student[], int count)
{
	float sum = 0;
	for (int i = 0; i < count; i++)
	{
		sum += student[i].score;
	}
	return sum / count;
}
int main()
{
	Student student[MAX_STUDENTS];
	int count = readStudent(student, "student.txt");
	printf("请输入ID查找学生信息\n");
	int searchID = 0;
	scanf("%d", &searchID);
	for (int i = 0; i < count; i++)
	{
		if (student[i].id == searchID)
		{
			displayStudent(&student[i]);
			break;
		}
	}
	addStudent(student, &count, "student.txt");
	printf("平均分数为:%.2f\n", calculateAverageScore(student, count));
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-二进制文件的读写

图书馆需要对图书库存进行管理,图书信息包括ISBN号、书名、作者和库存数量。请用C语言编写程序,定义一个图书信息的结构体,并实现以下功能:
从二进制文件中读取图书信息,并存储在结构体数组中。
允许用户通过ISBN号查询图书信息,并显示在控制台上。
用户可以输入一个ISBN号和新的库存数量,程序更新该ISBN号的图书库存,并写回二进制文件。
统计并输出库存数量低于10本的图书信息。
	
      
/*
图书馆需要对图书库存进行管理,图书信息包括ISBN号、书名、作者和库存数量。请用C语言编写程序,定义一个图书信息的结构体,并实现以下功能:
从二进制文件中读取图书信息,并存储在结构体数组中。
允许用户通过ISBN号查询图书信息,并显示在控制台上。
用户可以输入一个ISBN号和新的库存数量,程序更新该ISBN号的图书库存,并写回二进制文件。
统计并输出库存数量低于10本的图书信息。
*/
#include< stdio.h>
#include< stdlib.h>
#include< string.h>
#define MAX_BOOKS 1000
#define MAX_TITLE_LEN 100
#define MAX_AUTOHOR_LEN 50
typedef struct
{
	int isbn;
	char title[100];
	char author[50];
	int quantity;
}Book;
//从二进制文件中读取图书信息
int readBooks(Book book[], const char* filename)
{
	FILE* fp = fopen(filename, "r");
	if (!fp)
	{
		perror("打开文件失败\n");
		return 0;
	}
	int count = 0;
	while (fread(&book[count], sizeof(Book), 1, fp))//fread返回成功读取的元素总数
	{
		count++;
	}
	fclose(fp);
	return count;
}
//显示图书信息
void displayBook(const Book* book)
{
	printf("ISBN:%d,Title:%s,Author:%s,Quantity:%d\n",book->isbn,book->title,book->author,book->quantity);
}
//更新图书库存
void updateBookQuantity(Book book[], int count, const char* filename)
{
	int isbn, quantity;
	long position;
	printf("输入ISBN和库存数量:\n");
	scanf("%d %d", &isbn, &quantity);
	for (int i = 0; i < count; i++)
	{
		if (book[i].isbn == isbn)
		{
			book[i].quantity = quantity;
			position = i;
			break;
		}
	}
	FILE* fp = fopen(filename, "rb+");
	if (!fp)
	{
		perror("打开文件失败\n");
		return;
	}
	//定位到修改处
	long position = (long)sizeof(Book) * position;
	if (fseek(fp, position, 0) != 0)//fseek成功设置指针返回0,不然返回非零值
	{

	}
	//更新记录
	if (fwrite(&book[isbn], sizeof(Book), 1, fp) != 1)//fwrite成功写入返回写入的个数
	{
		perror("文件打开失败\n");
	}
	fclose(fp);
}
//统计库存低于10本的图书
void lowStockBook(Book book[], int count)
{
	printf("图书低库存的有:\n");
	for (int i = 0; i < count; i++)
	{
		if (book[i].quantity < 10)
		{
			displayBook(&book[i]);
		}
	}
}
int main()
{
	Book book[MAX_BOOKS];
	int count = readBook(book, "book.bin");
	printf("输入ISNB搜索图书\n");
	int searchisbn;
	scanf("%s", &searchisbn);
	for (int i = 0; i < count; i++)
	{
		if (book[i].isbn == searchisbn)
		{
			displayBook(&book[i]);
			break;
		}
	}
	updateBookQuantity(book, count, "book.bin");
	lowStockBook(book, count);
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-CSV格式的文件读写

公司需要对员工工资进行管理,员工信息包括工号、姓名、基本工资和奖金。请用C语言编写程序,定义一个员工信息的结构体,并实现以下功能:
从CSV文件中读取员工信息,并存储在结构体数组中。
允许用户通过工号查询员工的工资详情,并显示在控制台上。
用户可以输入一个工号和新的奖金数额,程序更新该工号的员工奖金,并写回CSV文件。
输出所有员工的总工资(基本工资+奖金)。
	
      
/*
公司需要对员工工资进行管理,员工信息包括工号、姓名、基本工资和奖金。请用C语言编写程序,定义一个员工信息的结构体,并实现以下功能:
从CSV文件中读取员工信息,并存储在结构体数组中。
允许用户通过工号查询员工的工资详情,并显示在控制台上。
用户可以输入一个工号和新的奖金数额,程序更新该工号的员工奖金,并写回CSV文件。
输出所有员工的总工资(基本工资+奖金)。
*/
#include < stdio.h>
#include < stdlib.h>
#include < string.h>
#define MAX_EMPLOYEES 500
#define MAX_NAME_LEN 50
typedef struct
{
	int id;
	char name[MAX_NAME_LEN];
	int baseSalary;
	int bonus;
}Employee;
//从CSV文件中读取员工信息
int readEmployees(Employee employees[], const char* filename)
{
	FILE* fp = fopen(filename, "r");
	if (!fp)
	{
		perror("打开文件出错\n");
		return 0;
	}
	int count = 0;
	char line[256];
	while (fgets(line,sizeof(line),fp))
	{
		sscanf(line, "%d,%49[^,],%f,%f", &employees[count].id, employees[count].name, &employees[count].baseSalary, &employees[count].bonus);
		//sscanf用于在字符串中读取字符,第一个参数不是fp而是字符串
		count++;
	}
	fclose(fp);
	return count;
}
// 显示员工工资详情
void displayEmployee(const Employee* employee) {
	printf("ID: %d, Name: %s, Base Salary: %.2f, Bonus: %.2f\n", employee->id, employee->name, employee->baseSalary, employee->bonus);
}

// 更新员工奖金
void updateEmployeeBonus(Employee employees[], int count, const char* filename) {
	int id, bonus;
	printf("Enter ID and new bonus: ");
	scanf("%d %d", &id, &bonus);
	for (int i = 0; i < count; i++) {
		if (employees[i].id == id) {
			employees[i].bonus = bonus;
			break;
		}
	}
	FILE* fp = fopen(filename, "w");
	if (!fp) {
		perror("File opening failed");
		return;
	}
	for (int i = 0; i < count; i++) {
		fprintf(fp, "%d,%s,%.2f,%.2f\n", employees[i].id, employees[i].name, employees[i].baseSalary, employees[i].bonus);
	}
	fclose(fp);
}

// 输出所有员工的总工资
void totalSalary(Employee employees[], int count) {
	float total = 0;
	for (int i = 0; i < count; i++) {
		total += employees[i].baseSalary + employees[i].bonus;
	}
	printf("Total Salary: %.2f\n", total);
}

int main() {
	Employee employees[MAX_EMPLOYEES];
	int count = readEmployees(employees, "employees.csv");
	printf("Enter ID to search for employee salary: ");
	int searchId;
	scanf("%d", &searchId);
	for (int i = 0; i < count; i++) {
		if (employees[i].id == searchId) {
			displayEmployee(&employees[i]);
			break;
		}
	}
	updateEmployeeBonus(employees, count, "employees.csv");
	totalSalary(employees, count);
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-1

请编写一个函数fn,它的功能是:将一个数字字符串转换为一个整数(不得调用C语言提供的将字符串转换为整数的函数)。例如,若输入字符串"-1234",则 函数把它转换为整数值 -1234。函数 fun 中给出的语句仅供参考。

      
#include< stdio.h>
#include< string.h>
int fun(char* s)
{
	int a = strlen(s);//不使用这个的话,得加个循环遍历求得字符串长度
	int b = 1;
	int sum = 0;
	for (int i = 0; i < a; i++)//遍历整个字符串
	{
		if (s[0] == '-')//如果字符为-号,那么我们将记录并且最终乘上
		{
			b = -1;
		}
		if ('0' <= s[i] && s[i] <= '9')//如果字符位于0到9之间就记录
		{
			sum = sum * 10;//先让sum递增一位
			sum = sum + (s[i] - '0');//再将新加入的放入个位
		}
	}
	return sum*b;//返回乘上符号的数字
}
int main()
{
	char s [40];
	scanf("%s",s);
	printf("%d",fun(s));
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-2

请编写函数 fn,函数的功能是: 将M行N列的二维数组中的字符数据,按列的顺序依次放到一个字符串中。

例如二维数组中是这样的
W W W W
S S S S
H H H H
则字符串中的内容应是:WSHWSHWSH。
	
      
#include< stdio.h>
#include< string.h>
#define M 30//#define M 30;你没看错,我竟然在宏定义后面加分号
#define N 30
char * fun(char s[M][N])
{
	int m = 0;
	char result[N * M] = {0};
	for (int i = 0; i < M; i++)//遍历行
	{
		for (int j = 0; j < N; j++)//遍历列
		{
			if (s[j][i])//如果这个位置存储了就执行我们的存入
				result[m++] = s[j][i];//存入
			else
				continue;//如果这个位置没有东西我们就跳过
		}
	}
	result[m] = '\0';//然后加入我们字符串的标准结束标志
	return result;//刚开始忘记加上返回了,卧槽了
}
int main()
{
	char s[M][N] = { { 'W','W','W','W' }, { 'S','S','S','S' }, { 'H','H','H','H' } };
	char* p = fun(s);
	printf("%s",p);
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-3

请编写函数fun,函数的功能是:统计一行字符串中单词的个数,作为函数值返回。一行字符串在主函数中输入,规定所有单词由小写字母组成。单词之间由若干个空格隔开,一行的开始没有空格

	
      
#include< stdio.h>
#include< string.h>
int fun(char *s)
{
	int i = 0;//遍历游标
	int j = 1;//单词间空格开始标志
	int res = 0;//结果
	while (s[i] != '\0')//当不到字符串末尾就不停止
	{
		if (s[i] == ' '&&j==1)//如果当前为空格,并且空格如果是许多空格的第一个
		{
			i++;//游标加1
			res++;//结果+1,因为我们只记录第一个空格代表第一个单词结束
			j = 0;//我们让j=0说明接下来如果还有空格就不记录了
		}
		else
		if (s[i] == ' ' && j == 0)//当前是空格,且不是单词间的第一个空格了
		{
			i++;//单纯让游标向后
		}
		if (s[i] != ' ')//如果当前不为空格,也就是单词开始了
		{
			i++;//游标还是向后
			j = 1;//我们将空格标记归为初始
			continue;
		}

	}
	return res+1;
}
int main()
{
	char s[30] = { 0 };
	gets(s);
	printf("这个字符串一共有%d个单词",fun(s));
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-4

请编写函数fun,函数的功能是:统计各年龄段的人数。N个年龄通过调用随机函数获得,并放在主函数的age数组中;要求函数把0至9岁年龄段的人数放在d[0]中,把10至19岁年龄段的人数放在d[1]中,把20至29岁年龄段的人数放在d[2]中,其余依此类推,把100岁(含100)以上年龄的人数都放在d[10]中。结果在主函数中输出。

	
      
#include< stdio.h>
#include< stdlib.h>
#define N 10000

int* fun(int* a,int *d)//统计各个年龄段的人数
{

	for (int i = 0; i < N; i++)//遍历数组
	{
		switch (a[i] / 10)//让这个岁数缩小到0~10
		{
		case 0:
			d[0]+=1;
			//d[0]++;我一开始每一个都是这样写的,不知道为什么明明加了,还是0
			//后来发现不是这里的问题,好像是从外面传进来的d数组的问题
			break;
		case 1:
			d[1]+=1;
			break;
		case 2:
			d[2]+=1;
			break;
		case 3:
			d[3]+=1;
			break;
		case 4:
			d[4]+=1;
			break;
		case 5:
			d[5]+=1;
			break;
		case 6:
			d[6]+=1;
			break;
		case 7:
			d[7]+=1;
			break;
		case 8:
			d[8]+=1;
			break;
		case 9:
			d[9]+=1;
			break;
		case 10:
			d[10]+=1;
			break;
		}
	}
	return d;//返回结果
}
int main()
{
	int d[11] = { 0 };//定义一个结果数组
	//int* d[11] = { 0 };原来是我一开始是这样写的,老糊涂了,指针数组都写出来了
	int age[N] = {0};
	for (int i = 0; i < N; i++)
	{
		age[i] = rand() % 100;
	}
	for (int z = 0; z < N; z++)
	{
		printf("岁数为%d\n",age[z]);
	}
	int *d1=fun(age,d);//我一开始直接用d来输出,不知道为什么老是11140000000
	for (int j = 0; j < 11; j++)
	{
		printf("%d ",d[j]);
	}
	for (int j = 0; j < 11; j++)
	{
		printf("\n%d岁到%d岁的人数有%d个\n", j * 10, (j + 1) * 10 - 1, d[j]);
	}
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-5

请编写函数fn,函数的功能是:删去一维数组中所有相同的数,使之只剩一个。数组中的数已按由小到大的顺序排列,函数返回删除后数组中数据的个数。 例如,一维数组中的数据是:2223445666677899101010。删除后,数组中的内容应该是:2 3 4 5 6 7 8 9 10

	
      
#include< stdio.h>
int fun(int *a,int array_size)
{
	int c=0, d=0;//定义一个当前下标,以及一个跳标
	for (int i =0;i< array_size;i++)//遍历数组
	{
		if(a[i] != a[d])//如果遍历的不等于跳标
		{
			a[c] = a[i - 1];//就让结果记录跳标的前一个
			//也就是222333444第一次3不等于2的时候,记录2,也就是最后一个2
			d = i;//让跳标指向当前i,也就是记录2以后让标指向3
			c++;//记录+1
		}
	}
	a[c] = a[array_size-1];//因为数组最后一个始终无法记录,因为它后面没有参考,所以手动记录
	return c+1;//返回大小
}
int main()
{
	int a[] = { 2,2,2,3,4,4,5,6,6,6,6,7,7,8,9,9,10,10,10 };
	printf("%d\n", sizeof(a) / sizeof(int));//计算数组大小
	int res = fun(a,sizeof(a)/sizeof(int));//返回新的数组大小
	for (int i =0;i< res;i++)
	{
		printf("%d ",a[i]);//循环打印
	}
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-6

请编写函数fun,函数的功能是:移动字符串中的内容,移动的规则如下:把第1到第m个字符,平移到字符串的最后,把第m+1到最后的字符移到字符串的前部。例如,字符串中原有的内容为:ABCDEFGHIJK,m的值为3,则移动后,字符串中的内容应该是:DEFGHIJKABC。

	
      
#include< stdio.h>
#include< stdlib.h>
char * fun(char *s,int m)
{
	int a = m,b=0;//定义一个a用来将后m-1个移到前面
	int i = 0,j=0;
	char* p = (char*)malloc(sizeof(char)*m);
	while (i < m)//将前m个放到临时数组
		//一开始写的是i!=m,始终少存一个
		//改成i< m 还是少
				  {
				  p[i] = s[i];//打断点发现,这里确确实实是存到了的ABC
				  i++;
				  }
				  while (s[a])//将m后面的m-1个移动到前面
	{
		s[b++] = s[a++];
	}
	while (j!=i)//原来是这个,我一开始条件是j!=i-1
		//i本身才是那个终止的值,i-1反而会造成缺少一个
	{
		s[b++] = p[j++];//将临时数组的放进后面去
	}
	s[b] = '\0';//添加字符串结束标志
	return s;//返回我们的字符串
}
int main()
{
	int m=0;
	printf("输入需要平移的量\n");
	scanf("%d",&m);
	char s[] = "ABCDEFGHIJK";
	char * p =fun(s, m);
	while(*p)
	{
		printf("%c",*p);
		p++;
	}
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-7

要求编写一个函数,该函数的功能是删除字符串中的所有空格。例如,如果输入字符串是 "asd af aa z67",那么输出应该是 "asdafaaz67"。

	
      
#include< stdio.h>
#include< string.h>
#define N 10
void fun(char * s)
{
	int i = 0;
	int j = 0;
	while (s[i]!='\0')//遍历字符串
	{
		if (s[i] != ' ')//当不为空格的记录字符
		{
			s[j++] = s[i++];
		}
		else//当为空格的时候略过它
		{
			i++;
			continue;
		}
	}
	s[j] = '\0';//最后添加一个字符串的结束标志
}
int main()
{
	char s[20] = {0};
	printf("请输入一串字符\n");
	gets(s);
	puts(s);
	fun(s);
	printf("%s",s);
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-8

请编写函数fun,函数的功能是:将放在字符串数组中的M个字符串(每串的长度不超过N),按顺序合并组成一个新的字符串。函数fun中给出的语句仅供参考。例如,字符串数组中的M个字符串为:

		AAAA
		BBBBBB
		CC
		则合并后的字符串的内容应是:AAAABBBBBBCC。
	
      
#include< stdio.h>
#include< stdlib.h>//分配内存函数的头文件
#define N 10
char* fun(char s[][N], int M,char *p)
//char* fun(char* s[][N], int M)我一开始是这样写的让结果返回
//但是发现打印不出来,我就想会不会是函数内部分配的内存也是出了函数就不存在了
//但是后面发现还是不行
{
	int z = 0;
	// 分配足够的空间,包括每个字符串的结束符

	for (int i = 0; i < M; i++)
	{
		int j = 0;
		while (s[i][j] != '\0')
		{
			p[z++] = s[i][j];//p[z++] = s[i][j];第一次这里内存出错
			//原来是s[0][0]其实是一个字符串,而不是一个字符
			//我想了半天我日,为什么呢
			//原来是主函数数组定义char* s[N][N]
			//定义成这玩意了,唉
			//还是不行,原来是函数参数声明我写的是
			//char* fun(char* s[][N], int M,char *p)
			//char*s[][N]你说这不是傻逼吗卧槽,三维了干
			j++;
		}
	}
	p[z] = '\0';
	return p;
}
int main()
{
	char s[N][N] = { "aasaaaa" , "bbbbb"  ,"ccccc" ,  "ddddd" , "eeeee"  , "fff"  , "gg"  , "hh"  , "ii"  , "kkkkk"  };
	int M = 0;
	printf("请输入需要将前几个字符串组合?\n");
	scanf("%d", &M);
	char* p = (char*)malloc(sizeof(char) * (N * M + M));
	fun(s, M,p);
	printf("%s", p);
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-9

要求编写一个函数 fun,其功能是将一个 M 行 N 列的二维数组中的数据按列的顺序依次放入一个一维数组中。给出的例子展示了一个 3 行 3 列的二维数组,以及按列顺序排列后一维数组的内容。

33 33 33 33
44 44 44 44
55 55 55 55
33 44 55 33 44 55 33 44 55 33 44 55
	
      
#include< stdio.h>
#include< stdlib.h>
#define N 4//我一开始写的是3,结果定义数组的时候报错,初始值定义太多
#define M 3
fun(int a[][N],int *b)
{
	int z = 0;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			b[z++] = a[j][i];
		}
	}
}
int main()
{
	int a[M][N] = { {33,33,33,33},{44,44,44,44},{55,55,55,55} };
	int b[M * N] = { 0 };
	fun(a, b);
	for (int i = 0; i < M * N; i++)
	{
		printf("%d ",b[i]);
	}
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-10

编写一个函数 fun,用于判断一个字符串是否为回文。回文是指顺读和倒读都一样的字符串。 如果字符串是回文,函数返回 1,并在主函数中输出 "YES";如果不是回文,函数返回 0,并在主函数中输出 "NO"。

字符串 "LEVEL" 是回文,所以函数返回 1,主函数输出 "YES"。
字符串 "123312" 不是回文,所以函数返回 0,主函数输出 "NO"。
	
      
#include< stdio.h>
#include< stdlib.h>
int fun(char* s)
{
	int isture = 0;
	int a = 0;
	while (s[a] != '\0')
	{
		a++;
	}
	a = a - 1;
	for (int i = 0; i < a / 2; i++)
	{
		if (s[i] == s[a - i])
		{
			isture = 1;
			continue;
		}
		if (s[i] != s[a - i])
		{
			isture = 0;
			break;
		}
	}
	return isture;
}
int main()
{
	char s[20] = { 0 };
	scanf("%s", s);
	if (fun(s))
	{
		printf("YES");
	}
	else
	{
		printf("NO");
	}
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-11

N名学生的成绩已在主函数中放入一个带头节点的链表结构中,h指向链表的头节点。请编写函数fun,它的功能是:找出学生的最高分,由函数值返回。

	
      
#include< stdio.h>
#include< stdlib.h>
#include< time.h>
#define N 10
typedef struct SlistNode
{
	int data;
	struct SListNode* Next;
}Student,*S;
int fun(Student* s)//当然S s也是可以的,不必拘泥
{
	Student* p = s;//定义我们的傀儡
	p = p->Next;//因为有头节点,所以我们跳过它
	int Max = p->data;//假设第一个为最大
	for (int i = 0; i < N; i++)//遍历数组
	{
		if (p->data > Max)
		{
			Max = p->data;
			p = p->Next;
		}
		else
		{
			p = p->Next;
		}
	}
	return Max;
}
int main()
{
	S s=NULL;//S是结构体指针 类型声明相当于(int*)
	S p = (S)malloc(sizeof(Student));
	p->Next = NULL;
	s = p;
	for (int i = 0; i < N; i++)
	{
		srand(time(0)+rand());//以时间为种子
		int a = rand() % 100;//每一秒都是随机且平均的
		p = (S)malloc(sizeof(Student));//分配空间
		p->data = a;
		p->Next = s->Next;
		s->Next = p;//s=p,我一开始这样写,完全s本身是头结点,下一个才是加入的新节点
	}
	p = s->Next;
	for (int i = 0; i < N; i++)
	{
		printf("%d ",p->data);
		p = p->Next;
	}
	printf("\n");

	printf("成绩最高的为%d\n",fun(s));
}

      
		

解决思路和难点

这里是描述解决思路的




经典例题-12

请编写函数fun,对长度为7个字符的字符串,除首、尾字符外,将其余5个字符按ASCII码降序排列。例如,原来的字符串为CEAedca,排序后输出为CedceEAa。

	
      
#include< stdio.h>
#define N 8
void fun(char *s)
{

	for (int i=1;i< N-2;i++)//使用简单选择排序
	//为什么-2,因为字符串结束符,以及第7字符都不排序
	//第一个也不参与排序
	{
		int M = i;
		for (int j = i; j < N-2; j++)
		{
			if (s[j] > s[M])
			{
				M = j;
			}
		}
		char temp = s[i];
		s[i] = s[M];
		s[M] = temp;
	}
}
int main()
{
	char s[N] = "CEAedca";
	fun(s);
	printf("%s",s);
}
      
		

解决思路和难点

这里是描述解决思路的




经典例题-13

学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:把指定分数范围内的学生数据放在b所指的数组中,分数范围内的学生人数由函数值返回。

例如,输入的分数是60 69,则应当把分数在60到69的学生数据进行输出,包含60分和69分的学生数据。主函数中将把60放在low中,把69放在heigh中。
	
      
#include< stdio.h>
#include< stdlib.h>
#include< time.h>
#define N 20
typedef struct List
{
	char num[12] ;//学号
	int ag;
	struct List *next;
}*Student,S;
int fun(Student s, S* b,int c,int d)
{
	int i = 0;
	Student p = s->next;
	while (p != NULL)
	{
		if (p->ag > c && p->ag < d)
		{
			b[i++] = *p;
			p = p->next;
		}
		else
		{
			p = p->next;
		}
	}
	return i - 1;
}
int main()
{
	Student p = (Student)malloc(sizeof(S));
	p->next=NULL;
	Student s = p;
	int a = 0;
	for (int i = 0; i < N; i++)
	{
		srand(time(0)+rand());
		a = rand() % 100;
		p = (Student)malloc(sizeof(S));
		p->ag = a;
		sprintf(p->num, "2024%d", i);
		p->next = s->next;
		s->next = p;
	}
	p = s->next;
	for (int j = 0; j < N; j++)
	{
		printf("学号为%s的学生的成绩为%d\n", p->num, p->ag);
		p = p->next;
	}
	printf("请输入分数范围:\n");
	int b = 0, c = 0;
	scanf("%d%d",&b,&c);
	S e[N];
	int d= fun(s, e, b, c);
	printf("这个分数段的人数共有%d人\n分别是\n",d);
	for (int i = 0; i < d; i++)
	{
		printf("学号%s\t分数%d\n",e[i].num,e[i].ag);
	}
	return 1;
}
      
		

解决思路和难点

这里是描述解决思路的




23年真题第一题-14

1.某公司二进制文件falicity.data保存有公司设备库存的数量,文件中保存的设备的信息有ID、Name、Num,结构如下:

ID Name Num
1 Switch 24
2 Hub 80
... ... ...

任务要求:

  1. 请用C语言编写该数据的结构体,并实现信息的输入与输出。
  2. 当用户输入ID和对应的Num时,修改对应设备的数量,并写回二进制文件中。(给出测试函数)
      
#include< stdio.h>
#include< stdlib.h>
#include< string.h>//无所谓,用与不用,都写上,当贡品
#define NAME_SIZE 50
#define RECODE_SIZE 100
typedef struct
{
	int ID;
	char Name[NAME_SIZE];
	int Num;
}Recode;
//从二进制流中读取文件
int readfalicity(Recode recode[], const char* filename)
{
	FILE* fp = fopen(filename,"r");
	if (!fp)//如果fp为空,那么!fp就永久为真
	{
		perror("打开文件失败\n");
		return 0;
	}
	int count = 0;
	while (fread(&recode[count], sizeof(Recode), 1, fp))//fread返回成功读入的元素个数,如果为0就停止
	{
		count++;//每次记录读入的个数
	}
	fclose(fp);
	return count;
}
//显示信息
void displayRecode(const Recode* recode)
{
	printf("ID is %d,NAME is %s,Num is %d\n", recode->ID, recode->Name, recode->Num);
}
//输入对于ID,Num时,修改对于设备数量,并写回二进制文件中
void update(Recode recode[], int count, const char* filename)
{
	int ID, Num;
	long position;
	printf("输入ID和Num\n");
	scanf("%d%d", &ID, &Num);
	for (int i = 0; i < count; i++)
	{
		if (recode[i].ID == ID)
		{
			recode[i].Num = Num;
			position = i;
			break;
		}
	}
	FILE* fp = fopen(filename, "wb");//直接重写,免得定位
	if (!fp)
	{
		perror("打开文件出错\n");
		return;
	}
	//更新记录
	if (fwrite(recode, sizeof(Recode), 1, fp))//fwrite成功返回写入的个数
	{
		printf("文件写入失败\n");
	}
	fclose(fp);
}


int main()
{
	Recode recode[RECODE_SIZE];
	int count = readfalicity(recode, "falicity.data");
	printf("输入ID用来修改Num\n");
	int ID;
	scanf("%d", &ID);
	for (int i = 0; i < count; i++)
	{
		displayRecode(&recode[i]);
	}
	update(recode, count, "falicity.data");
	return 0;
}
      
		

解决思路和难点

这里是描述解决思路的