May 30

lua的一个重要的应用是作为程序配置文件的语言(configuration language)。下面通过一个简单示例来说明其应用。

从一个简单示例开始

假设一个c语言程序要画一个窗口界面,窗口的长和宽可以由用户指定。要实现这个功能还有另外更简单的方法,例如使用环境变量或只包含(key, value)形式的普通文本文件,但是如果使用普通文本文件你还是需要对其进行解析。程序的配置文件如下(conf.lua):

--configuration file
--to define window_size
width = 200
height = 300

下面的代码演示了如何用lua提供的接口来获得这两个全局变量的值:

May 21

《Windows网络程序设计》考试在几天前就结束了,第一次在试卷上写代码写到手痛,只能说考试很水很恶心!最近翻了一下zsh的文档,突然想自己写一个shell来玩一下,结果写了一点基本的东西(只完成了执行进程和信号控制)就写不下去了,总想着添加接口的问题,于是又去看lua(已是第二次!)、翻云风大神的Blog(很多都是看不懂的),决定还是应该深入了解一下lua。这些都是题外话,与主题无关!wheel...在这里图片在blog中是没有水印的,今天特意用python的PIL模块写了一个简陋的添加水印的脚本。PIL模块在很久之前就用过了,不过当时是拿来生成验证码,;-D。。。对于简单的图像处理来说,PIL足以应付了(虽然我更喜欢opencv ;)),只能感叹一下python的模块真的很管用!

PIL生成水印图像很简单,把你的水印添加到源图像来生成目标图像,一个简单例子:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import Image

source_img = Image.open('source.png')
logo_img = Image.open('logo.png')   # 要保证你的logo是透明的哟。。。废话!
source_img.paste(logo_img, (source_img.size[0] - logo_img.size[0],
                 source_img.size[1] - logo_img.size[1]), logo_img)
source_img.save('target.png', 'PNG')

May 18
Q:什么是常量折叠?
A:常量折叠(constant folding),一种编译优化技术。例如:“2+2”应该在编译时就处理为4;

比如有以下代码:

const double PI = 3.141592653589793;
const double d  = 10.0;
const double c  = d/2*PI;

在编译时如果使用到c就用计算的结果来代替,这就是“常量折叠”。

应该说常量折叠就是编译器不想浪费静态内存而对const定义的常量进行预编译的结果。。。

上段代码,试着修改const定义的常量的值:

/*
                     {/ . .\}
                     ( (oo)   )
+--------------oOOo---︶︶︶︶---oOOo------------------+
#     FileName  :           const_folding.c
#     Describe  :           修改const定义的常量的值
#     Author    :           Lazy.monkey™
#     Email     :           lazymonkey.me@gmail.com
#     HomePage  :           lazymonkey.is-programmer.com
#     Version   :           0.0.1
#     LastChange:           2012-05-18 22:41:16
+------------------------------------Oooo--------------+

*/

#include <stdio.h>

int main (int argc, const char *argv[])
{
  const int a = 1;

  printf ("a = %d\n", a);
  *((int *) &a) = 2;
  printf ("a = %d\n", a);

  return 0;
}

运行结果:

a = 1

a = 2

可以了!_ Ok, I enjoy the time!

ps:这是以前在《C和指针》中看到的,原书中提了这种赋值方法,但又提到没人会使用这种蛋疼的方法去为一个变量赋值,呃。。。莫非我就是那个蛋疼的人?;(

May 16

Linux下虚拟地址空间分给进程本身是3GB,那么程序真正能用的有多少?一般我们写程序都是通过调用malloc函数进行地址空间的申请,刚才的问题就可以转换为malloc最大能为进程分配到多少内存空间?下面这段小程序可以测试当前使用的机器上malloc能分配的最大数量:

 

/*
                    {/ . .\}
                    ( (oo)   )
+--------------oOOo---︶︶︶︶---oOOo------------------+
#     FileName  :           max_malloc.c
#     Describe  :           获取本机堆的最大申请数量
#     Author    :           Lazy.monkey™
#     Email     :           lazymonkey.me@gmail.com
#     HomePage  :           lazymonkey.is-programmer.com
#     Version   :           0.0.1
#     LastChange:           2012-05-16 00:25:17
#     History   :
+------------------------------------Oooo--------------+

 */

#include <stdio.h>
#include <stdlib.h>

unsigned maximum = 0;
int main(int argc, const char *argv[])
{
    unsigned block_size[] = {1024 * 1024, 1024, 1};
    int i, count;

    for (i = 0; i < 3; i++) {
        for (count = 1;; count++) {
            void *block = malloc (maximum + block_size[i] * count);
            if (block) {
                maximum = maximum + block_size[i] * count;
                free (block);
            } else
                break;
        }
    }

    printf("maximum malloc size = %u bytes\n", maximum);
    printf("any way, i wana it show me as human size is %u MB\n",
            maximum / (1024 * 1024));

    return 0;
}

在我的机器上得到结果为2010MB左右,为什么一定要强调当前机器?其实malloc的最大申请数量并非是恒定的,即使是同一台机器也会有微小的变化,那么malloc的最大申请数量会受那些因素影响?实际上,操作系统版本、程序本身大小、用到的动态/共享库数量、大小、程序堆栈数量、大小都会使malloc最大申请数量有所变化,甚至有可能每次运行的结果都会有所不同,据说Linux采用了一种叫做随机地址空间分配的技术(主要是处于安全考虑,防止程序恶意攻击),使得进程的堆的空间变小。

May 12

小插曲

修改MakeFile

和Project0一样,Project1在make depend && make时,也会有错误提示,一步一步来解决:

0.去掉过于严格的编译选项(line 178):

CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror

改为:

CC_GENERAL_OPTS := $(GENERAL_OPTS)

1.去掉gcc栈保护的选项(line 176):

GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS)

改为:

GENERAL_OPTS := -O -Wall -fno-stack-protector $(EXTRA_C_OPTS)