2011-01-07 41 views
15
int* myPointer = new int[100]; 

// ... 

int firstValue = *(myPointer + 0); 
int secondValue = myPointer[1]; 

Có sự khác biệt về chức năng giữa *(myPointer + index)myPointer[index] không? Cách nào được coi là thực hành tốt hơn?Sự khác biệt giữa * (Con trỏ + Chỉ mục) và Con trỏ []

+8

Bạn quên: 'int thirdValue = 2 [myPointer];' Mà crazily cũng hoạt động. –

+0

@Martin Thật sao? Huh. Tìm hiểu một cái gì đó mới mỗi ngày, tôi đoán. – Maxpm

+3

@Maxpm - [Array subscripting là giao hoán trong C] (http://c-faq.com/aryptr/joke.html) – jww

Trả lời

30

Chức năng, chúng giống hệt nhau.

Ngữ nghĩa, con trỏ dereference nói "Đây là một điều, nhưng tôi thực sự quan tâm đến không gian X", trong khi truy cập mảng nói "Đây là một loạt các điều, tôi quan tâm đến Xth."

Trong hầu hết các trường hợp, tôi muốn biểu mẫu mảng.

+2

Ai đó đã bỏ phiếu này xuống? Tôi muốn mọi người bình luận, và cho tôi biết có gì sai với câu trả lời của tôi. –

+0

Không phải tôi, nhưng trong trường hợp này nó không phải là 'Xth' nhưng là' X + 1th'. –

+5

@Fritschy: Vâng, như các lập trình viên, tôi cho rằng chúng ta đếm từ 0;) –

11

Không, chúng có chức năng tương đương.

Đầu tiên, index được thu nhỏ theo kích thước loại sau đó được thêm vào cơ sở myPointer, sau đó giá trị được trích xuất từ ​​vị trí bộ nhớ đó.

Cách thực hành tốt hơn là cách thực hành dễ đọc hơn, thường là, nhưng không nhất thiết phải luôn là biến thể myPointer[index].

Đó là vì bạn thường quan tâm đến yếu tố của mảng, chứ không phải là vị trí bộ nhớ để dereference.

3

Không có sự khác biệt về chức năng mà tôi biết nhưng biểu mẫu myPointer[1] hoàn toàn dễ đọc hơn và ít có khả năng xảy ra lỗi mã hóa hơn.

DC

Dạng *(myPointer + 1) không cho phép thay đổi kiểu của con trỏ đến một đối tượng và do đó nhận được quyền truy cập vào toán tử [] quá tải.

Cũng gỡ lỗi là xa khó

int *ints[10]; 
int myint = ints[10]; 

là dễ dàng hơn để đón trực quan hơn

int *ints; 
int myint = *(ints + 10); 

cũng trình biên dịch có thể chèn phạm vi kiểm tra để bắt lỗi tại thời gian biên dịch.

DC

+0

+1 - toán tử điểm chính re 'operator []' quá tải. –

+0

Nhưng khi bạn cần địa chỉ, biểu mẫu 'ints + 10' tốt hơn' & ints [10] '. – ruslik

+0

Nếu bạn cần địa chỉ mà bạn không quan tâm đến toán tử quá tải [], và tránh nó an toàn hơn. –

0

Mã dễ đọc hơn và dễ bảo trì hơn là mã tốt hơn.

Đối với phần chức năng ... Không có sự khác biệt. Cả hai lần bạn đang "chơi với bộ nhớ".

1

Không có sự khác biệt về chức năng. Quyết định sử dụng một trong hai biểu mẫu thường được thực hiện tùy thuộc vào ngữ cảnh mà bạn đang sử dụng nó. Bây giờ trong ví dụ này, dạng mảng đơn giản hơn để sử dụng và đọc và do đó là sự lựa chọn hiển nhiên. Tuy nhiên, giả sử bạn đang xử lý một mảng ký tự, nói rằng, tiêu thụ các từ trong một câu. Cho một con trỏ đến mảng bạn có thể tìm thấy nó dễ dàng hơn để sử dụng hình thức thứ hai như trong đoạn mã dưới đây:

int parse_line(char* line) 
{ 
    char* p = line; 
    while(*p) 
    { 
     // consume 
     p++; 
    } 
    ... 
} 
18

Không có sự khác biệt giữa

*(array+10); //and 
array[10]; 

nhưng đoán những gì?kể từ +associative

*(10 + array); //is all the same 
10[array]; //! it's true try it ! 
+1

Điều này đúng bởi vì '+' là giao hoán. Hoạt động '+' cũng là kết hợp, nhưng điều này không quan trọng ở đây. – rcode

0

Trên thực tế, Khi một mảng 'a' được khởi tạo một con trỏ đến vị trí bộ nhớ đầu tiên của nó tức là .. a [0] được trả về đó là gì, nhưng một;

Vì vậy, nếu bạn làm 'a + 1' nó thực sự là một con trỏ đến một [1]

nếu bạn làm 'a + 2' nó thực sự là một con trỏ đến một [2]

nếu bạn thực hiện 'a + 3' nó thực sự là con trỏ đến [3] , v.v.,

vì vậy nếu bạn làm * (a + 1) bạn sẽ nhận được giá trị của [1] và tương tự cho các giá trị khác . nếu bạn làm * (a) bạn thực sự nhận được [0], Vì vậy, tôi nghĩ rằng nó khá rõ ràng bây giờ như thế nào nó hoạt động ..

Các vấn đề liên quan