一直以来个人对C语言的困惑
- 函数指针数组
- 转移表
- 字符串操作
这次的问题解决是源自于这次的作业 通讯录
的反复尝试
先把这个通讯录代码贴上
#define _CRT_SECURE_NO_WARNINGS
#define MAX_Capacity 300
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"function.h"
typedef struct Meg{
char name[1024]; //这里的char name; 是不对的,必须要是要是char name[1024]
// 同时定义成指针也是错误的,char *name ,这时的
char num[1024];
char gender[1024];
}Meg;
struct Meg_arr{
Meg arr[MAX_Capacity];
int size;
}Addrss,*Addr_point;
void inint(){
Addrss.size = 0;
for (int i = 0; i < MAX_Capacity; i++){
Addrss.arr[i].name[0] = '\0';
Addrss.arr[i].num[0] = '\0';
Addrss.arr[i].gender[0] = '\0';
}
}
int Menu(){
printf(" 通讯录 \n");
printf("*****************\n");
printf("1.新增联系人\n");
printf("2.删除联系人\n");
printf("3.查找联系人\n");
printf("4.修改联系人\n");
printf("5.打印全部联系人\n");
printf("6.排序联系人\n");
printf("7.清空联系人\n");
printf("8.退出\n");
printf("*****************\n");
printf("请输入你的选择\n");
int choose_01;
while (1){
scanf("%d", &choose_01);
if (choose_01 >= 1 && choose_01 <= 8){
break;
}else{
printf("输入有误!!请重新输入\n");
}
}
return choose_01;
}
void AddPerson(){
system("cls");
printf("增加联系人\n");
/*Meg* ptr = &Addrss.arr[Addrss.size]; TODO 问题一
scanf("%s",ptr->name);*/
int i = Addrss.size;
printf("请输入姓名:");
scanf("%s", &Addrss.arr[i].name);
printf("请输入手机号:");
scanf("%s", &Addrss.arr[i].num);
printf("请输入性别:");
scanf("%s", &Addrss.arr[i].gender);
Addrss.size += 1; // Addr_point->arr += 1;; 和 (Addr_point->size) += 1 这两个地方不能用指针
printf("增加联系人完毕\n");
system("pause");
}
void DelectPerson(){
system("cls");
char* name_ptr;
char name[1024];
PrintAll();
printf("删除联系人\n");
if (Addrss.size > 0){
printf("输入你要删除的联系人姓名:\n");
scanf("%s", &name);
//name_ptr = &name[0];
for (int i = 0; i < Addrss.size; i++){
if (strcmp(Addrss.arr[i].name, name) == 0){
for (; i < Addrss.size; i++){
strcpy(Addrss.arr[i].name, Addrss.arr[i + 1].name);
strcpy(Addrss.arr[i].num, Addrss.arr[i + 1].num);
strcpy(Addrss.arr[i].gender, Addrss.arr[i + 1].gender);
}
Addrss.size -= 1;
printf("修改完毕!!!\n");
break;
}
else{
//printf("没有这个人,即将推出...."); // TODO Bug +1
}
}
}
else{ printf("没有联系人!!\n"); }
system("pause");
}
void FindPerson(){
char name[1024];
system("cls");
printf("查找联系人\n");
PrintAll();
printf("输入你要查找的联系人:\n");
scanf("%s", &name);
for (int i = 0; i < Addrss.size; i++){
if (strcmp(Addrss.arr[i].name,name)==0){
printf("序号\t姓名\t\t电话号码\t性别\n");
printf("[%d]\t%s\t\t%s\t%s\t\n", i + 1, Addrss.arr[i].name, Addrss.arr[i].num, Addrss.arr[i].gender);
break;
}
else{
//printf("没有这个人\n"); TODO Bug +2
}
}
system("pause");
}
void UpData(){
char name[1024];
system("cls");
printf("修改联系人\n");
printf("输入你要修改的联系人\n");
scanf("%s", name);
for (int i = 0; i < Addrss.size; i++){
if (Addrss.arr[i].name == name){
printf("序号\t姓名\t\t电话号码\t性别\n");
printf("[%d]\t%s\t\t%s\t%s\t\n", i + 1, Addrss.arr[i].name, Addrss.arr[i].num, Addrss.arr[i].gender);
printf("请输入修改的信息\n");
printf("请输入姓名:");
scanf("%s", &Addrss.arr[i].name);
printf("请输入手机号:");
scanf("%s", &Addrss.arr[i].num);
printf("请输入性别:");
scanf("%s", &Addrss.arr[i].gender);
printf("修改完成!!\n");
}
else{
//printf("没有这个人\n"); TODO Bug +3
//printf("修改联系人失败\n");
}
}
system("pause");
}
void PrintAll(){
system("cls");
printf("序号\t姓名\t\t电话号码\t性别\n");
for (int i = 0; i < Addrss.size; i++){
printf("[%d]\t%s\t\t%s\t\t%s\t\n",i+1,Addrss.arr[i].name,Addrss.arr[i].num,Addrss.arr[i].gender);
}
//printf("打印全部联系人完毕\n");
system("pause");
}
void SortPerson(){
system("cls");
printf("排序联系人\n");
for (int i = 0; i < Addrss.size; i++){
for (int j = 0; j < Addrss.size - i- 1;j++)
if (strcmp(Addrss.arr[j].name, Addrss.arr[j + 1].name)>0){
Change(&Addrss.arr[j],&Addrss.arr[j+1]); //TODO 函数
}
}
PrintAll();
system("pause");
}
void Change(Meg *fornt,Meg *end){
char tmp[1024];
strcpy(tmp,end->name);
strcpy(end->name, fornt->name);
strcpy(fornt->name,tmp );
strcpy(tmp,end->num);
strcpy(end->num, fornt->num);
strcpy(fornt->num,tmp );
strcpy(tmp,end->gender);
strcpy(end->gender, fornt->gender);
strcpy(fornt->gender,tmp );
}
void ClearPerson(){
system("cls");
char ans;
printf("是否要全部清空联系人?Y/N\n");
while(1){
scanf("%c",&ans);
if (ans == 'Y'){
inint();
break;
}else if (ans =='N'){
printf("放弃清空!\n");
break;
}
else {
printf("请重新输入\n");
}
}
system("pause");
}
void Empety(){
//占位函数G
}
typedef void(*Func)();
Func arr[] = {
Empety,
AddPerson,
DelectPerson,
FindPerson,
UpData,
PrintAll,
SortPerson,
ClearPerson
};
int main(void){
while (1){
int choose_00 = Menu();
if (choose_00 == 8){
printf("通讯录退出\n");
break;
}
arr[choose_00]();
system("cls");
}
return 0;
}
以上程序的主文件, 当然还有下面的头文件
#pragma once // 只加载一次函数定义
void Empety();
int Menu();
void AddPerson();
void DelectPerson();
void FindPerson();
void UpData();
void PrintAll();
void SortPerson();
void ClearPerson();
void Change();
头文件必不可少
第一谈 关于函数指针数组
typedef void(*Func)();
Func arr[] = {
Empety,
AddPerson,
DelectPerson,
FindPerson,
UpData,
PrintAll,
SortPerson,
ClearPerson
};
这里的typedef void(*Func)();
就是定义了一个无指向的函数指针,并且将这个指针重定义成 Func类型
第二谈 关于转移表
转移表的应用源自于为了减小if else 的分叉使用,使用数组的结构减小来广域.转移表的使用很好的解决了…
第三谈 关于字符串的变更和初始化
- 这里尤其小心C语言中的字符串操作,在使用指针变化时可以当做字符组组操作,当然使用strcpy也是一种比较好用方式
void Change(Meg *fornt,Meg *end){
char tmp[1024];
strcpy(tmp,end->name);
strcpy(end->name, fornt->name);
strcpy(fornt->name,tmp );
strcpy(tmp,end->num);
strcpy(end->num, fornt->num);
strcpy(fornt->num,tmp );
strcpy(tmp,end->gender);
strcpy(end->gender, fornt->gender);
strcpy(fornt->gender,tmp );
}
这里的strcpy及很方便的解决字符数组反复定义的问题