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处理的不仅仅是常量,而且包括语言结构……