1、静态与自动初始化:
变量的初始化取决于它的存储类型,存储于静态内存中的变量只初始化一次,并且它的初始化是在程序开始之前,程序并不需要执行任何指令把需要初始化的值放到合适的位置,它们从程序开始运行时就在那里了,这个任务是由链接器来完成的;它用可执行文件中合适的值对变量进行初始化,如果变量未被初始化,变量的初始值将会被设为零。当文件在载入内存准备执行时,已经初始化的变量值和程序指令一样被载入内存中,因此在程序执行时静态变量已经初始化。
然而自动变量就没有这么幸运了,因为它运行在运行时堆栈中,执行流每次进入他们所在的代码块时,这类变量每次所处的内存位置可能并不相同,在程序开始运行之前,编译器无法对这些位置进行初始化,如果自动变量在声明时给出了初始值,则执行流在每次执行到这个自动变量声明所在的位置时都会使用一跳隐式的赋值语句来进行初始化,这条隐式的赋值语句和普通的赋值语句是相同的也需要时间和空间来执行它。
当然数组的初始化也遵循变量的初始化特征,因此如果一个数组在初始化列表中有很多的值,并且声明的是自动变量,那么就可能有很多条赋值语句,对于那些非常庞大的数组,这个数组初始化所需要的时间也将持续增加。因此当数组的初始化局部于一个函数或者代码块时,就应该考虑效率方面的因素了,在程序执行流在每次进入该函数或代码块时,每次都对数组进行一次初始化是不是值得的。如果答案是否,就应该把数组声明为static,这样初始化只需开程序开始之前执行一次。
2、多维数组:先举一个例子 int arr[4][6]; 例子中的arr到底是6行4列还是4行6列呢? 实际上两种说法都可以,因为多维数组在内存中的存储并不是按它所标注行列数来存储的,还是顺序存储的,我们给其标注一个行列号知识为了形象的表示多维数组,只要我们每次按照同一种行列的表示方式就不会出现问题,因为无论是怎样解释行和列都不会改变数组在内存中的存储顺序,我们只需要找到表示这个数组存储最合理的解释方式就可以了,也就是说arr[4][6] 和 arr[24] 所表达的是同一个意思知识表现方式不同罢了,当然你还可以写成arr[2][12]、arr[3][8];但是这些表现方式相同只是针对其在内存中的存储方式而言,在实际的编程中arr[4][6]和arr[24]还是不同的,例如在arr[4][6]中arr[1]表示的是指向一个包含有6个元素的数组的指针常量;而在arr[24]中arr[1]表示的是数组arr[24]中的第二个元素,如果这个表达式作为左值则表示arr[]只第二个元素所在的内存位置,如果作为右值则表示第二个元素所在位置存储的值。在arr[4][6]中数组名arr的含义是一个指向整型数组的指针,而在arr[24]中数组名arr的含义是一个指向整型的指针。
3、多维数组的访问:多维数组的可以使用下标的形式也可以使用指针的形式,这是因为多维数组和一维数组一样,下标访问知识指针访问的一种伪装的形式,因此下面的表达式是相等的:
arr[1][3];
*(*(arr+1) + 3);
*(arr[1] + 3);
(*(arr+1))[3];
4、这里需要注意一下两种声明的差别:
第一种声明:
char str[4][6] =
{
"Hello", "Word", "OK"
};
第二种声明:
char *pstr[4] =
{
"Hello", "Word", "OK"
};
这两种声明看起来很类似实际上他们在编程中的表现形式差异很大,在内存中的存储方式也很大,在这里首先需要理解的是这两种声明到底声明的是什么,只要搞清楚这个,他们之间的差别就自然而然的知道了:
第一种声明声明了一个二维数组,数组中的元素是字符;第二种声明声明了一个一维数组,而这个一维数组中的元素是指向字符串的指针。只要弄清楚了这个,他们之间的区别就很容易理解,至于他们之间到底有什么区别编程中可以自己理解。