Mac里输入特殊符号

Mac里输入特殊符号特别简单,按住option键(or with shift as well)再按键盘即可。下面是wiki里的两幅映射表:

这个链接对特殊符号分类分得很好:http://www.andyjv.com/mac.html

GNU screen给session设置名字——screen -S NAME

创建时设置:
$ screen -S NAME

在session中设置:
C-a :
sessionname NAME

恢复:
$ screen -r NAME

awk中创建子进程

在使用awk过程中越发觉得awk强大!

有这样一个任务,输入文件(in.txt)是一个无序的多行文本,格式如下:

baidu       www.baidu.com/     7
net114      www.net114.com     NULL
soufun      zzbbs.soufun.com           202.108.253.30
baidu       www.baidu.com/     8
miibeian    www.miibeian.gov.cn        110.85.5.15
baidu       www.baidu.com/     1
baidu       www.baidu.com/     2
net114      www.net114.com     122.11.51.71
miibeian    www.miibeian.gov.cn        8.5.1.74
baidu       www.baidu.com/     3
... ...

每行3列,列之间用 \t 分隔。

需求是:将in.txt按照第一列切分成多个文件,并要求输出文件有序。
Read more »

shell中如何wait某个后台程序并取得其返回值

要等待某个特定PID的后台程序执行结束并取得其返回值(exit code),在BASH中可以这样做:

cmd & p1=$!
wait $p1 || ret=$?

Read more »

[zz] C++ 学习 专家推荐书单

Table Of Content:

综合/巨著:
《C++程序设计语言(特别版)》
《C++Primer中文版》(第四版)
《C++编程思想》(第二版)
入门:
《Accelerated C++中文版》
《C++ PRIMERPLUS》(第5版)中文版
中级:
《C++必知必会》
《Effective C++中文版》
《More Effective C++中文版》
《Effective STL》
《C++高级编程》
《C++沉思录》(Ruminations on C++)
《设计模式》(Design Patterns)
《C++经典问答》(C++ FAQs)
专题/高级:
《C++标准程序库:自修教程与参考手册》(The C++ Standard Library: A Tutorial and Reference)
《Imperfect C++中文版》
《大规模C++程序设计》
《C++设计新思维:泛型编程与设计模式之应用》(Modern C++ Design)
《C++网络编程,卷1,卷2》
Read more »

[zz] C++强大的背后

在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,四年后改称为C++。C++是一门通用编程语言,支持多种编程范式,包括过程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP),后来为泛型而设计的模版,被发现及证明是图灵完备的,因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继承了C的特色,既为高级语言,又含低级语言功能,可同时作为系统和应用编程语言。
C++广泛应用在不同领域,使用者以数百万计。根据近十年的调查,C++的流行程度约稳定排行第3位(于C/Java之后)。 C++经历长期的实践和演化,才成为今日的样貌。1998年,C++标准委员会排除万难,使C++成为ISO标准(俗称C++98),当中含非常强大的标准模版库(standard template library, STL)。之后委员会在2005年提交了有关标准库的第一个技术报告(简称TR1),并为下一个标准C++0x而努力。可惜C++0x并不能在200x年完成,各界希望新标准能于2011年内出台。
流行的C++编译器中,微软Visual C++ 2010已实现部分C++0x语法并加入TR1扩充库,而gcc对C++0x语法和库的支持比VC2010更多。
应否选择C++哪些程序适宜使用C++?C++并非万能丹,我按经验举出一些C++的适用时机。
Read more »

gcc的”变参宏”(Variadic Macros)

就像变参函数那样,gcc里的宏(Macros)也可以定义不定个数的参数,主要就是配合变参函数使用。例如:

#define eprintf(...) fprintf (stderr, __VA_ARGS__)

注意:这里是两个下划线__.

使用时:

eprintf ("%s:%d: ", input_file, lineno)
          ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)

除了使用gcc提供的__VA_ARGS__代替变参外,我们还可以给参数起名字,方法是在”…”之前写上名字,如:

#define eprintf(args...) fprintf (stderr, args)

这里有一个问题,例如下面:

#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

eprintf ("success!\n")
          ==> fprintf(stderr, "success!\n", ); // 问题:这里多了个逗号!

这样肯定是不行的,因此,gcc还为此提供了”##”符号。##符号在 逗号参数名 之间时不做连字符作用,而作为变参宏的特别用处,如下:

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

eprintf ("success!\n")
          ==> fprintf(stderr, "success!\n"); // aha! 这样就OK了!

这个已经是C99标准了,并且gcc能很好的支持,只有一点要注意的:

Variadic macros are a new feature in C99. GNU CPP has supported them for a long time, but only with a named variable argument (`args…’, not `…’ and __VA_ARGS__). If you are concerned with portability to previous versions of GCC, you should use only named variable arguments. On the other hand, if you are concerned with portability to other conforming implementations of C99, you should use only __VA_ARGS__.

c++的const_cast

c++的const_cast操作符是给一个变量删除增加 constvolatile 修饰,例如:

const int a = 10;
int &b = const_cast<int&>(a);
// 注意:这里任何b=xxx的操作都会导致为定义行为的发生!
//     因为a原始定义的时候就是const类型.

或:

void func(const int &c) {
    int &d = const_cast<int&>(c);
    d = 20; // 这里修改是ok的,因为c原始定义并不是const类型
            // 只是在函数传参时才变成"const"的
}

int main(void) {
    int c = 10;
    func(c);
}

对const_cast<>的变量进行修改操作只有在原始变量不是真正的const情况下是安全的, 如果原始变量是const类型,那么任何修改都会导致为定义行为。

const_cast is safe only if you’re casting a variable that was originally non-const.

变长数组与alloca

C99标准里规定了允许在栈上定义变长数组或者叫变长自动数组(Variable-length Automatic Array). 例如:

/* s1 and s2 are two strings(char*) */
char str[strlen (s1) + strlen (s2) + 1]; /* str 就是栈上的变长数组 */
strcpy (str, s1);
strcat (str, s2);

栈上的变长数组比堆上的变长数组有什么好处呢?

1. 不需要担心内存回收,数组变量在超出作用域后会自动回收;
2. 对于多维数组使用尤为方便,例如:

int arr[m][n][k];
int ***p = (int***)malloc(sizeof(int) * m * n * k); /* 这样使用不如 arr 直观方便 */

gcc在这方面早就有了很好的支持,我实际试的是在3.x版就已经支持了,而且,对于C90和C++都支持。
另外,gcc还增加了一个函数:alloca()
类似malloc(),只是alloca()分配的内存是在栈上。

alloca() 和栈上的变长数组的区别在于,alloca() 的分配的内存有效范围是在整个函数内部,而变长数组的有效范围是 { } 之间,例如:

void func(void)
{
    int *p = NULL;
    if (xxx) {
        p = alloca(sizeof(int)); /* alloca分配的内存在if语句外也可以使用. */
        int arr[n]; /* arr的有效范围在if语句内. */
        ...
    }
    ...
}

不过需要注意的是,如果alloca和变长数组在同一个函数里混用时,当一个变长数组被销毁时,在他之后调用的alloca分配的内存也将被销毁。这是gcc manual中的原文:

If you use both variable-length arrays and alloca in the same function, deallocation of a variable-length array will also deallocate anything more recently allocated with alloca.

这点很好理解,变长数组和alloca都是在栈上分配内存,编译器在对栈上的变量销毁时只是简单的弹栈,如下:

if (xxx) {
   int arr[n];
   p = alloca(xxx);
}

上面这段代码执行时栈的变化:

      |   |       top-->|   |             |   |
top-->|   |             | p |             | p |已经无效了!
      |arr|             |arr|             |arr|弹栈,销毁arr
      |...|             |...|       top-->|...|
      +---+             +---+             +---+
(1)分配arr空间      (2)分配p的空间       (3)销毁arr时p同时被销毁

因此,虽然alloca和变长数组可以给我们带来方便,但使用时一定要小心!

[zz]STL迭代器何时失效,很重要,一不小心后果严重

1. vector<T>::iterator

[23.2.4.3] vector modifiers
iterator insert(iterator position, const T& x);
void insert(iterator position, size_type n, const T& x);
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);

Notes: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid…….

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

Effects: Invalidates all the iterators and references after the point of the erase.

2. list<T>::iterator

[23.2.2.3] list modifiers
iterator insert(iterator position, const T& x);
void insert(iterator position, size_type n, const T& x);
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);

void push_front(const T& x);
void push_back(const T& x);

Notes: Does not affect the validity of iterators and references. ……

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

void pop_front();
void pop_back();
void clear();

Effect: Invalidates only the iterators and references to the erased elements.

deque<T>::iterator

[23.2.1.3] deque modifiers

iterator insert(iterator position, const T& x);
void insert(iterator position, size_type n, const T& x);
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);

Effects: An insert in the middle of the deque invalidates all the iterators and references to elements of the deque.
An insert at either end of the deque invalidates all the iterators to the deque, but has no effect on the validity of references to elements fo the deque.

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

Effects: An erase in the middle of the deque invalidates all the iterators and references to elements of the deque. An erase at either end of the deque invalidates only the iterators and the references to the erased elements.

Assosiative container::iterator

<set> <map> <multiset> <multimap>
[23.1.2] line 8:
The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.