2015-05-12 24 views
7

Giả sử rằngSự khác nhau giữa mảng và mảng là gì?

int array[16]; 

Có được chuyển đổi tiêu chuẩn gọi là chuyển đổi mảng-to-con trỏ, vì vậy array sẽ được chuyển đổi ngầm để gõ int*, nhưng tại sao &array bằng array?

Ví dụ,

int array[16]; 
void *p = array; 
void *q = &array; 
printf("%p\n", p); 
printf("%p\n", q); 

Điều này sẽ cho ra cùng một địa chỉ và không có lỗi biên dịch.

Tại sao?

Trả lời

2

Đó là cách tên mảng hoạt động trong C.

Tên của biến mảng đại diện cho địa chỉ của phần tử đầu tiên của mảng.

vậy,

void *p = array; //array name, gives address of the first element. 

void *q = &array; //adress-of-array name, also gives address of the first element 
        // actually &array is of type int (*)[16] which is decayed to int * 
        // and casted to void * here 

T.B. Thậm chí, FWIW,

void *r = &array[0]; //address of the first element 

cũng sẽ cung cấp cho bạn địa chỉ giống nhau.

Điều này sẽ phát ra cùng một địa chỉ và không có lỗi biên dịch.

Chúng thực sự là giá trị giống nhau và trình biên dịch tại đây không có gì để hét lên.

Điểm cần lưu ý: khi bạn chỉ định (các) địa chỉ cho con trỏ trống, bạn sẽ mất thông tin loại được liên kết với chúng.

0

Một mảng trong C hoạt động như một con trỏ đến địa chỉ của phần tử đầu tiên trong bộ nhớ.

+0

Không hoàn toàn đúng. Trong hầu hết các trường hợp, một tên mảng phân rã thành một con trỏ tới phần tử đầu tiên trong mảng, nhưng lấy ví dụ này: 'char foo [20] =" bar "; size_t size = sizeof foo; ', nếu' foo' sẽ là con trỏ, 'size' sẽ là 4 hoặc 8, nhưng trên thực tế nó sẽ là 20 –

+0

@EliasVanOotegem cảm ơn vì đã chỉ ra điều này, bạn chính xác –

0

Bởi vì bạn đang về cơ bản nói điều tương tự trong hai dòng sau:

void *p = array; // Pointer to array, which is an address 
void *q = &array; // Pointer to reference to an array, which is basically saying "A pointer to the same address as the pointer". 

Nói cách khác:

void *p; 

là giống như:

&array; 
10

Loại của &arrayint (*)[16] (một con trỏ đến một mảng gồm 16 số nguyên). Loại array, khi còn lại để phân rã, là int* (con trỏ đến số nguyên). Cả hai đều trỏ đến cùng một vị trí, nhưng có một ý nghĩa khác với trình biên dịch.

Nếu bạn làm (&array)[0], giá trị bạn kết thúc bằng mảng ban đầu là 16 số nguyên, bạn có thể lập lại chỉ số, như (&array)[0][0]. (&array)[1] sẽ là mảng tiếp theo của 16 số nguyên, nếu có.

Nếu bạn làm array[0], giá trị bạn kết thúc bằng số nguyên mà bạn không thể lập lại được. array[1] chỉ là số nguyên tiếp theo. (Điều này đúng bất kể nếu array là một int[16] hoặc một int*.)

Rõ ràng, nếu bạn rồi bật con trỏ của bạn vào void con trỏ, bạn sẽ mất bất kỳ sự khác biệt ngữ nghĩa có thể có được.

0

Biểu Loại ---------- ---- & mảng trống () [10] - con trỏ đến mảng 10 phần tử của void * & array [0] void * * - con trỏ đến con trỏ để làm mất hiệu lực

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