指针和数组的效率问题
在继续阅读前, 建议读者拥有计算机组成原理相关只是背景
考虑如下代码
//数组方法
for(int i = 0; i < 10; i++)
{
array[i] = 0;
}
和代码
指针方法
for( ap = array; ap < array+10; ap++)
{
*ap = 0;
}
在数组方法中, 每次指令先取出i的值, 然后根据每一个array元素的长度并乘法计算(例如对于int来说,通常乘以4), 得到真正偏移地址的长度, 最后赋值. 简而言之,取值,乘法
在指针方法中, 区别在于, 每次的循环中, 将ap加4, 中间并没有乘法操作. 简而言之, 取值,加法 我们知道, 乘法操作需要的时钟周期是加法的几倍甚至几十倍. 由此可见, 虽然数组法容易阅读, 但是指针法的效率更高, 生成代码片段更小
效率并不是总是最高, 当指针法也被迫参与到乘法计算中, 那么效率就会甚至相同
比如代码
a = get_value();
*(array + a) = 0;
这里的指针法也需要乘法计算地址, 因此并没有效率提高.
声明一个二维指针
int (*p)[10]
p里的每一个int元素都有[10]的容量, 注意[]的运算优先级比*高
声明一个数组, 里面每一个元素都是int指针
int *p[10]
p是一个[10]元素的数组, 数组里的元素类型为int*
声明string的两种方式
//方式1
char const *keyword[] = {
"do",
"for",
"if",
"register",
"switch"};
这种方式声明的string数组, 每一个keyword[]都被存储在随机的区域,并不连续
评价: char *keyword里面存储了多余的指针, 可能浪费空间
//方式2
char const keyword[][9] = {
"do",
"for",
"if",
"register",
"switch"}
这种方式的第二个维度依据最长单词设定, 所有单词都存在连续区域中
评价: 浪费空间, 当然, 如果所有单词长度都差不多, 空间浪费就小于方案1
对于方案1, 我们还可以在*keyword数组中追加一个NULL元素, 此NULL可以让函数遍历时检查是否到达了末尾
sizeof问题
sizeof(&array) 返回第一个元素的指针的大小
网友评论