homework-03
非常好...果然是我图样图森破...GitHub竟然被墙了...
尴尬的是需要FQ将代码上传至in sync状态...然后翻回来继续上传才行...
还有一些没传上去的...不过主体应该都在了...不知能否运行...
是不是我还没有用对HitHub...总之从上午开始传的代码下了课还没传上去...
然后GitHub官网也打不开...
一. 程序的架构和思路:
由于这种面向对象的窗体程序原来也没少写过...似乎感觉轻车熟路的样子...
事实证明我又天真了...我把《C#入门经典》这本书放家了!
没有参考书只能自己百度了...
和往常一样,我从程序分块入手。这次的作业是将homework-02弄成一个面向对象的窗体程序。
于是界面似乎就是这样...
中间的那个灰框是DataGridView控件,之前没用过,重点是这个。
于是任务就简单了,我将这个程序分为两块,如何用.dll文件链接上次写的程序,and如何让DataGridView显示数据和highlight。
程序我做了少许修改,听从TA的建议,将/h/v合并到了一个程序里,用两个变量h和v表示。
由于我上周听完课后依旧没明白/a该如何实现,因此在这里我就将其简化了(反正加上/a主要修改的是上次的程序)。
呈上代码:
1 #include "mydll.h" 2 int max(int x,int y) 3 { 4 if (x > y) return x; 5 else return y; 6 } 7 void calc(int h,int v) 8 { 9 freopen("input.txt","r",stdin); 10 int a[100][100]; 11 int b[100][100]; 12 int m,n; 13 int i,j,k,temp = 0; 14 scanf("%d,",&m); 15 scanf("%d,",&n); 16 for (i = 1;i <= m;i++) 17 for (j = 1;j <= n;j++) 18 { 19 scanf("%d,",&a[i][j]); 20 a[i + m][j] = a[i][j]; 21 a[i][j + n] = a[i][j]; 22 a[i + m][j + n] = a[i][j]; 23 } 24 fclose(stdin); 25 ans = a[1][1]; 26 for (i = 1;i <= m;i++) 27 for (j = 1;j <= n;j++) ans = max(ans,a[i][j]); 28 memset(b,0,sizeof(b)); 29 int top; 30 if (h == 0 && v == 1) 31 { 32 for (j = 1;j <= n;j++) 33 { 34 temp = 0; 35 for (i = 1;i <= m * 2;i++) 36 { 37 temp = temp + a[i][j]; 38 b[i][j] = temp; 39 } 40 } 41 for (i = 1;i <= m;i++) 42 for (j = i;j <= m * 2;j++) 43 { 44 if ((j - i) <= m) 45 { 46 temp = 0;top = 1; 47 for (k = 1;k <= n;k++) 48 { 49 temp = temp + b[j][k] - b[i - 1][k]; 50 if (temp > ans) 51 { 52 ans = temp; 53 begin_x = i;end_x = j; 54 begin_y = top;end_y = k; 55 } 56 else if (temp < 0) 57 { 58 temp = 0; 59 top = k + 1; 60 } 61 } 62 } 63 } 64 } 65 else if (h == 1 && v == 0) 66 { 67 for (i = 1;i <= m;i++) 68 { 69 temp = 0; 70 for (j = 1;j <= n * 2;j++) 71 { 72 temp = temp + a[i][j]; 73 b[i][j] = temp; 74 } 75 } 76 for (i = 1;i <= n;i++) 77 for (j = i;j <= n * 2;j++) 78 { 79 if ((j - i) <= n) 80 { 81 temp = 0;top = 1; 82 for (k = 1;k <= m;k++) 83 { 84 temp = temp + b[k][j] - b[k][i - 1]; 85 if (temp > ans) 86 { 87 ans = temp; 88 begin_y = i;end_y = j; 89 begin_x = top;end_x = k; 90 } 91 else if (temp < 0) 92 { 93 temp = 0; 94 top = k + 1; 95 } 96 } 97 } 98 } 99 } 100 else if (h == 0 && v == 0) 101 { 102 for (j = 1;j <= n;j++) 103 { 104 temp = 0; 105 for (i = 1;i <= m;i++) 106 { 107 temp = temp + a[i][j]; 108 b[i][j] = temp; 109 } 110 } 111 for (i = 1;i <= m;i++) 112 for (j = i;j <= m;j++) 113 { 114 if ((j - i) <= m) 115 { 116 temp = 0;top = 1; 117 for (k = 1;k <= n;k++) 118 { 119 temp = temp + b[j][k] - b[i - 1][k]; 120 if (temp > ans) 121 { 122 ans = temp; 123 begin_x = i;end_x = j; 124 begin_y = top;end_y = k; 125 } 126 else if (temp < 0) 127 { 128 temp = 0; 129 top = k + 1; 130 } 131 } 132 } 133 } 134 } 135 else 136 { 137 int length; 138 for (j = 1;j <= n * 2;j++) 139 { 140 temp = 0; 141 for (i = 1;i <= m * 2;i++) 142 { 143 temp = temp + a[i][j]; 144 b[i][j] = temp; 145 } 146 } 147 for (i = 1;i <= m;i++) 148 for (j = i;j <= m * 2;j++) 149 { 150 if ((j - i) <= m) 151 { 152 temp = 0;length = 0;top = 1; 153 for (k = 1;k <= n * 2;k++) 154 { 155 if (length < n) 156 { 157 temp = temp + b[j][k] - b[i - 1][k]; 158 length++; 159 } 160 else 161 { 162 temp = temp + b[j][k] - b[i - 1][k]; 163 temp = temp - b[j][k - 1] + b[i - 1][k - 1]; 164 top++; 165 } 166 if (temp > ans) 167 { 168 ans = temp; 169 begin_x = i;end_x = j; 170 begin_y = top;end_y = k; 171 } 172 else if (temp < 0) 173 { 174 temp = 0; 175 length = 0; 176 top = k + 1; 177 } 178 } 179 } 180 } 181 } 182 } 183 int main() 184 { 185 calc(0,0); 186 printf("%d\n",ans); 187 return 0; 188 }
以及.h文件:
1 #include<stdio.h> 2 #include<string.h> 3 int begin_x,end_x,begin_y,end_y; 4 int ans; 5 int max(int x,int y); 6 void calc(int h,int v); 7 int main();
采用gcc中的命令gcc -Wall -shared homework-03.c -o mydll.dll生成.dll文件。
在VS2012中用
[DllImport("mydll.dll")]
static extern void calc(int h,int v);
实现对源程序的调用。
但是为什么会错呢!!!而且为什么不能互相调用全局变量呢!!!
实在找不到好的解决方法,只能把代码写进C#了...
这就能随意调用全局变量来获取数据了,于是计算结果十分简单。
问题出在DataGridView控件上。
作为新控件,神马方法、属性都得查MSDN的文档,具体哪个是做什么用的都得明白,因此很费时间。
不过最后终于完成了...
对于在同一程序中运行多次数据,需要用一个tabControl来增加一个tabPage,再在tabPage上添加一个DataGridView。
这就需要动态创建这些文件,具体代码请见setupDataGridView()函数。
二. 回答问题:
那怎么能让同一份代码服务于两个不同输出的程序呢?
答:老师给的方法是代码的重用,通过百度google我了解到此种方法是用面向对象程序调用c程序生成的.dll文件,从而实现使用c程序中函数。最后把结果return出来即可。可是问题也是我没有解决的,我需要return回来的变量不止一个,但是同学说不可利用struct(也可能是十分复杂),因此我尝试了如何共享全局变量,失败...
你现在使用的代码规范是什么, 和上课前有什么改进?
答:我一直觉得我的代码很难懂...因为我喜欢把所有程序都写入主函数...为此我得到了队友严厉的谴责...
现在我尝试把代码分开来写,写入不同的函数,用函数名来提示function。
你的同伴有哪些优点 (列出至少三点), 和那些需要改进的地方 (列出至少三点)
答:王文涛是我们学院实验班的同学,他的基础知识很棒,能提出一些实用的建议,以及自学能力很强。
但是由于项目做的不多,他的代码能力不是很强,对于主流语言C#了解过少,项目经验不多。
你的代码从 作业2 到 作业3 经历了哪些变化? 哪些代码需要重构 (看关于代码重构的资料), 哪些需要重写, 为什么?
答:首先我把作业2的n段代码合并到了一个程序中,实现了命令行操作/v/h的选择。
如果使用动态链接库的话,代码几乎不用重构,只需重写.h头文件即可。
现在讲代码改为C#语言,大体也不用改动,只需改动数组的定义语句,以及C#的文件读入,这是比较繁琐的地方,因为C#中读入只能按行读入字符串,需要人为用split函数分割,并按位操作将字符转换为数字,具体请见代码readdata()函数。
你的设计是如何保证 不同的 maxsum.exe 命令行最后在一个GUI 的界面显示的? (C++ 的设计模式中有 singleton 的概念, 说明一个类的实例如何在一个进程中保持单例, 我们这里谈的是软件如何在操作系统中保持 singleton)
答:方法有很多,我让程序每隔n秒扫描文件,看是否存在如命令行中的文件名,有,就读入即可。
Personal Software Process Stages |
时间百分比(%) |
实际花费的时间 (分钟) |
原来估计的时间 (分钟) |
|
Planning |
计划 |
|||
· Estimate |
· 估计这个任务需要多少时间,把工作细化并大致排序 |
2.6% | 30 | 30 |
Development |
开发 |
|||
· Analysis |
· 需求分析 (包括学习新技术) |
10.2% | 120 | 60 |
· Design Spec |
· 生成设计文档 |
2.6% | 30 | 30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
1.3% | 15 | 30 |
· Coding Standard |
· 代码规范 (制定合适的规范) |
1.3% | 15 | 30 |
· Design |
· 具体设计 |
10.2% | 120 | 90 |
· Coding |
· 具体编码 |
41.0% | 480 | 300 |
· Code Review |
· 代码复审 |
10.2% | 120 | 90 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
10.2% | 120 | 120 |
Reporting |
总结报告 |
|||
|
5.1% |
60 |
60 | |
|
5.1% | 60 | 60 | |
Total | 总计 | 100% |
总用时 1170 |
总估计的用时 900 |
三. 感想:
最深刻的教训——工具书很重要!
自学能力还是不够强,眼睛看电子书很难受,具体控件的应用还是应该从简单样例入手。