Tại sao trong mảng int a[]; a và &a có cùng giá trị địa chỉ

Nếu em khai báo 1 mảng là:

int a[5];

printf("%p\n", a);
printf("%p", &a);

thì lại cùng in ra 1 địa chỉ là 22FE30;

a trỏ đến địa phần tử đầu tiên của mảng có địa chỉ là: 22FE30;
vậy tại sao địa chỉ của a cũng bằng 22FE30;

M.n giúp em với ạ. Tks

1 Like

Vì a không có thật nên nó giống nhau, nhưng kì thực bản chất là khác nhau.

a có kiểu là int[5], vậy &aint*[5] (con trỏ). Nghĩa là *(a+1) là a[1], còn &a+1 là văng tuốt ra ngoài.

p + 1 = (char*)p + sizeof(*p)

4 Likes

Theo mình:

  • a: chính là con trỏ của mảng a[5], nên a trỏ đến phần tử đầu tiên.
  • &a: là địa chỉ của mảng a, cũng chính là địa chỉ của phần tử đầu tiên.

Vì vậy nên nó giống nhau.

1 Like

Hi Phạm Cường.
Theo mình thì vì a có kiểu dữ liệu là int [5] nó không phải là một con trỏ nên không có vùng nhớ riêng như các biến con trỏ được cấp phát động.

#include <iostream>

int main(int argc, char** argv) {
int a[5];

std::cout << a << std::endl; // Cùng giá trị.
std::cout << (&a) << std::endl; // Cùng giá trị.
std::cout << &a[0] << std::endl; // Cùng giá trị.

int* p = a;
*p = 100;
std::cout << a[0] << std::endl;
std::cout << a << std::endl;
std::cout << &a << std::endl;
std::cout << *a << std::endl;

return 0;
}
1 Like

tại vì mảng trong C decay thành con trỏ. Chữ decay ko biết dịch là gì :V

thời xa xưa C++ làm theo C để code C cũng biên dịch với trình biên dịch C++ được. Mảng trong C bị decay thành con trỏ ko biết vì sao :V Nhưng có lẽ là vì hàm trong C ko có quá tải được (overload, hay nhiều hàm cùng tên nhưng khác tham số), nên khai báo void f(char s[10]) với void f(char s[20]) thì cả 2 hàm chỉ có 1 tham số là mảng s, nhưng mảng cần tới 2 tham số là vị trí của mảng và kích cỡ mảng mới phân biệt char[10] với char[20] được, nhưng ở đây f chỉ nhận 1 tham số nên nó đành phải vứt tham số kích cỡ mảng đi còn cái con trỏ tới phần tử đầu tiên của mảng :V

quá khứ ko cho phép gọi &a nếu a là mảng, vì khi viết a thì nó đã bị decay thành con trỏ tới mảng hay địa chỉ của mảng rồi ko cần &a nữa, nhưng sau đó được cho phép :V

2 Likes

Hi tntxtnt.
Cõ lẽ để cho đơn giản. Thay vì phải cài đặt một kiểu dữ liệu mảng thì việc quản lý qua con trỏ và bộ nhớ sử dụng cái sãn có luôn.

1 Like

để cho đơn giản mà 10 câu hỏi về con trỏ hết 9 câu hỏi vì sao truyền mảng X x[10] vào hàm ko được thì “đơn giản” kiểu ngược logic rồi :V Chắc là do hạn chế vì ko quá tải hàm được, chứ C++ truyền mảng ngon lành.

2 Likes

When an array name is passed to a function, what is passed is the location
of the initial element

đây nè, kinh thánh mục 5.3 trang 99 có ghi rõ rồi, tên mảng truyền vô hàm là truyền địa chỉ của phần tử đầu tiên trong mảng thôi nên printf("%p", a);printf("%p", &a); là một :V

ko thấy ghi lý do :V

trong phần Appendix C trang 260 cũng có ghi là vào năm 1988 khi kinh thánh được soạn thảo vơ sần 2 update từ vơ sần 1 năm 1978, “Applying the address-of operator to arrays is permitted, and the result is a pointer to the array.” tức là vào năm 1978 ko ghi &a được? :V

3 Likes

Hi tntxtnt.
Ý mình là đơn giản trong xây dựng trình dịch. Thực tế thì quá tải hàm trong C++ thì khi dịch nó sẽ viết lại tên hàm bị quá tải theo một cú pháp riêng. Việc đó tuy tạo ra sự linh hoạt trong lập trình nhưng khi cần gọi các hàm từ file thư viện .so thì thực sự phứ tạp hơn.

2 Likes

Thuộc lĩnh vực môn cấu trúc dữ liệu và giải thuật bạn ạ. Theo mình được biết khi bạn khởi tao 1 mảng a[5] thì con trỏ a nó chỉ tới vị trí đầu tiên của mảng vì vậy mà có điều bạn thắc mắc.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?