Archive

Archive for March 9th, 2010

Linux 环境编程的一些常识

March 9th, 2010 leeing No comments

杂乱地记录一些在 linux 下编程的常识,主要来自<Beginning Linux Programming> 的第一章。

  • /bin: 二进制文件目录,用于存放启动系统时用到的二进制文件。
  • /usr/bin: 用户二进制文件目录,用于存放用户使用的标准程序。
  • /usr/local/bin: 本地二进制文件目录,用于存放特定软件安装的程序。
  • /opt: 可选的操作系统组件和第三方应用可以安装在这个目录。可以将路径添加到PATH。
  • /usr/include: 系统的标准库函数。
  • /usr/include/sys及 /usr/include/linux: 一般放置依赖于特定系统的头文件。

如果没有用 -o 选项告诉编译器将可执行文件放在何处,则会默认将程序放到一个名为a.out的文件里,而a.out的意思是:assembler output,即汇编输出。

库文件的类型:

  • .a :archive 代表传统的静态函数库,类似于windows中的LIB文件,包含在可执行文件中。
    静态库的一个缺点是:如果同时运行多个应用程序,且使用来自同一个函数库时,内存中会有多个相同的拷贝,这将浪费大量的内存和磁盘空间。
  • .so :shared object 代表共享函数库,类似于windows中的dll文件,在程序运行时加载。
    程序使用共享库时的链接方式是这样的:它本身不再包含函数代码,而是引用时可访问的共享代码,当编译好的程序被装载到内存中执行时,函数引用被解析并产生对共享库的调用,如果有必要才被加载到内存中。
    可以使用ldd命令来查看程序所信赖的共享库。

在 gcc 中,参数 -lm 表示链接名为libm的库,并且,编译器会优先选择共享库。而 -L则表示添加库的搜索路径。-c 表示阻止编译器创建一个完整的程序。

$ gcc -c bill.c fred.c                           #生成目标文件
$ ar crv libfoo.a bill.o fred.o                  #生成静态库文件
$ gcc -o program program.o -L. -lfoo             #指定库文件位置

info 的优点是:可以通过链接或者交叉引用来浏览文档并可直接跳转到相关的章节。

> 重定向
>> 将输出附加到一个文件中。

0:标准输入
1:标准输出
2:标准错误

Categories: C++, Linux Tags:

C++ Primer 学习笔记:数组和指针 (2)

March 9th, 2010 leeing No comments

C++ Primer 学习笔记四:数组和指针 (2)

1. 指向const 对象的指针。

如果指针指向const对象,则不允许用指针来改变其所指的const值,C++ 语言强制要求指向const对象的指针也必须具有const特性。

const double *cptr; // cptr may point to a double that is const.

注意这里cptr本身并不是一个const,可以让它指向另一个double对象(可以不是const类型的),但是不能通过cptr来改变所指对象的值。

不能使用void* 指针保存const对象的地址,必须使用const void* 类型的指针保存const对象的地址:

const int universe = 42;
const void *cpv = &universe;

允许把非const对象的地址赋给指向const对象的指针,例如:

double dval = 3.14;
const double *cptr = &dval; // const double* 型的指针可以指向double类型对象。

*cptr = 1.0 // 会产生编译错误,通过它修改对象的值。
const double pi = 3.1415926

cptr = &pi; // 可以给cptr 重新赋值
double cptr1 = &pi; // 编译错误,必须用const double* 型的指针来指向 const double对象。

虽然dval不是const对象,但不允许通过cptr来修改其值。

不能使用指向const对象的指针修改基础对象,然而如果该指针指向的是一个非const对象,则可以用其它方法修改其所指的对象。

将const对象认为是“自以为指向const的指针”可以更好地理解这个概念。

2. const指针。

const指针代表指针本身的值不能修改,即不能修改它所指向的对象。但是指针本身是const的事实没有说明是否能使用该指针修改它所指向的对象的值:指针所指的对象的值能否修改完全取决于该对象的类型。

一般的声明方式是:

int errnum = 0;
int *const curerr = &errnum;

3. 指向const对象的const指针。

const double pi = 3.14159;
const double *const pi_ptr = &pi;

表示:pi_ptr首先是一个const指针,其次它指向double型的const对象。

4.指针和typedef。

使用typedef 经常带来意外的结果,例如:

typedef string *pstring;
const pstring cstr;

因为typedef并不是文本扩展,在这里声明const string时,const修饰的是pstring类型,这是一个指针,因此该声明语句应该是把cstr定义为指向string类型对象的const指针。

所以它等价于下面的代码:

string *const cstr; // 而不是:const string* cstr;

用typedef写const类型定义时,const限定符加在类型名前面容易引起对所定义的真正类型的误解,下面三种声明意义都是相同的:

string s;
typedef string *pstring;
const pstring cstr1 = &s;
pstring const cstr2 = &s;
string *const cstr3 = &s;

习惯于将const置于前面,但是把声明语句重写为置const于类型之后更易于理解。

Read more…

Categories: C++ Tags: