通过指针算术而不是[]运算符引用访问数组元素是否不好?


12

我刚刚开始学习用C编程,并且为了提高对指针和数组的理解,我尝试引用数组的元素而根本不创建任何指针:

for(k1 = 0; k1 < ROW; k1++){
    for(k2 = 0; k2 < COLUMN; k2++){

        array[k1][k2] = k1*COLUMN + k2 + 1;

        printf("[%d][%d] = %d\n", k1, k2, *(array[k1] + k2));

    }
}

整个代码可以编译并完美运行。

我想必须在大型源代码中为每个数组创建一个指针似乎效率很低。

因此,与其使用指针存储和检索数组的地址,不如上面所示,直接使用数组的地址是一种不好的编程习惯吗?


使用printf "[%d][%d] = %d\n", k1, k2, array[k1] [k2]));将避免指针的算术运算,并且更易于理解。
卡斯珀范登伯格2015年

1
哈哈,你救了我。我这样做只是为了更好地了解指针和数组的工作原理。
Niko Gambt 2015年

指针算术实际上比使用数组索引快30%。
安迪

Answers:


16

它的“坏”之处在于难以理解的程度。a[x]与相同*(a+x),因此效率或行为没有差异(实际上x[a]也可以)。只是a[x]对我们人类而言通常更直观。

但这并不是说可读性不是大问题。要查看有多大,请考虑一下如果在代码中看到这两个表达式,将如何“读取”它们:

  • *(a+x)=“指针a和整数之和所指向的东西x
  • a[x]=“ x数组的第一个成员a

同样,当您需要引用数组元素的地址时:

  • (a+x)=“指针a与整数之和x
  • &a[x]=“ x数组的第th个成员的地址a

在大多数情况下,[]当您查看在多个不同数组(尤其是数组数组)上运行的非平凡代码时,这些版本就更容易理解。这就是为什么[]运算符首先存在的原因。

PS严格将这种事情作为学习练习是一个非常好的主意。重要的是要了解数组实际上只是指针和偏移量。


这个。谢谢。我刚刚真正地了解到,什么时候需要引用任何数组元素的地址,然后再引用另一个元素的地址,然后再引用另一个元素的地址,是否仍然不好?不使用指针,而是直接使用数组?我的这个问题确实很难弄清楚,这就是为什么我没有在OP中键入它的原因。无论如何,由于我没有问,您的回答是令人满意的。
Niko Gambt 2015年

1
@NikoGambt您总是可以问另一个问题=)
Ixrec

1
你的意思仅仅是…… 编程语言的全部目的是使代码更易于人类阅读。如果我们不在乎,那么我们都将以十六进制编写操作码。
所罗门慢

2
数组不是指针,只是隐式衰减到指针。
CodesInChaos

4

是的,这是不好的做法,但不是出于效率低下的原因。

数组运算符在幕后使用了算术指针,因此它们同样有效。

指针算术的问题是它很容易出错并且更难阅读。

经验法则:除非必须使用指针算术。


1
由于它仍然使用指针算术,这是否意味着指针也同样容易出错且难以读取?
Niko Gambt 2015年

1
@NikoGambt编译器非常擅长在后台进行指针算术运算,并且很少犯“错误”;结果是程序员会因讨厌的错误而犯错。
卡斯珀范登伯格2015年

@KaspervandenBerg是的,我同意。但是,我对程序员犯的错误很感兴趣,只是不确定是否需要引用数组的地址来执行上面的操作是否是不好的编程习惯? ,如果确实存在这种情况。
Niko Gambt 2015年

1
@NikoGambt书写的东西是不太可读出于性能几乎总是不好的做法,但写的东西是不太可读,而并无益处是明确不好的做法。
尼尔

@尼尔我的小实验不是没有意义的。通过这样做,我了解到编译器似乎制作了一个指针数组来引用多维数组。但是,由于您说可读性比性能更重要,所以我认为它仍然是不好的编程习惯。
Niko Gambt 2015年

0

冷静学习c,您刚刚发现了c种绕口令。您不是对数组进行指针算术运算,而是对指针数组进行运算。无法对数组执行指针算术运算。数组会衰减为指针,但不是其自身的指针类型。我所拥有的(请参阅cmaster的评论)是

int *array[]; //This is a array to pointers of type *int. 

array[k1] + k2; //This is pointer arithmetic on one pointer stored in the array  

取消引用此指针可得到您刚刚计算出的指针所指向的值。通常做的事情没有意义。但是您可以像这样线性化数组,然后大步向前。

int array[y_dim*x_dim]; 
int index = x_dim*y + x; 
array[index]; //Gives you the element in x, y!

大步走她是x_dim。希望我的答案是澄清的!


是否使用了它不是从OP清晰int* array[ROW];int array[ROW][COLUMN];,或int (*array)[COLUMN];。这三个定义中的任何一个都可以与OP中的代码一起使用。
cmaster-恢复莫妮卡

是的,我知道这一点,对此我的回答有点笨拙。我纠正了,谢谢!
fhtuft
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.