2013-01-12 60 views
10

Câu hỏi của tôi là căn cứ vào đoạn mã sau:C con trỏ ký hiệu so với ký hiệu mảng: Khi đi qua với chức năng

int myfunct(int ary[], int arysize) 
int myfunct2(int *ary, int arysize) 

int main(void){ 
    int numary[10]; 
    myfunct(numary, 10) 
    myfunct2(numary, 10) 
    return; 
} 

int myfunct(int ary[], int arysize) { 
     //Whatever work is done 

    } 

int myfunct2(int *ary, int arysize) { 
    // Whatever work is done 

    } 

Có một lý do để sử dụng một trong những khác không? Để xây dựng, khi có liên quan với mảng số, có bất kỳ lý do nào sẽ muốn sử dụng ký hiệu con trỏ trên ký hiệu mảng. Nếu người ta sử dụng ký hiệu con trỏ thì trong số học con trỏ hàm sẽ được sử dụng vv .. VÀ nếu người ta sử dụng ký hiệu mảng [], người ta có thể làm việc với mảng như bình thường. Tôi mới lập trình và hiện tại tôi không thấy bất kỳ lợi ích nào khi sử dụng ký hiệu con trỏ.

Câu hỏi chính xác của tôi là có bất kỳ lý do gì để chuyển một mảng số tới hàm bằng cách sử dụng ký hiệu con trỏ và do đó sử dụng thao tác con trỏ trong hàm.

Trả lời

8

Không có sự khác biệt chức năng thực sự giữa hai ký hiệu. Trong C, khi bạn chuyển một biến mảng tới một hàm, nó sẽ phân rã thành một con trỏ bất kể ký pháp. Tuy nhiên, theo ý kiến ​​của tôi, ký hiệu con trỏ thích hợp hơn là. Vấn đề với [] ký hiệu trong định nghĩa hàm là, theo ý kiến ​​của tôi, nó là một chút nhầm lẫn:

void foo(int array[]) 
{ 

} 

Một sai lầm phổ biến trong lập trình C mới là giả định rằng sizeof(array) sẽ cung cấp cho bạn số lượng của các yếu tố trong mảng nhân với sizeof(int), giống như nếu array là một biến mảng được khai báo trên ngăn xếp. Nhưng thực tế là array đã bị phân rã thành con trỏ, mặc dù ký hiệu sai lệch [] và do đó sizeof(array) sẽ là sizeof(int*). array thực sự chỉ là một con trỏ đến phần tử đầu tiên, hoặc có thể là một con trỏ tới một số nguyên được phân bổ ở bất kỳ đâu.

Ví dụ, chúng ta có thể gọi foo như thế này:

int x = 10; 
foo(&x); 

Trong trường hợp này, [] ký hiệu trong định nghĩa của foo là loại gây hiểu nhầm.

+0

Vì vậy, nếu tôi sử dụng * ary trái ngược với ary [], tôi có thể sử dụng ary [0] trong hàm không? – SystemFun

+0

@Vlad, vâng ............, –

+0

@Vlad Tôi nghĩ bạn đã hiểu câu trả lời của tôi? 'ary [0]' là '* (ary + 0)' là '* ary', bất kể ngữ cảnh. Nếu bạn có thể sử dụng nó, bạn có thể sử dụng cái kia (trong biểu thức, nghĩa là). – melpomene

10

Khi bạn khai báo tham số hàm dưới dạng mảng, trình biên dịch sẽ tự động bỏ qua kích thước mảng (nếu có) và chuyển đổi nó thành con trỏ. Đó là, tuyên bố này:

int foo(char p[123]); 

là 100% tương đương với:

int foo(char *p); 

Trong thực tế, đây không phải là về ký hiệu nhưng về kiểu thực tế:

typedef char array_t[42]; 
int foo(array_t p); // still the same function 

này có không liên quan gì đến cách bạn truy cập p trong chức năng. Hơn nữa, toán tử [] không phải là "ký hiệu mảng". [] là một nhà điều hành con trỏ:

a[b] 

là 100% tương đương với:

*(a + b) 
+0

Tôi hiểu điều đó. Câu hỏi của tôi đề cập đến các thao tác sẽ được thực hiện trong hàm đó. – SystemFun

+1

@Vlad Nếu câu hỏi của bạn là về bên trong của hàm, tại sao mã ví dụ của bạn là tất cả mọi thứ nhưng điều đó? – melpomene

-1

Bạn chỉ cần sử dụng các ký hiệu mảng cho mảng đa chiều. (Bạn không phải cung cấp kích thước của thứ nguyên đầu tiên).

1

Các tuyên bố đó hoàn toàn giống nhau. Để trích dẫn tiêu chuẩn:

Một tuyên bố của một tham số là "mảng của kiểu" sẽ được điều chỉnh để "con trỏ đủ điều kiện để gõ"

C99 phần tiêu chuẩn 6.7.5.3 đoạn 7

0

Trong C hiện đại có các mảng độ dài biến đổi kể từ C99, ký hiệu mảng là thích hợp hơn nếu là một mảng, tôi nghĩ vậy. Đối với một mảng chiều, bạn có thể làm những việc như

int myfunct(size_t size, int array[size]) { 
    ... array[i] .. 
} 

và cho hai chiều

int myfunct(size_t size, int array[size][size]) { 
    ... array[i][j] .. 
} 

Vì vậy, ký hiệu mảng phù hợp hơn nhiều trong bức tranh chung. Một trình biên dịch tinh vi sau đó thậm chí có thể làm kiểm tra giới hạn, nhưng tôi không biết bất kỳ điều đó thực hiện điều này được nêu ra.

+0

Lưu ý rằng trong trường hợp một chiều, 'int array [size]' có cùng tác dụng với 'int * array', tức là' mảng' vẫn là một con trỏ, và 'size' là thừa, ngoại trừ để dùng làm tài liệu . Trong trường hợp 2-D, kiểu 'mảng' là' int (*) [size] '. –

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