电话号码管理--链表的简单使用

电话号码管理



综述

电话号码管理项目功能包括简易菜单、单链表、包括增删改查等基本操作。链表插入采用尾插法。

链表结构

每个节点中内容:

  • id id号码
  • name 姓名
  • phone_number 电话号码
  • home_address 家庭地址
  • company_address 公司地址

在这里插入图片描述

init

int init(PHONE **head)
{
    PHONE *newnode = (PHONE *)malloc(sizeof(PHONE));
    if(NULL == newnode)
    {
    return -1;
    }
    //newnode->value = 0;
    newnode->next = NULL;
    *head = newnode;
    return 0;
}

这段代码是一个函数,名称为 init,它接收一个指向 PHONE 指针的指针,用于指向一个链表的头节点。

这个函数首先使用 malloc 分配一个新的 PHONE 节点,如果分配失败,则返回 -1。

接着,这个函数初始化新节点的值为 0,将 next 指针设置为 NULL。

最后,将链表头节点指针指向新节点,即将 *head 设置为 newnode。

这个函数返回 0 表示初始化成功。

create

int create(PHONE *head)
{
    PHONE *p;
    p = head;
    PHONE *newstudent = (PHONE *)malloc(sizeof(PHONE));
    if(NULL == newstudent)
    {
        return -1;
    }
    。。。。
      newstudent->next = NULL;
    while(head->next != NULL)
    {
        head = head->next;
    }
    head->next = newstudent;
    。。。。
    head = p;
}

这段代码是一个函数,名称为 create,它接收一个指向链表头节点的 PHONE 指针。

这个函数首先将指针 p 指向链表头节点 head,以便在后面将链表头节点指针传递回来。

然后,使用 malloc 分配一个新的 PHONE 节点 newstudent,如果分配失败,则返回 -1。

接着,初始化新节点的值,并将 next 指针设置为 NULL。

接下来的代码是在链表的尾部插入新节点,它使用一个循环将指针 head 移动到链表的末尾,即指向最后一个节点。

最后,将新节点插入链表的末尾,即将 head 指向的节点的 next 指针指向新节点。

最后,将指针 head 指向链表头节点,以便将链表头节点指针传递回来。

注意,该函数返回类型为 int,但是没有返回值。如果在分配新节点时发生错误,则返回 -1,否则函数将正常返回。

delete

int delete(PHONE *head)
{
    PHONE *p;
    p = head;
    char name[20];
。。。。。。

    while(head->next != NULL)
    {
    if(strcmp(head->next->name,name) == 0)
    {
        count++;
       PHONE *ptr = head->next;
        head->next = ptr->next;
        free(ptr);
    }
。。。。。

    head = p;
    printf("\n");
    return 0;
    
}

这段代码中的循环用于遍历链表,查找匹配输入的姓名的节点。

具体地,使用条件判断语句 while 和表达式 head->next != NULL 循环遍历链表,当 head 指向的节点不为 NULL 时,执行循环体内的代码。

循环体内部的条件判断语句 if 判断链表中下一个节点的姓名是否与输入的 name 相等,如果相等,则执行删除操作。

删除操作首先将指针 ptr 指向需要删除的节点,然后将链表中该节点的前一个节点的 next 指针指向该节点的后一个节点,即删除该节点。

最后,释放节点内存,将 head 指针指向下一个节点,继续循环遍历链表,直到遍历完整个链表。

在循环结束后,将指针 head 指向链表头节点,以便将链表头节点指针传递回来。

函数返回 0 表示删除成功。注意,该函数删除的是第一个匹配的节点,如果有多个节点匹配,则只删除第一个匹配的节点。如果链表中没有匹配的节点,则函数将正常返回。

allfree

PHONE *allfree(PHONE *head)
{
    while(head->next != NULL)
    {
        PHONE *ptr = head;
        head = head->next;
        free(ptr);
    }
    free(head);
    head = NULL;
    return head;
}

这段代码用于释放链表中所有节点占用的内存,同时将链表头节点指针置为 NULL。

具体地,使用条件判断语句 while 和表达式 head->next != NULL 循环遍历链表,当 head 指向的节点不为 NULL 时,执行循环体内的代码。

循环体内部的操作首先将指针 ptr 指向当前节点,然后将 head 指针指向下一个节点,最后释放节点内存。

在循环结束后,需要释放链表头节点占用的内存,然后将链表头节点指针置为 NULL。

最后,函数返回 NULL 指针,以便将链表头节点指针传递回来。

需要注意的是,该函数在释放内存时,必须保证链表中至少有一个节点。如果链表为空,或者链表中只有一个节点,需要特殊处理。如果链表中只有一个节点,释放内存后,需要将链表头节点指针置为 NULL,否则会出现野指针的问题。

ANSI颜色转义

printf("\033[1;33m Hello World. \033[0m \n");  

颜色列表如下:

none         = "\033[0m"  
black        = "\033[0;30m"  
dark_gray    = "\033[1;30m"  
blue         = "\033[0;34m"  
light_blue   = "\033[1;34m"  
green        = "\033[0;32m"  
light_green -= "\033[1;32m"  
cyan         = "\033[0;36m"  
light_cyan   = "\033[1;36m"  
red          = "\033[0;31m"  
light_red    = "\033[1;31m"  
purple       = "\033[0;35m"  
light_purple = "\033[1;35m"  
brown        = "\033[0;33m"  
yellow       = "\033[1;33m"  
light_gray   = "\033[0;37m"  
white        = "\033[1;37m"  

字背景颜色范围:40–49 字颜色: 30–39

40:30:41:31:42:绿                          32: 绿  
43:33:44:34:45:35:46:深绿                        36: 深绿  
47:白色                        37: 白色  

输出特效格式控制:

\033[0m  关闭所有属性    
\033[1m   设置高亮度    
\03[4m   下划线    
\033[5m   闪烁    
\033[7m   反显    
\033[8m   消隐    
\033[30m   --   \033[37m   设置前景色    
\033[40m   --   \033[47m   设置背景色  

光标位置等的格式控制:

\033[nA  光标上移n行    
\03[nB   光标下移n行    
\033[nC   光标右移n行    
\033[nD   光标左移n行    
\033[y;xH设置光标位置    
\033[2J   清屏    
\033[K   清除从光标到行尾的内容    
\033[s   保存光标位置    
\033[u   恢复光标位置    
\033[?25l   隐藏光标    
\33[?25h   显示光标

Makefile

在这里插入图片描述
在这里插入图片描述

顶层Makefile

include scripts/Makefile
#包含 
scripts/Makefile 文件。它可能包含其他变量、目标和规则,以及其他可能需要在此Makefile中使用的脚本和功能。
modules_make = $(MAKE) -C $(1);
modules_clean = $(MAKE) clean -C $(1);
#这些是两个变量,用于执行每个模块的make命令和clean命令。这些变量可以通过参数传递需要操作的模块的名称。
.PHONY: all mm mc clean
#这是一个特殊目标,告诉Make,这些目标不是文件名,而是伪目标。它告诉Make无论如何都要执行它们。
all: $(Target)
#这是一个目标,告诉Make要构建$(Target)。它将在mm目标后执行。
mm:
    @ $(foreach n,$(Modules),$(call modules_make,$(n)))
#这是一个目标,用于执行每个模块的make命令。它使用foreach循环来迭代所有的模块名称,并通过modules_make变量调用make命令。
mc:
    @ $(foreach n,$(Modules),$(call modules_clean,$(n)))
#这是一个目标,用于执行每个模块的clean命令。它使用foreach循环来迭代所有的模块名称,并通过modules_clean变量调用clean命令。
$(Target) : mm
    $(CC) $(CFLAGS) -o $(Target) $(AllObjs) $(Libs)
    @ echo $(Target) make done!
#这是一个目标,告诉Make要构建$(Target)。它在mm目标完成后执行。它使用$(CC)编译器,$(CFLAGS)编译选项和$(Libs)链接库来编译所有的目标文件,并将它们链接成可执行文件。
clean : mc
    rm -rf $(Target)
    @ echo clean done!
#这是一个目标,告诉Make清理项目。它在mc目标完成后执行。它使用rm命令来删除$(Target)和其他生成的文件。
#这些是命令,用于输出构建和清理操作完成的消息。前面的@符号告诉Make不要输出命令本身,只输出命令的结果。

scripts Makefile

CC := gcc
CFLAGS := -Wall -O3
Libs = -lpthread
Target := phone
Source := $(wildcard ./*.c)
Objs := $(patsubst %.c,%.o,$(Source))
Modules += allfree create delete display init login menu  search   main
AllObjs := $(addsuffix /*.o,$(Modules))

Makefile 文件中包含了一些特殊的变量和命令,可以指导 Make 工具根据代码的依赖关系自动化构建程序。

在这段代码中,首先定义了一些变量:

  • CC:C 编译器名称;
  • CFLAGS:编译器选项,包括 -Wall 和 -O3;
  • Libs:需要链接的库文件,这里是线程库;
  • Target:目标程序名,这里是 phone;
  • Source:所有源文件的路径和名称;
  • Objs:所有对象文件的路径和名称,通过把源文件的扩展名 .c 替换为 .o 得到;
  • Modules:项目中所有模块的名称,这里是 allfree、create、delete、display、init、login、menu、search 和 main;
  • AllObjs:所有模块的对象文件路径和名称,通过在模块名后加上 /* 和 .o 得到。

接下来是一些命令,以及命令的依赖关系和规则:

  • .PHONY:声明了一个伪目标,表示这些目标不是实际存在的文件,只是用来作为 make * 的执行目标;
  • all:构建目标程序 phone,依赖于所有对象文件 $(Objs) 和链接库 $(Libs);
  • $(Target):生成目标程序 phone,依赖于所有对象文件 $(Objs) 和链接库 $(Libs);
  • $(Objs):编译所有源文件 $(Source),每个源文件对应一个对象文件;
  • $(Modules):每个模块都要编译成一个对象文件,依赖于对应的源文件;
  • clean:删除所有对象文件 $(Objs) 和目标程序 $(Target)。
    通过执行 make 命令,根据 Makefile 文件中的定义,自动编译源代码,并生成目标程序。

search main init include display delete create allfree 目录下Makefile

include ../scripts/Makefile

all : $(Objs)

clean : 
    rm -rf $(Objs)

这是一个简单的 Makefile,它包含另一个 Makefile,该 Makefile 位于 scripts 目录中(假定为父目录级别),并定义了两个目标,all 和 clean。

all 目标依赖于目标文件($(Objs)),并仅构建它们。实际的构建命令没有在此 Makefile 片段中显示,但应该在包含的 Makefile(…/scripts/Makefile)中定义。

clean 目标删除目标文件

result

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦梨甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值