有了指针,数组,字符串的概念,总算可以继续说说 MVC了。前面说过。模块化的设计,接口参数针对模式,而数据是通过缓冲来传递的。那么对于MVC 的 C ,control我们也存在缓冲。这里先说一下,control,控制,侠义的控制,如同你的游戏机手柄,或者你的鼠标。但其实还有另外一种控制。例如警察针对嫌疑犯,前者对后者的控制,其实这个控制包含了另一种解释,即,约束和掌握。
因此说,广义的控制,应该是存在主从关系的由主对从的影响力的表现。这话说的有点大和杂了,无非希望你别认为,只有触发和通过你的手才叫控制。当A,使用某种信息,可以影响到时,这其实就是控制。
我们先不说键盘怎么操作,这个很无聊,有两个无聊点:
1、各种键盘甚至游戏柄都是外设,而不同操作系统下,对这个外设的接口通常有各自的方式。介绍这类问题会把讨论,谈歪了。
2、很多教科书,如同推销自己的传家宝一样,推销scanf这个函数,那么试想,如果你尝试测试一个软件,需要很多方式的组合,是不是你也手工一个个键盘按一遍?何必呢?把对应的情况,依次传入文件,再有程序读取这些文件,一样。
鬼话:很多设备我们都可以看作流文件,键盘如此,你依次读取的文件内容也可以 。
因此,先说个广义上的控制。这还不是我们傻乎乎的把键盘的按键写到文件里。而是我们读取程序运行的参数。现在重新调整第3篇 MVC模块化编程中,设计到的入口参数(注意,这不是接口参数,而是针对程序的给入参数)。假设我们把
height = 3
width = 5
mode = 1
如上文本保存到名为config_attr这个文件名。我们的control模块的目标就是能正确识别到有3个参数。为了能完成这个目标,我们分析一下需要的基本功能,如下散列(散列的意思是内容没有前后因果逻辑,这比较适合开发小组一开始进行头脑风暴,确认大体的设计任务内容):
1、我们需要对文本文件进行读取操作。
2、我们能区分行。
3、我们能从行中区分单词。
4、我们能比较单词。
5、我们能将单词转换为数字。
6、检测多个单词是否合法
6、我们能将对应的数字和对应的正确的单词所指向的参数进行存储。
当然我们还能测试。
下面一个工作任务就是对上述工作进行函数名的设计。不过先得听我两句,
鬼话1:有些新手此时会脑袋有点蒙,如果换个任务,我该怎么细分动作?这事,还真没法教你。因为任何一个任务,都可以有不同的细分方式,而不同的任务,也很难有一个套路来细分。这是经验,或者说是阅历,不是什么军规,规则就可以解决的。
鬼话2:书上有的,记得不用背,这是和教学,考试非常相反的思想。有就查,不然你花钱买书做什么。而书上没有的,恰恰是需要你通过反复的实践和练习靠自己沉淀才能获得的。即便是你获得了葵花宝典,认为看了就神功了,我仍然认为,疼痛忍耐力这种神功,还是需要你漫长的忍耐才能练成。
所以,记得多练。我们继续。
read_param_from_file 这个已经存在。目标是把一个文件的内容读取出来。
split_line 目标区分行
split_token 目标区分单词
//比较不用了吧,咱们用strcmp得了。有标准函数不用,是傻瓜。
//单词转数字?其实你可以参考文献1,查查atol之类的函数,对应还有strtol等,你可以对比一下他们的区别,为了统一期间,我们使用atol等函数。
check_grammar 检测每行的数据是否合规
set_param 设置参数
好的,我们开始写代码,先把control.c的代码如下设计
#include <stdio.h> char filename[1024]; static int split_line(void){ return 1; } static int split_token(void){ return 1; } static int check_grammar(void){ return 1; } static int set_param(void){ return1; } static void read_param_default(void){ printf("read_param_default func !\n"); return; }
static int read_param_from_file(char * filename){ printf("read_param_from_file func !\n"); return 0; }
void control(int flag){ if (flag){ read_param_from_file(filename); }else{ read_param_default(); } return; }
#include <stdio.h> #include "define_attr.h" char filename[1024]; static int split_line(void){ __PRINT_FUNC(); return 0; } static int split_token(void){ __PRINT_FUNC(); return 0; } static int check_grammar(void){ __PRINT_FUNC(); return 0; } static int set_param(void){ __PRINT_FUNC(); return 0; } static void read_param_default(void){ __PRINT_FUNC(); return; }
static int read_param_from_file(char * filename){ __PRINT_FUNC(); return 0; }
void control(int flag){ if (flag){ read_param_from_file(filename); }else{ read_param_default(); } return; }
#include <stdio.h> #include <setjmp.h> #include "value.h" #include "define_attr.h"
jmp_buf context_buf; typedef void F_V_V(void); static int test = 0; static void model_init(void); static void model_done(void); static void model_exit(void); #define MODEL_ENTRY_NUM 4 static F_V_V *model_entry[MODEL_ENTRY_NUM] = {model_init,model_done,model_exit,model_exit};
static void model_init(void){ int t; __PRINT_FUNC(); if ( (t = setjmp(context_buf)) >= 10){ printf("my god ,i escape! %d\n",t); model_exit(); } return; } static void model_done(void){ int i; __PRINT_FUNC(); for (i = 0 ; i < 100; i++){ printf("touch the dog! \n"); if (test >= 10){ printf("the officers come ! run away!\n"); longjmp(context_buf,test); } test += 1; } return; }
static void model_exit(void){
__PRINT_FUNC();
return;
}
void model(int status){
status = (status >= MODEL_ENTRY_NUM ) ? MODEL_ENTRY_NUM-1: status;
model_entry[status]();
}
#include "value.h" #include <stdlib.h> #include "control.h" #define FREE_S_G_POINT(s,g) do {if (s) {free(s); s = 0; g = 0;} }while (0) static int init_flag; static char *s_pmodel = 0; static char *s_pcontrol_input = 0; static int init_control(void){ if (s_pcontrol_input == 0){ s_pcontrol_input = g_pcontrol_input = (char *)malloc(sizeof(char)*CONTROL_INPUT_SIZE); return 1; } return 0; } static void free_control(void){ FREE_S_G_POINT(s_pcontrol_input,g_pcontrol_input); } static int init_model(void){ if (s_pmodel == 0){
s_pmodel = g_pmodel = (char *)malloc(sizeof(char)*100);
return 1;
}
return 0;
} static void free_model(void){ FREE_S_G_POINT(s_pmodel,g_pmodel); } static int init_status(void){ g_status = 1; return 1; } static void free_status(void){ return; } int init_all(void){ if (init_flag == 1) {return init_flag;} init_flag = 1; init_flag = init_flag & init_status(); init_flag = init_flag & init_model(); init_flag = init_flag & init_control(); return init_flag; } int get_init_status(void){ return init_flag; } void free_all(void){ if (init_flag == 0) {return;} init_flag = 0; free_control(); free_model(); free_status(); return; } int g_status; char *g_pmodel ; char *g_pcontrol_input;
#ifndef VALUE_H #define VALUE_H extern int g_status; // used for model module extern char *g_pmodel; //used for control module extern char *g_pcontrol_input; int init_all(void); void free_all(void); #endif
#ifndef CONTROL_H #define CONTROL_H #define CONTROL_INPUT_SIZE 4096 void control(int); extern char filename[]; #endif
有点没得要领
其实指针,以及C语言的其他基本类型都一回事儿吧,就是一段内存,再加上对内存使用方法的解释。 类型转换就是转换一下内存使用的方法。
只不过指针里面保存的是内存地址而已。抛开一些表面的概念,以底层一点的角度去理解,还算简单的。
当然具体使用的时候,有什么技巧,什么陷阱,容易弄错的地方,经验还是很有用的。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。