今天向大家介绍一个利用C语言实现通讯录的过程。

通讯录相信大家都听说过,存放一个人的信息,用来方便联系。下图为我们即将实现通讯录的功能:


图中已经描述的很清楚了,这个通讯录的容量为1000,所录入的信息包括名字、电话、地址、QQ、性别和年龄这五个部分。该通讯录有7个功能,增加、删除、查找、修改、排序、展示和退出。下面就来介绍用C语言来实现的过程。

首先我们还是在一个项目中创建三个文件,两个源文件,一个文件存放主函数,一个文件来存放通讯录的实现函数,还有一个头文件来声明函数。

声明模块

接下来我们来看头文件部分,看看到底声明了哪些东西:
代码如下:

#include <stdio.h>
#include <string.h>#define MAX 1000#define MAX_NAME 20
#define MAX_TELE 12
#define MAX_ADDR 100
#define MAX_QQ 12
#define MAX_SEX 5typedef struct PeoInfo
{char name[MAX_NAME];char tele[MAX_TELE];char addr[MAX_ADDR];char qq[MAX_QQ];char sex[MAX_SEX];int age;
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[MAX];//数据int sz;//有效个数
}Contact;//添加一个人的信息
void add_contact(Contact* pc);//显示通讯录中的信息
void show_contact(Contact* pc);//删除指定的联系人
void del_contact(Contact* pc);//查找指定联系人
void search_contact(Contact* pc);//修改指定联系人
void modify_contact(Contact* pc);//排序通讯录的数据
void sort_contact(Contact* pc);

首先两个头文件,都是老熟人了,相信大家肯定十分熟悉了。

接下来定义了一串常量,这些常量下面马上就会用到。

然后定义了一个结构体PeoInfo,简单分析不难发现,这个结构体表示的就是一个人的信息。姓名、电话、地址、QQ、性别这几条信息存放在一个字符数组中,年龄是int类型。前面我们定义的这些常量代表的就是这些字符数组的内存大小。比如char name[MAX_NAME ], 前面我们已经定义了,MAX_NAME的值为20,这就代表这个字符数组有20个元素,占20个字节,也就是说我们所输入人的名字所占内存的大小为20个字节。当然,如果想要调整这个大小,直接改变上面define定义常量的值即可。这也是为什么我们要在前面用define定义一串常量的原因。

下面我们又定义了一个结构体Contact,这个结构体有两个成员,一个是结构体数组,数组中的每个元素就是上面创建的结构体。还有一个元素是整型变量sz。上一个结构体代表的是一个人的信息,而通讯录的目的就是把多个人的信息存放在一起,所以这个结构体Contact所代表的的就是我们的通讯录。这里大家可能疑惑存放人的信息,只用一个结构体数组不就搞定了吗,这里还把它和一个整型变量封装在一起有什么用呢?

当然是有用的,这个整型变量代表的是通讯录中所录入人的有效个数,下面我们在实现通讯录功能的时候大家就会知道它的作用了。

接下来就是通讯录功能实现函数的声明,这些函数我会作为本篇博客的重点来向大家介绍。

主函数模块

看完头文件部分,接下来我们来看主函数部分的代码
代码如下:

#include "contact.h"void menu()
{printf("*******************************\n");printf("****** 1. add     2. del  * ***\n");printf("****** 3. search  4. modify ***\n");printf("****** 5. sort    6. show   ***\n");printf("******       0. exit        ***\n");printf("*******************************\n");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SORT,SHOW
};int main()
{//创建的通讯录Contact con = { 0 };int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case ADD:add_contact(&con);break;case DEL:del_contact(&con);break;case SORT:sort_contact(&con);break;case SHOW:show_contact(&con);break;case SEARCH:search_contact(&con);break;case MODIFY:modify_contact(&con);break;case EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

第一行引用我们前面放声明部分的头文件,这样我们就能把头文件里所声明的内容拿过来用了。

下面我们直接来看main函数里的内容。

首先我们要创建一个通讯录,前面我们说了,结构体Contact代表的是通讯录,这里我们创建一个通讯录变量con.

然后是一个do while循环,do while循环和while循环最大的不同就是它的判断语句在do while函数调用后进行判断,也就是说它最少会执行一次,执行完之后才会判断下次要不要继续执行。这种机制正好完美的符合通讯录的功能。因为当别人要使用通讯录的时候,我们就必然要先给别人提供选项供使用者选择,也就是说通讯录必须使用一次,所以这里我们采用do while循环。

进入do while循环内部,先打印一个菜单,菜单函数的内容就在do while语句上面放着,这个函数的目的仅仅就是打印一个菜单供我们选择功能,不需要传参,也不需要返回值。接下来向大家展示一下这个菜单的打印效果:

这就是向我们展示的菜单,继续往下分析。

接下来提示使用者就可以进行选择,根据菜单的提示来输入想要输入的数字。

拿到输入的选项后,紧接着进入一个switch语句中,根据所输入的选项来调用相应的函数,实现对应的功能。这里大家肯定发现了,我们输入的选项是一个数字,而case语句中的选项是一个单词,这又是怎么一回事。这些单词实际上是我们在main函数上方定义的枚举常量,枚举常量的第一个变量默认值为0,然后从第二个变量开始的值依次加1.也就是说EXIT的值为0,ADD的值为1,DEL的值为2,正好和菜单的功能相对应。这里肯定有人要问了,为什么不直接去写1234这些数字呢?这里采用枚举变量的目的实际上就是为了增加代码的可读性,写数字的话功能多了就会分不清,而定义一个枚举常量就可以清楚的看到switch case语句实现了那些功能。

当我们输入0之后,do while循环就会结束。大家注意while的判断框中就是变量input,也就是我们输入的值。当我们输入其他值是,判断为真,do while语句就会一直执行下去,一直实现通讯录的功能。而当输入0之后,判断为假,do while循环结束,这次通讯录的使用也就完了。

功能模块

好了接下来我们就来分析通讯录功能模块的内容。通讯录的每一个功能都是封装在一个函数中的,然后这些函数我们是放在另一个源文件中的,这样做的目的很明确了,就是为了增加代码的可读性,便于修改代码。

功能1:增加

接下来我们来看通讯录的第一个功能增加:

代码如下:

void add_contact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满\n");}else{printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入QQ:>");scanf("%s", pc->data[pc->sz].qq);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age));pc->sz++;printf("添加成功\n");}
}

先分析函数声明部分,首先这个函数不需要返回值。接收的参数应该是我们在main函数中所创建的结构体变量。这里需要注意,我们在传参的时候,不要传结构体变量,而是传结构体的指针。因为结构体变量的第二个参数是记录当前有效人的信息,所以当我们通过函数增加或者删除掉一个人之后,我们希望能够改变结构体中有效人数的值。而传递结构体,结构体形参只是实参的一份临时拷贝,改变形参并不会改变实参的值,所以这里我们需要传递结构体的地址。

增加函数开始执行前我们先要判断,通讯录中有效人信息量是否已经达到了通讯录的容量,我们在头文件中设置的通讯录容量为1000,当然这个是可以修改的。如果判断容量已满,则不再增加,判断未满那就继续增加。

增加一个人的信息实现起来很简单,就是给一个结构体赋值的过程,赋值完成之后给有效人数加1,就可以完成这次增加操作了。

功能6:展示

为了能够很好的给大家展示每一步操作的完成,接下来我们先来实现通讯录第六个功能,展示。

代码如下:

void show_contact(Contact* pc)
{int i = 0;printf("%10s %12s %20s %5s %12s %5s\n", "名字", "电话", "地址", "年龄", "QQ", "性别");for (i = 0; i < pc->sz; i++){printf("%10s %12s %20s %5d %12s %5s\n", pc->data[i].name,pc->data[i].tele,pc->data[i].addr,pc->data[i].age,pc->data[i].qq,pc->data[i].sex);}
}

展示函数接收的参数和返回类型和增加函数是一样的。

打印通讯录内容之前我们先打印一个表头,就像Excel的表头一样,目的是方便查找。打印的时候我们可以估算一下各个信息的长度,然后打印。%10s的意思就是打印的空间占10个字符型空间。

由于通讯录中可能有多条信息,所以打印的时候采用一个循环来打印,打印的次数就是有效信息数sz的值。打印的方法使用的是结构体基础知识,结构体成员的访问,这里就不再多提了。

然后联合上一条增加函数向大家展示一次增加后的结果:

选择1输入一个人的信息,再选择6展示通讯录内容,最后选择0退出通讯录。

功能2:删除

接下来我们再来实现第二个功能,删除。

大家想一下,当我们在删除一个成员的时候,是不是应该先输入我们要删除的成员某一个信息,比如姓名,然后再拿输入的这个信息来和通讯录里已存的信息来比较,当找到这条信息之后再进行删除操作。

也就是说在删除之前我们要先进行一次查找已有信息的操作。这里我们再把目光往长远看一点,后面的查找是不是也要查找一个人的信息,而修改也要查找一个人的信息。也就是说这个查找功能好几个函数都要用到,于是我们把这个查找功能封装在通讯录功能源文件内部,这个函数不需要向外部声明,因为仅仅只是在通讯录源文件内部使用。

查找一个人信息函数代码如下:

static int find_peo_by_name(Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(name, pc->data[i].name) == 0){return i;//找到了,返回下标}}return -1;//找不到
}

因为这个函数我们不用让外面看到,所以用static来修饰这个函数,这样的话这个函数就只能在该源文件内部使用。该函数接收两个参数,一个是通讯录结构体,一个是要查找的成员名称。

查找的过程采用遍历的方式,让通讯录中的每一个成员的名字来和要查找的成员名字来作比较,这里用到字符串比较函数strcmp,这里简单提一下,当这两个字符串相等时,该函数返回值为0,第一个大于第二个返回一个大于0的值,小于则返回一个小于0的值。当判断函数的返回值等于0时,说明找到了要查找的元素,紧接着返回该元素的下标。如果找不到返回-1即可。

找到成员之后,接下来我们来考虑怎么删除成员。删除的过程我们是这样实现的,假如这里有六个成员123456.此时要删除成员3,我们把3所在的空间用4覆盖,再把4所在的空间用5覆盖,5所在的空间用6覆盖。然后把成员数删除一个,此时只剩下五个成员,所以6原来所在的空间就不会被放到该通讯录中了。

实现代码如下:

void del_contact(Contact* pc)
{if (pc->sz == 0){printf("抱歉,通讯录为空\n");}else{char name[MAX_NAME] = { 0 };printf("请输入要删除人的名字:>");scanf("%s", name);//1. 找到指定的联系人的位置int pos = find_peo_by_name(pc, name);if (pos == -1){printf("很遗憾,删除的人不存在\n");}else{//2. 删除int j = 0;for (j = pos; j < pc->sz - 1; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("删除成功\n");}}
}

首先我们要判断通讯录中是否有成员,如果没有成员,那么也就没有必要查找元素删除了,直接提示该通讯录内容为空。

当判断有成员之后,我们先输入要删除成员的名字,然后调用查找函数找到这个成员并且返回它的下标,如果没找到就提示没找到,如果找到了我们就来进行删除操作。

这里的变量pos是所找到成员的下标,然后通过一个循环来进行成员覆盖。这里我们来判断一下循环次数,假如按照我上面举的例子,123456,要删除3,返回下标是pos = 2,而我们要覆盖的次数是3次,这里我们知道通讯录的成员个数是sz,所以sz-pos-1就是我们要循环的次数了。定义初始变量为pos,判断语句为sz-1,正好循环sz-pos-1次。

删除操作就是结构体的赋值,很容易理解。

删除完之后记得要给成员数sz减1,要不然最后一个成员的内容还在那放着。

看一下效果,我们先输入三个人的信息,并且展示出来:

然后选择2删除第二个人李四的信息并展示:

可以看到成功的删除了李四的信息。

功能3:查找

接下来我们再来看第三个功能,查找。

前面我们已经写了一个寻找成员的函数,查找函数中我们依然可以来调用。

代码如下:

void search_contact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);int pos = find_peo_by_name(pc, name);if (pos == -1){printf("查无此人\n");}else{printf("%10s %12s %20s %5s %12s %5s\n","名字", "电话", "地址", "年龄", "QQ", "性别");printf("%10s %12s %20s %5d %12s %5s\n", pc->data[pos].name,pc->data[pos].tele,pc->data[pos].addr,pc->data[pos].age,pc->data[pos].qq,pc->data[pos].sex);}
}

先输入要查找人的姓名,然后调用查找函数,观察返回值,如果找不到,就打印查无此人。如果找到,返回这个人的下标,我们就可以通过这个人的下标来把这个人的信息展示出来。打印的方法和上面写的展示函数方法是一样的。

接下来我们来查找王五的信息:

可以看到成功的找到王五,并且将它的信息打印了出来。

功能4:修改

下面来看第四个功能,修改:

修改开始前和删除是一样的,首先要找到修改的元素,这里使用的还是前面所写的查找函数,判断它的返回值。

找到之后再进行修改。
代码如下:

void modify_contact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = find_peo_by_name(pc, name);if (pos == -1){printf("查无此人\n");}else{printf("请输入新的名字:>");scanf("%s", pc->data[pos].name);printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);printf("请输入新的QQ:>");scanf("%s", pc->data[pos].qq);printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);printf("请输入新的年龄:>");scanf("%d", &(pc->data[pos].age));}
}

修改的方法其实就是给要修改成员所在的内存重新赋值,方法和前面增加的方法是一样的,只不过这里我们直接拿到了要赋值成员的下标,于是直接通过下标就可以赋值了。

修改之后展示结果如下:

可以看到成功的将其张三的信息修改成立韩六的信息。

功能6:排序

接下来我们就来看最后一个功能,排序。

排序同样,我们要根据成员的某一个信息来排序,这里还是使用姓名来排序。排序方法采用我们最常见的冒泡排序,升序排列。

这里可能有人会疑惑了,姓名是汉字怎么排序,这里告诉大家,C语言识别汉字的时候是按照它的拼音来识别的,也就是一组字符串。字符串大小的比较就是使用前面我提到过的strcmp函数,比较的是这些字符串的ASCII码值。第一个大于第二个字符串返回大于0的数,小于返回小于0的数,等于返回0.

代码如下:

void sort_contact(Contact* pc)
{int i = 0;int j = 0;for (i = 0; i < pc->sz - 1; i++){int flag = 1;//假设已经有序for (j = 0; j < pc->sz - 1 - i; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){PeoInfo tmp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = tmp;flag = 0;}}if (1 == flag){break;}}
}

冒泡排序的思想相信大家非常常见了,这里我就不再多提了。如果有人还不熟悉,我在前面专门写过一篇有关冒泡排序的文章,大家可以参考一下。

排序的结果:

可以看到成功对三个成员进行了排序。

以上就是C语言实现通讯录的全部过程和分析,当然这个程序还是可以增加很多功能的,今天我就介绍这么几种。还有一点不足的就是,这个通讯录只能使用一次,当然,当大家的知识储备越来越多的时候,我们就可以写出更完善的通讯录了。其实可以看到,通讯录实现起来虽然十分复杂,但实际上使用的内容都是我们C语言基础的知识,所以只要大家基础扎实,多加练习,以后一定可以熟练的完成这种复杂问题的实现。

希望这篇文章能够帮助到大家。

最后将完整的代码留给大家,以供参考:

text.c

#include "contact.h"void menu()
{printf("*******************************\n");printf("****** 1. add     2. del  * ***\n");printf("****** 3. search  4. modify ***\n");printf("****** 5. sort    6. show   ***\n");printf("******       0. exit        ***\n");printf("*******************************\n");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SORT,SHOW
};int main()
{//创建的通讯录Contact con = { 0 };int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case ADD:add_contact(&con);break;case DEL:del_contact(&con);break;case SORT:sort_contact(&con);break;case SHOW:show_contact(&con);break;case SEARCH:search_contact(&con);break;case MODIFY:modify_contact(&con);break;case EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

Contact.c

#include "contact.h"void add_contact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满\n");}else{printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入QQ:>");scanf("%s", pc->data[pc->sz].qq);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age));pc->sz++;printf("添加成功\n");}
}void show_contact(Contact* pc)
{int i = 0;printf("%10s %12s %20s %5s %12s %5s\n", "名字", "电话", "地址", "年龄", "QQ", "性别");for (i = 0; i < pc->sz; i++){printf("%10s %12s %20s %5d %12s %5s\n", pc->data[i].name,pc->data[i].tele,pc->data[i].addr,pc->data[i].age,pc->data[i].qq,pc->data[i].sex);}
}static int find_peo_by_name(Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(name, pc->data[i].name) == 0){return i;//找到了,返回下标}}return -1;//找不到
}void del_contact(Contact* pc)
{if (pc->sz == 0){printf("抱歉,通讯录为空\n");}else{char name[MAX_NAME] = { 0 };printf("请输入要删除人的名字:>");scanf("%s", name);//1. 找到指定的联系人的位置int pos = find_peo_by_name(pc, name);if (pos == -1){printf("很遗憾,删除的人不存在\n");}else{//2. 删除int j = 0;for (j = pos; j < pc->sz - 1; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("删除成功\n");}}
}void search_contact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);int pos = find_peo_by_name(pc, name);if (pos == -1){printf("查无此人\n");}else{printf("%10s %12s %20s %5s %12s %5s\n","名字", "电话", "地址", "年龄", "QQ", "性别");printf("%10s %12s %20s %5d %12s %5s\n", pc->data[pos].name,pc->data[pos].tele,pc->data[pos].addr,pc->data[pos].age,pc->data[pos].qq,pc->data[pos].sex);}
}void modify_contact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = find_peo_by_name(pc, name);if (pos == -1){printf("查无此人\n");}else{printf("请输入新的名字:>");scanf("%s", pc->data[pos].name);printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);printf("请输入新的QQ:>");scanf("%s", pc->data[pos].qq);printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);printf("请输入新的年龄:>");scanf("%d", &(pc->data[pos].age));}
}void sort_contact(Contact* pc)
{int i = 0;int j = 0;for (i = 0; i < pc->sz - 1; i++){int flag = 1;//假设已经有序for (j = 0; j < pc->sz - 1 - i; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){PeoInfo tmp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = tmp;flag = 0;}}if (1 == flag){break;}}
}

Contact.h

#include <stdio.h>
#include <string.h>#define MAX 1000
#define MAX_NAME 20
#define MAX_TELE 12
#define MAX_ADDR 100
#define MAX_QQ 12
#define MAX_SEX 5typedef struct PeoInfo
{char name[MAX_NAME];char tele[MAX_TELE];char addr[MAX_ADDR];char qq[MAX_QQ];char sex[MAX_SEX];int age;
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[MAX];//数据int sz;//有效个数
}Contact;//添加一个人的信息
void add_contact(Contact* pc);//显示通讯录中的信息
void show_contact(Contact* pc);//删除指定的联系人
void del_contact(Contact* pc);//查找指定联系人
void search_contact(Contact* pc);//修改指定联系人
void modify_contact(Contact* pc);//排序通讯录的数据
void sort_contact(Contact* pc);

【C语言】- 通讯录实现详解相关推荐

  1. (转)C语言位运算详解

    地址:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html C语言位运算详解 作者:911 说明:本文参考了http://www2.ts ...

  2. R语言基础知识详解及概括

    R语言基础知识详解及概括 目录 R语言基础知识详解及概括 R数据可视化示例 R语言进行数据创建

  3. c语言练习题及答案)(1),c语言练习题(带详解答案)1.pdf

    c语言练习题(带详解答案)1 (-2) -1: 一单项选择题 /为求商运算符,该运算符能够对整型.字符.浮点等类型的数 据进行运算,5/2 2 1.(A )是构成C语言程序的基本单位. 11.如果 i ...

  4. python语言的格式框架_django框架模板语言使用方法详解

    本文实例讲述了django框架模板语言使用方法.分享给大家供大家参考,具体如下: 模板功能 作用:生成html界面内容,模版致力于界面如何显示,而不是程序逻辑.模板不仅仅是一个html文件,还包括了页 ...

  5. C语言再学习 -- 详解C++/C 面试题 2

    (经典)C语言测试:想成为嵌入式程序员应知道的0x10个基本问题. 参看:嵌入式程序员面试问题集锦 1.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define ...

  6. python自动解析json_Python语言解析JSON详解

    本文主要向大家介绍了Python语言解析JSON详解,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. JSON 函数使用 JSON 函数需要导入 json 库:import jso ...

  7. c语言4 答案详解,2019考研数据结构C语言版详解答案(4)

    <数据结构(C语言版)>复习重点在二.三.六.七.九.十章,考试内容两大类:概念,算法,自从计算机专业课统考以后,专业课考试题型分为2类,一类选择题,一类综合应用题.本次新东方在线整理了数 ...

  8. 计算机科学类专升本复习之“C语言结构体”详解(初稿)

    C语言结构体详解,C语言struct用法详解 前面所学到的"数组":它是一组具有"相同类型"的数据的集合. 但是在实际的编程中,我们往往还需要 一组" ...

  9. 【C语言】函数详解(入门到进阶)

    目录 前言 一.什么是函数 二.函数的构成 三.函数的调用和声明 四.函数的参数 五.函数的递归 总结 写在后面 前言 最近帮家里的小朋友整理一些学习C语言的知识点 有整体入门基础文章--[C语言]拯 ...

  10. 一个简单的C语言程序(详解)

    C Primer Plus之一个简单的C语言程序(详解) #include <stdio.h>int main(void) //一个简单的 C程序 {int num; //定义一个名为 n ...

最新文章

  1. 写给Python开发者:机器学习十大必备技能
  2. Windows锁定计算机C代码编程实现
  3. windows 下安装wamp环境
  4. 2015蓝桥杯省赛---java---A---3(九数分三组)
  5. 史上最全的ECharts讲解与使用
  6. 能把汉字转化为拼音的一个函数
  7. linux常用命令(4)——系统管理2
  8. Python——Selenium Chrome Driver配置
  9. java多线程(1)----多线程的概述
  10. linux如何回到下一级,linux如何返回上一级目录
  11. 小说网站源码+采集器+App端
  12. android 控件发光_Android自定义控件打造闪闪发光字体
  13. 八七、Node.js事件循环与多进程
  14. 数字化的一切都会在安全沙箱里面
  15. linux下批量创建文件(空文件、带内容文件)、文件夹
  16. 论文翻译 —— Model Free Episodic Control
  17. python-22-使用Kivy开发手机app
  18. laya 学习抛出事件与接收事件
  19. [转]OpenSynergy的COQOS Hypervisor SDK-实现仪表和车载信息娱乐系统共享显示
  20. APP android 测试用例手册

热门文章

  1. python——图片爬虫:爬取爱女神网站(www.znzhi.net)上的妹子图 进阶篇
  2. win32api模拟键盘鼠标
  3. 十六进制颜色值与RGB(A)颜色值互相转换。
  4. 为何联通资费比移动电信低,用户却是最少的呢?看完你就知道了
  5. 【乐逍遥网站设计】网站设计一般多少钱
  6. XXL-JOB - 调度中心和执行器的简单使用
  7. 全国各省土壤类型空间分布数据
  8. Eclipse 安装ADT
  9. 服务器一直生成lpk.dll文件
  10. js pdf文件 如何调用打印机打印_可以使用Javascript打开PDF文件的打印对话框吗?...