`
阿尔萨斯
  • 浏览: 4169968 次
社区版块
存档分类
最新评论

C和指针 (pointers on C)——第八章:数组(上)

 
阅读更多
第八章数组


本章原书作者的意图主要是跟指针进行比较,两者的共同点以及区别。因为小弟我的汇编基础为0,因此8.1.4指针的效率这一块我实在是不明白。
本科时候学的数组绝对不会像现在一样学数组,所以好好学数组!
它和指针在作为函数参数传递时是不是可以混用?
声明数组和声明指针在编译过程中是否相同?
形参可以省略几个下标,为什么?
char *a = "hello";和char a[]="hello";有什么区别?
指向整型指针的指针和指向整形数组的指针有什么区别?


总结:
数组名的值绝大多数的情况中是指向第一个元素的指针。除了sizeof:返回值为整个数组所占用的字节。&:返回一个指向数组的指针,都不是指向第一个元素的指针。
关于下标表达式 array[value]和间接访问表达式*(array+(value))是一样的。因此,下标不仅可以用于数组名,也可以用于指针表达式。
指针表达式效率更高,但是代码的可维护性更加需要,因此,还是要以更清晰的表达为好。
指针在声明时候值分配了容纳指针的空间。
数组实际上是一个指针常量,当我们声明一个数组时,它同时也分配了一些内存空间。
当数组名作为函数参数传递时,实际传递给函数的是一个指向数组第1个元素的指针。函数所接受到的参数实际上是原参数的一份拷贝,所以函数可以对其操作而不会影响实际的参数。
当指针参数做函数参数传递时,是可以修改原参数的。
但是当函数声明的时候:
int strlen(char *string);
int strlen(char string[]);这样是相等的。但也只有这样是相等的。


关于初始化:
数组可以用一对花括号包围一组值来作为初始值列表。当列表值少于数组长度时,那么将使用缺省值进行初始化。
字符串数组也可以用一种很像字符串常量的快速方法进行初始化。
char *a = "hello";和char a[]="hello";
前者很明显是个字符串常量。后者“”里面只是代表一个数组初始化列表。


多维数组的存储顺序,是对最右边的下标率先变化。
多维数组名的值是一个指向它第一个元素的指针,也就是一个指向数组的指针。
当一个对位数组名作为参数传递给函数时候,第一维以后必须显式得指明长度。这样编译器才能推断出每一个子数组维数的长度。


关于指针数组:
两种方式。一是矩阵形式:
char keyword[][10]=
{ "do",
"for",
"if"
};
这样以来,这个矩阵将包含NUL终止符。而且每一行的长度相同。
char keyword[] =
{
"do",
"for",
"if",
'\0'
};
这样一来,这就是一个指针的数组,每一行长度会自动调整,会多一个指针数组的大小空间。


警告:
1、当访问多维数组元素时,误用逗号分割下标:
int a[3][4];//right
int a[3,4];//实际上只是声明了a[4]
2、在一个指向未显式声明长度的数组的指针上执行指针运算。
int matrix[3][10];
int *p =matrix;//错误,matrix并不是指向整型的指针,而是一个指向整型数组的指针。
应该这样声明:int (*p)[10] = matrix;


编程提示:
1、一开始就编写良好的代码显然比依赖编译器来修正劣质代码更好。
2、源代码的可读性几乎总是比程序的运行时效率更重要;
3、只要有可能,函数的指针形参都应该声明为const。
理由有三:一、一种更好的文档习惯,有些人希望观察函数原型就能发现数据不能被修改。
二、编译器可以捕捉到任何试图修改数据而意外产生的错误。
三、这类声明允许向函数传递const参数。
4、在多维数组的初始值列表中使用完整的多层花括号能提高可读性。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics