C/C++学习笔记-02

C++学习笔记-02

C++中的逗号表达式

使用逗号运算符的为了把几个表达式串在一起。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。从本质上讲,逗号的作用是导致一系列运算被顺序执行。

最右边的那个表达式的值将作为整个逗号表达式的值,其他表达式的值会被丢弃。例如:

var = (count=19, incr=10, count+1);

在这里,首先把 count 赋值为 19,把 incr 赋值为 10,然后把 count 加 1,最后,把最右边表达式 count+1 的计算结果 20 赋给 var。上面表达式中的括号是必需的,因为逗号运算符的优先级低于赋值操作符。

下面看一个列子:

#include 
using namespace std;

int main()
{
    int i, j;

    j = 10;
    i = (j++, j+100, 999+j);

    cout << i;

    return 0;
}       

二维数组

二维数组必须指定列的数量,行的数量可以不指定,二维数组的初始化方式有以下几种:

(1)分行进行初始化

int a[2][3]={{1,2,3},{4,5,6}}; 
在{ }内部再用{ }把各行分开,第一对{ }中的初值1,2,3是0行的3个元素的初值。第二对{ }中的初值4,5,6是1行的3个元素的初值。
相当于执行如下语句: int a[2][3]; a[0][0]=1;a[0][1]=2;a[0][2]=3;a[1][0]=4;a[1][1]=5;a[1][2]=6; 
注意,初始化的数据个数不能超过数组元素的个数,否则出错。

(2)不分行的初始化

int a[2][3]={ 1,2,3,4,5,6}; 
把{ }中的数据依次赋给a数组各元素(按行赋值)。即a[0][0]=1; a[0][1]=2;a[0][2]=3;a[1][0]=4;a[1][1]=5;a[1][2]=6;

(3)为部分数组元素初始化

static int a[2][3]={{1,2},{4}}; 
第一行只有2个初值,按顺序分别赋给a[0][0]和a[0][1];第二行的初值4赋给a[1][0]。由于存储类型是static,故其它数组元素的初值为0。注:某些C语言系统(如:Turbo C)中,存储类型不是static的变量或数组的初值也是0。 
static int a[2][3]={ 1,2}; 
只有2个初值,即a[0][0]=1,a[0][1]=2,其余数组元素的初值均为0。 

(4)可以省略第一维的定义,但不能省略第二维的定义。系统根据初始化的数据个数和第2维的长度可以确定第一维的长度。

int a[ ][3]={ 1,2,3,4,5,6}; 
a数组的第一维的定义被省略,初始化数据共6个,第二维的长度为3,即每行3个数,所以a数组的第一维是2。 
一般,省略第一维的定义时,第一维的大小按如下规则确定: 
初值个数能被第二维整除,所得的商就是第一维的大小;若不能整除,则第一维的大小为商再加1。例如,int a[ ][3]={ 1,2,3,4};等价于:int a[2][3]={ 1,2,3,4}; 
若分行初始化,也可以省略第一维的定义。下列的数组定义中有两对{ },已经表示a数组有两行。 
static int a[ ][3]={{1,2},{4}};

动态链接库与静态链接库

库有两种,一种是静态链接库,一种是动态链接库,不管是哪一种库,要使用它们,都要在程序中包含相应的include头文件。我们先来回顾一下程序编译的过程。如下图:

1、静态链接库

链接阶段,将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。该可执行文件可能会比较大。

这种链接方式的好处是:方便程序移植,因为可执行程序与库函数再无关系,放在如何环境当中都可以执行。

下面写一个简单的函数,生成库文件 头文件为:  对应的源文件为: 

下面生成静态库: 输入:g++ -c print.cpp 生成.o目标文件

然后用ar命令进一步生成库libprint.a:

ar -crv libprint.a libprint.o

这样就生成了一个静态链接库libprint.a。

然后写一个测试文件: 

下面编译一下该文件:

g++ -o atest main.cpp -L ./ -l print
-L是指定加载库文件的路径
-l是指定加载的库文件 

一旦可执行文件生成后,静态链接库可删除,不影响程序正常运行。

2、动态链接库

动态链接有一个缺点就是可移植性太差,如果两台电脑运行环境不同,动态库存放的位置不一样,很可能导致程序运行失败。 在具体的应用中,静态与动态应当合理选择!!!

先面用上面的代码生成一个动态链接库:

输入:g++ -fPIC -shared -o libprint.so print.cpp

这样就生成了一个libprint.so的动态库

同样的以动态链接的方式编译main.cpp:g++ -o sotest main.cpp -L ./ -l print

注:执行时会报错:./sotest: error while loading shared libraries: libprint.so: cannot open shared object file: No such file or directory 这是因为在/etc/ld.so.conf文件中没有设置动态库寻找的路径,在ld.so.conf文件下面添加包含我们的so 文件的目录,然后sudo ldconfig一下就行了。 

此种方式生成可执行文件后,动态链接库不能删除,否则程序运行不了。 最后,比较两种方式生成的文件的大小,如图: 

附录:

g++(gcc)编译选项 l -shared :指定生成动态链接库。

l -static :指定生成静态链接库。

l -fPIC :表示编译为位置独立的代码,用于编译共享库。目标文件需要创建成位置无关码,念上就是在可执行程序装载它们的时候,它们可以放在可执行程序的内存里的任何地方。

l -L. :表示要连接的库所在的目录。

l -l:指定链接时需要的动态库。编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a/.so来确定库的名称。

l -Wall :生成所有警告信息。

l -ggdb :此选项将尽可能的生成gdb的可以使用的调试信息。

l -g :编译器在编译的时候产生调试信息。

l -c :只激活预处理、编译和汇编,也就是把程序做成目标文件(.o文件)。

l -Wl,options :把参数(options)传递给链接器ld。如果options中间有逗号,就将options分成多个选项,然后传递给链接程序。

你可能感兴趣的:(C/C++学习笔记-02)