Qt和HTML笔记:初始化
为了应对最近的比赛,但对很对 GUI 系统都不怎么熟悉,而且又要用 C++ 进行项目核心代码的编辑。RetVal 希望团队做出一个很炫的图形界面,不过,对 C++ 的窗口系统还真的不熟悉。于是尝试用 Qt 和 HTML 5 来进行界面的编程,也算是一个新挑战。
不过似乎关于 Qt 和 HTML 5 的中文资料还不多,于是整理一下笔记吧。这个博客也很久没更新了……
迭代器
看了一下nihui的博客,看到了QList的使用,于是有点好奇,然后 csslayer 的讨论更挑起我的兴趣,于是去搜索QList和QMutableListIterator类,找到http://doc.trolltech.com/qq/qq12-qt4-iterators.html,Qt 4 的迭代器的使用。
其实我一直觉得 STL 的迭代器很奇怪,使用*、[]、++、--等运算符来操作,一开始我竟找不到如何使用这一套看似十分强大的库函数的方法,而且编程思路和很多调用不一致。
像
vector<int> a; vector<int>::iterator iter = a.begin (); while (iter != a.end ()) { cout << *iter << endl; iter ++; }
为什么就想到用 * 来取元素呢?既然 iter 不是指针,这个操作符就不应该用啊……不过 C++ 还是用了,而且用得也很巧妙……
呃,我觉得很大程度上是因为我一开始学的是 Java 吧,现在越来越觉得其实编程语言的不同本质上是编程思想的不同,编程思想类似的语言,像 Python 和 C++ ,如果你知道怎么用 C++ 会很快就找到如何使用 Python 的。
很好奇为什么 Qt 的 QTL 居然可以和 STL 共存且兼容,可以使用 STL 里 agorithm 头文件里面声明的算法。然后那篇文章里提到的一点
The STL iterator syntax is modeled after the syntax of pointers into an array. This makes it possible to use STL's (or Qt's) generic algorithms on a plain C++ array.
然后我明白了,原来 C++ STL 里面的迭代器模型就是指针,所以所有关于指针取值、前后运算的操作符都可以用在迭代器上,而且是那么自然,更重要的是 C++ 的模板是没有类型检查的,只要最终类型支持在模板函数里用到的那些方法即可。
那篇文章里面提到的有关迭代器内容修改、遍历的问题我觉得都说的很有道理,不一一翻译了,推荐一看。
更详细的 Qt 4 文档:http://developer.qt.nokia.com/doc/qt-4.8/containers.html
[C语言]字符串与其他类型间的转换
字符串->其他类型:sscanf(const char *src, const char *format, ... )
这个函数和scanf(const char *format, ...)类似,但不同的是,sscanf()是把字符串src当作输入,然后从中提取需要的信息的。所以,事实上format参数的运用和我们从标准输入(键盘)那里获取参数是相似的。
例如:
由字符串提取整数(十进制):
char *src="2"; int i; sscanf(src, "%d", &i); /* i = 2 */
从字符串提取浮点数:
char *src="2.2"; float f; sscanf(src, "%f", &f); /* f = 2.2 */
从字符串提取字符串:
char *src="abc def"; char a[4], b[4]; sscanf(src, "%s %s", a, b); /* a="abc". b="def" */
这个是比较有意思的应用。这样,我们就可以很方便地分割字符了。
而使用这个函数时,不需注意后面的参数是指针而不是整数或者其他数值类型。
其他类型->字符串:sprintf(const char *dest, const char *format, ...)
这个函数和sscanf是相对应的。因此,可以类比printf()的用法来得出这个函数的用法,就是从把后文format的内容复制到src中而不是标准输出而已。
例如:
十进制整数到字符串:
char dest[3]; int i=3; sprintf(dest, "%d", i); /* dest = "3"; */
浮点数到字符串:
char dest[5]; float f=3.3f; sprintf(dest, "%f", f); /* dest = "3.3" */
字符串到字符串:
char dest[10]; char *a="abc", *b="def"; sprintf(dest, "%s %s", a, b); /* dest = "abc def" */
这样也可以当作字符串合并函数用~
而使用sprintf()时必须注意目标字符串的长度。
以上的仅仅列举了常用的一些类型转换,至于其他类型,只要修改格式中的%x就好了(x替换为其他类型的代表字符,叫做类型转换符吧,另外注意‘x’本身其实也代表一种类型)。作为一个参考的文档,把Linux Programmer's Manual上关于sscanf()和sprintf()的文档也翻译一下吧~
类型转换符:(就是修饰在‘%’后面的字符,作为后面传入参数的类型提示。)
- d - 十进制整数,对应int类型指针
- i - 整数,对应int类型;与d不同的是,如果字符串中的整数以‘0x’等暗示进位制的前缀时,它会自动识别为该进制下的整数。
- o - 八进制整数,对应int类型指针
- u - 无符号十进制整数,对应unsigned int类型指针
- x - 十六进制整数,对应int类型指针
- f - 浮点数,对应float类型指针
- s - 连续字符串(没有空格分开),对应char的指针
- c - 指定长度的字符串,例如:10c读取10个字符到字符串中。对应char指针
- [] - 匹配正则表达式……
- ……
类型修饰符:(就是在前面类型转换符前面加的修饰符)
- h - 修饰短整数
- l - 长整数
- L - 更精确的double类型(也就是long double)
- ……
另外,这两个函数就存在于stdio.h中,属于标准函数。更详细的内容,例如正则表达式的使用,参见Linux Programmer's Manual……
New laptop...
I bought a new laptop today, Acer 455G. It features AMD Phenom II N970 with AMD Radeon HD 6470M. I admitted that it wasn't a really good setup but it cost little. I had been working on the new machine since 7 o'clock, a little longer than I expected but still can't find the driver for AMD Radeon HD 6xxxM and suffered a terrible 1024x768 display on a 16:9 monitor. Then I would try OpenSuse 11.4 KDE edition.
However, I had chosen it, whether good or not.
L.UI 开发
断断续续地,又很久没更新过了……
L.UI这个东西是我学习SDL写的一套界面,名字是为了纪念一件事,或许是我做错了的一件事。不过,从寒假结束到现在,在这其中,我还是学到了不少东西。学习了M-V-C的设计模式,终于明白绘制和控制分离的好处了——这样就不用传递太多的东西;还有,就是坚持…… The code will be released in the near future...
A little busy these days, I had been working on a project that cost a lot of time and energy. I thought I had done a lot of wrong things the past seven days. Finally, with the help of the rest five colleagues, I had worked out a version that could be submitted but it was still a demo.
It was the first time for me to be a 'leader' in a team. People all trusted me but I thought I was not a good leader then. However, I will try to be a good leader in the following days.
I was still studying English... (But I didn't know how to set up the input method in Kubuntu. )
#define的继续讨论
正如上次所说的,#define可以定义语言结构,例如:
#include <stdio.h> #define Dear(x) void main(x) { #define she int argc, int *argv[] #define I int i; #define love for(i=0;i<99;i++) #define you printf("I love you!\n"); #define by ; #define name } Dear(she) I love you by name
可以把一段原来很普通的代码变得“优雅”。当然,C语言在宏命令处理方面肯定没有其它宏命令处理强,而且也容易出错。
正如代码所说的,可以定义没有“main()”的代码。
关于#define预处理的讨论
以前看过一本C++的书说常量的定义最好不要用#define而用const,以前总不太明白为什么要新增一种常量类型const来定义。C语言的常规方法#define不是很好吗?
然而,事实上,#define处理的不仅仅是常量,而且包括语言结构……