【C语言】动态通讯录(超详细)
通讯录是一个可以很好锻炼我们对结构体的使用,加深对结构体的理解,在为以后学习数据结构打下结实的基础
这里我们想设计一个有添加联系人,删除联系人,查找联系人,修改联系人,展示联系人,排序
这几种功能的通讯录
目录
- 整体框架:
- 菜单:
- 创建通讯录:
- 初始化:
- 实现功能:
- 添加联系人:
- 删除联系人:
- find()的定义:
- 查找联系人:
- 修改联系人:
- 展示联系人:
- 排序:
- free空间:
- 源代码:
注意:我们按照三个区域划分
上图所示进行区域划分
- con.c用来放实现功能的函数
- con.h用来放头文件的声明
- test.c用来放整体框架
整体框架:
使用do...while
循环创建整体框架
整体框架在
test.c
中,这部分我们用来测试代码
int main()
{int input = 0;InitContact(&Con);do{menu();printf("请输入你的选项\n");scanf("%d", &input);switch (input){case Add:break;case Del:break;case Search:break;case Modify:break;case Show:break;case Sort:break;case Exit:printf("你已成功退出\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}
- 注意:
- 我在使用case语句时没有用数字1,2,3…
而是使用了枚举常量,因为枚举常量会更方便程序员查看与操作要与菜单的数字相匹配,不然就会弄巧成拙
enum option
{Exit,Add,Del,Search,Modify,Show,Sort,
};
菜单:
菜单的设计随心所欲,但要与枚举相匹配!
void menu()
{printf("**************************\n");printf("*** 1.Add 2.Del **\n");printf("*** 3.Search 4.Modify **\n");printf("*** 5.Show 6.Sort **\n");printf("*** 0.Exit **\n");printf("**************************\n");printf("**************************\n");
}
创建通讯录:
此部分我们在
Contact.h
中创建,在另外两个里include
就可以
创建通讯录之前要先创建一个联系人的结构体:
假设我们的结构体包含了一个人的姓名,年龄,性别,电话,住址
那么久可以很好的进行创建:
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;
其中的常量用define
按需求进行定义,避免牵一发而动全身的情况
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
因为要动态通讯录
故设计通讯录时不能使用PeoInfo
创建数组的方式进行
可以创建结构体指针,指向动态内存分配的空间
typedef struct Contact
{PeoInfo* Data;int sz;int capacity;
}Contact;
最后在test.c
文件中创建通讯录 Contact Con;
初始化:
在
con.c
中进行设计,不要忘记在test.c
中调用,在con.h
中声明
实现功能皆是如此设计,将不在赘述
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;pc->capacity = START;PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);//start为初始化大小,define定义为3if (p != NULL){pc->Data = p;}else{perror("InitContact->malloc");}
}
实现功能:
添加联系人:
void AddContact(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){PeoInfo* str = (PeoInfo*)realloc(pc->Data, sizeof(PeoInfo) * (pc->capacity + START_ADD));//START_ADD为define定义,为一次扩容数量if (str != NULL){pc->Data = str;pc->capacity = pc->capacity + START_ADD;printf("增容成功\n");}else{perror("AddContact->realloc");return;}}printf("输入名字\n");scanf("%s", pc->Data[pc->sz].name);printf("输入年龄\n");scanf("%d", &pc->Data[pc->sz].age);printf("输入性别\n");scanf("%s", &pc->Data[pc->sz].sex);printf("输入电话\n");scanf("%s", &pc->Data[pc->sz].tele);printf("输入住址\n");scanf("%s", &pc->Data[pc->sz].addr);printf("输入成功\n");pc->sz++;
}
删除联系人:
void DelContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无需删除\n");return;}char name[NAME_MAX];printf("输入你要删除人的姓名\n");scanf("%s", name);int ret = find(pc, name);//我们这里使用了find函数if (ret == -1){printf("查无此人\n");return;}for (int i = ret; i < pc->sz-1; i++){pc->Data[i] = pc->Data[i + 1];}pc->sz--;
}
我们在输入查找姓名后要进行查找,因此我们设计了一个find
函数,方便别的函数的使用
find()的定义:
int find(Contact* pc, char name[])
{for (int i = 0; i < pc->sz; i++){if (strcmp(name, pc->Data[i].name) == 0){return i;}}return -1;
}
查找联系人:
void SearchContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空\n");return;}char name[NAME_MAX];printf("输入你要查找人的姓名\n");scanf("%s", name);int ret = find(pc, name);if (ret == -1){printf("查无此人\n");return;}printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");printf(" % -20s % -5d % -5s % -20s % -20s\n",pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}
修改联系人:
void ModifyContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空\n");return;}char name[NAME_MAX];printf("输入你要修改人的姓名\n");scanf("%s", name);int ret = find(pc, name);if (ret == -1){printf("查无此人\n");return;}printf("输入名字\n");scanf("%s", pc->Data[ret].name);printf("输入年龄\n");scanf("%d", &pc->Data[ret].age);printf("输入性别\n");scanf("%s", &pc->Data[ret].sex);printf("输入电话\n");scanf("%s", &pc->Data[ret].tele);printf("输入住址\n");scanf("%s", &pc->Data[ret].addr);printf("输入成功\n");
}
展示联系人:
void ShowContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无需打印\n");return;}printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");for (int i = 0; i < pc->sz; i++){printf(" % -20s % -5d % -5s % -20s % -20s\n",pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);}
}
排序:
排序可以按照名字排,或是年龄,亦或是性别等等
这里我们只进行名字的排序,使用方法大同小异(快排)
int cmp_name(void* e1,void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}
free空间:
最后一步就是释放空间有始有终
void DestoryContact(Contact* pc)
{free(pc);
}
源代码:
con.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"int find(Contact* pc, char name[])
{for (int i = 0; i < pc->sz; i++){if (strcmp(name, pc->Data[i].name) == 0){return i;}}return -1;
}//void InitContact(Contact* pc)
//{
// assert(pc);
// pc->sz = 0;
// memset(pc->Data, 0, sizeof(pc->Data));
//}
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;pc->capacity = START;PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);if (p != NULL){pc->Data = p;}else{perror("InitContact->malloc");}
}void DestoryContact(Contact* pc)
{free(pc);
}void AddContact(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){PeoInfo* str = (PeoInfo*)realloc(pc->Data, sizeof(PeoInfo) * (pc->capacity + START_ADD));if (str != NULL){pc->Data = str;pc->capacity = pc->capacity + 2;printf("增容成功\n");}else{perror("AddContact->realloc");return;}}printf("输入名字\n");scanf("%s", pc->Data[pc->sz].name);printf("输入年龄\n");scanf("%d", &pc->Data[pc->sz].age);printf("输入性别\n");scanf("%s", &pc->Data[pc->sz].sex);printf("输入电话\n");scanf("%s", &pc->Data[pc->sz].tele);printf("输入住址\n");scanf("%s", &pc->Data[pc->sz].addr);printf("输入成功\n");pc->sz++;
}void ShowContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无需打印\n");return;}printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");for (int i = 0; i < pc->sz; i++){printf(" % -20s % -5d % -5s % -20s % -20s\n",pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);}
}void DelContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无需删除\n");return;}char name[NAME_MAX];printf("输入你要删除人的姓名\n");scanf("%s", name);int ret = find(pc, name);if (ret == -1){printf("查无此人\n");return;}for (int i = ret; i < pc->sz-1; i++){pc->Data[i] = pc->Data[i + 1];}pc->sz--;
}void SearchContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空\n");return;}char name[NAME_MAX];printf("输入你要查找人的姓名\n");scanf("%s", name);int ret = find(pc, name);if (ret == -1){printf("查无此人\n");return;}printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年龄", "性别", "电话", "住址");printf(" % -20s % -5d % -5s % -20s % -20s\n",pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}void ModifyContact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空\n");return;}char name[NAME_MAX];printf("输入你要修改人的姓名\n");scanf("%s", name);int ret = find(pc, name);if (ret == -1){printf("查无此人\n");return;}printf("输入名字\n");scanf("%s", pc->Data[ret].name);printf("输入年龄\n");scanf("%d", &pc->Data[ret].age);printf("输入性别\n");scanf("%s", &pc->Data[ret].sex);printf("输入电话\n");scanf("%s", &pc->Data[ret].tele);printf("输入住址\n");scanf("%s", &pc->Data[ret].addr);printf("输入成功\n");
}int cmp_name(void* e1,void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}
con.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30#define START 3
#define START_ADD 2typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;typedef struct Contact
{PeoInfo* Data;int sz;int capacity;
}Contact;//init
void InitContact(Contact* pc);//add
void AddContact(Contact* pc);//show
void ShowContact(Contact* pc);//del
void DelContact(Contact* pc);//search
void SearchContact(Contact* pc);//modify
void ModifyContact(Contact* pc);//sort
void SortContact(Contact* pc);//destory
void DestoryContact(Contact* pc);
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"enum option
{Exit,Add,Del,Search,Modify,Show,Sort,
};void menu()
{printf("**************************\n");printf("*** 1.Add 2.Del **\n");printf("*** 3.Search 4.Modify **\n");printf("*** 5.Show 6.Sort **\n");printf("*** 0.Exit **\n");printf("**************************\n");printf("**************************\n");
}
int main()
{int input = 0;Contact Con;InitContact(&Con);do{menu();printf("请输入你的选项\n");scanf("%d", &input);switch (input){case Add:AddContact(&Con);break;case Del:DelContact(&Con);break;case Search:SearchContact(&Con);break;case Modify:ModifyContact(&Con);break;case Show:ShowContact(&Con);break;case Sort:SortContact(&Con);break;case Exit:DestoryContact(&Con);printf("你已成功退出\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}
欢迎纠错与讨论
相关文章:
【C语言】动态通讯录(超详细)
通讯录是一个可以很好锻炼我们对结构体的使用,加深对结构体的理解,在为以后学习数据结构打下结实的基础 这里我们想设计一个有添加联系人,删除联系人,查找联系人,修改联系人,展示联系人,排序这几…...
Mac下docker安装MySQL8.0.34
学习并记录一下如何用docker部署MySQL 在Docker中搜索并下载MySQL8.0.x的最新版本 下载好后,在Images中就可以看到MySQL的镜像了 通过下面的命令也可以查看docker images启动镜像,使用下面的命令就可以启动镜像了docker run -itd --name mysql8.0.34 -…...
基于python编写的excel表格数据标记的exe文件
目录 一、需求: 二、思路: 三、工具 四、设计过程 (一)根据需要导入相关的图形界面库 (二)创建图形窗口 (三)标签设计 (四)方法按钮设计 ࿰…...
acwing算法基础之基础算法--高精度加法算法
目录 1 知识点2 模板 1 知识点 大整数 大整数,它们的长度都为 1 0 6 10^6 106。大整数是指长度为 1 0 6 10^6 106的整数。 大整数 - 大整数 大整数 * 小整数 大整数 / 小整数 把大整数存储到向量中,需要考虑高位在前还是低位在前,低位在前…...
openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86
文章目录 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x8684.1 BIOS84.2 操作系统环境设置84.3 网络 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86 …...
二分查找:34. 在排序数组中查找元素的第一个和最后一个位置
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《算法》 文章目录 前言一、题目解析二、解题思路1. 暴力查找2. 一次二分查找 部分遍历3. 两次二分查找分别查找左右端点1.查找区间左端点2. 查找区间右端点 三、代码实现总结 前言 本篇文…...
javaee ssm框架项目整合thymeleaf2.0 更多thymeleaf标签用法 项目结构图
创建ssmthymeleaf项目 创建ssmthymeleaf项目参考此文 thymeleaf更多常用标签 <!DOCTYPE html> <html lang"en" xmlns:th"http://www.thymeleaf.org"> <head><meta charset"UTF-8"><title>Title</title> …...
lv7 嵌入式开发-网络编程开发 11 TCP管理与UDP协议
目录 1 TCP管理 1.1 三次握手 1.2 四次挥手 1.3 保活计时器 2 wireshark安装及实验 3.1 icmp协议抓包演示 3.2 tcp协议抓包演示 3 UDP协议 3.1 UDP 的主要特点: 4 练习 1 TCP管理 1.1 三次握手 TCP 建立连接的过程叫做握手。 采用三报文握手࿱…...
overleaf在线编辑工具使用教程
文章目录 1 用 orcid注册overleaf获取模板2 使用模板 1 用 orcid注册overleaf获取模板 通常来说,在期刊投稿网站information for author中找template 。下载压缩包后上传到over leaf中。 加入找不到官方模板,用overleaf中的 2 使用模板 .bib文件&…...
Python基础复习【第一弹】【黑马】
本篇是观看b站黑马视频所做的笔记第一弹,为1-98节。 b站-黑马Python # 1.Hello World print("Hello World")# 2.字面量 在代码中,被写下来固定的值# 3.字符串 print("python")# 4.单行注释 # 多行注释""" "&q…...
【Word】公式编辑器中连字符/减号等显示偏长/过长
问题 当公式编辑器中出现连字符的时候,连字符显示偏长,如下图所示: 方法 在连字符的前后加上双引号后即可解决连字符显示偏长的问题。 最终效果对比如下: 结语 Word的公式编辑器中,双引号内部的内容被当做普通…...
架构设计系列4:如何设计高性能架构
在架构设计系列1:什么是架构设计中,我们讲了架构设计的主要目的,是为了解决软件系统复杂度带来的问题,今天我们来聊聊软件系统复杂度的来源之一高性能。 一、什么是高性能架构? 要搞清楚什么是高性能架构,…...
1392. 最长快乐前缀
链接: 1392. 最长快乐前缀 题解: class Solution { public:string longestPrefix(string s) {if (s.size() < 0) {return "";}int MOD 1e9 7;// 构建26的n次方,预处理std::vector<long> pow26(s.size());pow26[0] 1…...
【C++设计模式之备忘录模式:行为型】分析及示例
简介 备忘录模式(Memento Pattern)是一种行为型设计模式,它用于保存和恢复对象的状态。备忘录模式通过将对象的状态封装成一个备忘录(Memento),并将备忘录保存在一个管理者(Caretakerÿ…...
数据结构与算法(四):哈希表
参考引用 Hello 算法 Github:hello-algo 1. 哈希表 1.1 哈希表概述 哈希表(hash table),又称散列表,其通过建立键 key 与值 value 之间的映射,实现高效的元素查询 具体而言,向哈希表输入一个键…...
FFmpeg 命令:从入门到精通 | ffplay 播放控制选项
FFmpeg 命令:从入门到精通 | ffplay 播放控制选项 FFmpeg 命令:从入门到精通 | ffplay 播放控制选项选项表格图片 FFmpeg 命令:从入门到精通 | ffplay 播放控制选项 选项表格 项目说明Q,Esc退出播放F,鼠标左键双击全…...
代码随想录day59
647. 回文子串 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成&#…...
【小工具-生成合并文件】使用python实现2个excel文件根据主键合并生成csv文件
1 小工具说明 1.1 功能说明 一般来说,我们会先有一个老的文件,这个文件内容是定制好相关列的表格,作为每天的报告。 当下一天来的时候,需要根据新的报表文件和昨天的报表文件做一个合并,合并的时候就会出现有些事新增…...
【论文阅读】An Evaluation of Concurrency Control with One Thousand Cores
An Evaluation of Concurrency Control with One Thousand Cores Staring into the Abyss: An Evaluation of Concurrency Control with One Thousand Cores ABSTRACT 随着多核处理器的发展,一个芯片可能有几十乃至上百个core。在数百个线程并行运行的情况下&…...
网页版”高德地图“如何设置默认城市?
问题: 每次打开网页版高德地图时默认定位的都是“北京”,想设置起始点为目前本人所在城市,烦恼的是高德地图默认的初始位置是北京。 解决: 目前网页版高德地图暂不支持设置起始点,打开默认都是北京,只能将…...
小谈设计模式(8)—代理模式
小谈设计模式(8)—代理模式 专栏介绍专栏地址专栏介绍 代理模式代理模式角色分析抽象主题(Subject)真实主题(Real Subject)代理(Proxy) 应用场景远程代理虚拟代理安全代理智能引用代…...
queryWrapper的使用教程
大于、等于、小于 eq 等于 例:queryWrapper.eq("属性","lkm") ——> 属性 lkm ne 不等于 例:queryWrapper.ne("属性","lkm") ——> 属性<> lkm gt 大于 例:queryWrapper.gt("属性…...
数组模拟双链表
文章目录 QuestionIdeasCode Question 实现一个双链表,双链表初始为空,支持 5 种操作: 在最左侧插入一个数; 在最右侧插入一个数; 将第 k 个插入的数删除; 在第 k 个插入的数左侧插入一个数; …...
鸡群优化(CSO)算法(含MATLAB代码)
先做一个声明:文章是由我的个人公众号中的推送直接复制粘贴而来,因此对智能优化算法感兴趣的朋友,可关注我的个人公众号:启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法,经典的,或者是近几年…...
3. 安装lombok maven镜像设置
安装lombok & maven镜像设置 一、maven镜像设置 Maven:负责进行项目管理、依赖工具管理的 软件。 快捷解决方案: 1.方法一 直接配置系统默认的文件 各个人因为登录的用户名不同,所以目录名不同。 2.方法二 自定义本地仓库的位置 完成之后重新打…...
详谈Spring
作者:爱塔居 专栏:JavaEE 目录 一、Spring是什么? 1.1 Spring框架的一些核心特点: 二、IoC(控制反转)是什么? 2.1 实现手段 2.2 依赖注入(DI)的实现原理 2.3 优点 三、AO…...
PyTorch入门之【AlexNet】
参考文献:https://www.bilibili.com/video/BV1DP411C7Bw/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 AlexNet 是一个经典的卷积神经网络模型,用于图像分类任务。 目录 大纲dataloadermodeltraintest 大纲 各个文件的作用&…...
(六)正点原子STM32MP135移植——内核移植
目录 一、概述 二、编译官方代码 三、移植 四、编译 一、概述 前面已经移植好了TF-A、optee、u-boot,在u-boot能正常跑起来的情况下,现在来移植内核。 二、编译官方代码 进入kernel目录 2.1 解压源码、打补丁 /* 解压源码 */ tar xf linux-6.1.28.…...
自媒体工作内容管理助手
内容助手 访问地址:editor.yunwow.cn 背景介绍 最近在学习流量运营, 流量运营的第一站是内容创作, 我试过不少原创内容,都是跟生活相关的例如:录一段联琴的视频、录一段秋天的风景、写一段生活感悟、发一段小宠物的生…...
Echarts 教程一
Echarts 教程一 可视化大屏幕适配方案可视化大屏幕布局方案Echart 图表通用配置部分解决方案1. titile2. tooltip3. xAxis / yAxis 常用配置4. legend5. grid6. series7.color Echarts API 使用全局echarts对象echarts实例对象 可视化大屏幕适配方案 rem flexible.js 关于flex…...
wordpress收件邮箱怎么设置/app拉新一手渠道
【文档说明】本文档介绍从SQLSERVER2008R2通过创建链接服务器ORACLE11G,进行数据的获取操作的步骤;网上也有很多的相关文档,但是操作一直不成功,估计是环境比较复杂。 【操作步骤】 【1】在SQLSERVER服务器上面安装ORACLE CLIEN…...
江门网站建设易搜互联/seo外包服务项目
随着信息技术的快速发展和网络技术的日益完善,人们越来越重视电子商务。校园 二手物品交易系统是校园电子商务的一个典型代表。二手市场从以前的路边旧货市场转 变到网络中,通过二手交易系统实现了二手交易。而校园二手物品交易系统带给学生省 时、省…...
做思路导图的网站manage/长沙免费建站网络营销
并发编程设计之Thread-Per-Message模式:最简单实用的分工方法引言如何理解 Thread-Per-Message 模式用 Thread 实现 Thread-Per-Message 模式引言 并发编程领域的问题总结为三个核心问题:分工、同步和互斥。其中,同步和互斥相关问题更多地源…...
wordpress对接易支付宝/黄金网站软件免费
AI开发平台ModelArtsModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化标注、大规模分布式Training、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周…...
网站栏目设计规划表/新网站秒收录技术
什么是图?图是一种复杂的非线性表结构.由若干给定的点一级任意两点间的连线所构成.图通常用来描述事物之间的特定关系, 代表的就是事物, 线就是事物之间所具有的关系.例如社交网络就是一种典型的图关系, 每一个用户都是一个顶点,任意两个用户加了好友, 他们之间就有了一条边.简…...
山西网站建设公司哪家好/百度竞价推广是什么工作
根据Gartner的研究统计,在实施虚拟世界的公司中,有90%都在18个月(或更短)的时间内以失败而告终。失败的原因多是由于公司没有充分考虑用户使用的问题,而非纯粹的技术因素。 Gartner的副总裁表示,“如此高的失败率给企业上了严峻的…...