Khi khai báo void Ham(int (*a)[100], int n, int m)
thì a
có ý nghĩa như thế nào?
-
int *a
vàint(*a)[100]
vàint *a[100]
khác nhau như thế nào? -
int (*a)[100]
để làm gì?
Khi khai báo void Ham(int (*a)[100], int n, int m)
thì a
có ý nghĩa như thế nào?
int *a
và int(*a)[100]
và int *a[100]
khác nhau như thế nào?int (*a)[100]
để làm gì?a là mảng 100 con trỏ.
int *a[100]
mới là mảng 100 con trỏ kiểu int
Chỗ này nó lằng nhằn một chỗ là có cái dấu (*a)
, nên ta phải đọc là
a là con trỏ, trỏ tới mảng 100 phần tử kiểu int
Tool giúp mình dịch khai báo C
a xem lịch sử chỉnh sửa và thời gian chỉnh sửa cửa thớt đi ạ
hí, không có gì đâu ạ.
mà không hiểu sao lại dùng cái (*a)[100] này nhỉ? vì theo a nói thì *a trỏ đến 1 mảng 100 phần tử, thế để mình *a mà không cần [100] có được ko a?
Khác nhau về khái niệm
int (*a)[100]
là cho biết a
sẽ trỏ tới một mảng kiểu int
, mảng này có 100 phần tử kiểu int
.int *a
là để cho biết a
sẽ trỏ tới địa chỉ int
, địa chỉ đó có thể là mảng.int *a[100]
là cho biết a
là mảng 100 phần tử, mỗi phần tử là một con trỏ kiểu int
.Khác nhau về kích thước giữa int *a
và int(*a)[100]
Khai báo int (*a)[100]
là để khai báo rõ ràng rằng a
trỏ tới mảng kiểu int
với kích thước mỗi phần tử là 400 bytes
bởi vì 100 * 4 bytes = 400 bytes
. Cho int
có kích thước 4 bytes
.
Khai báo int *a
thì a có thể trỏ tới mảng kiểu int
với kích thước của mỗi phần tử là 4 bytes
.
Ví dụ
#include <stdio.h>
int main() {
int (*pa100)[100];
int a100[100];
pa100 = a100;
printf("pa100 points to \t\t%p\n", *pa100);
printf("a100 is on \t\t\t%p\n", a100);
a100[1] = 3;
printf("a100[1] = %d \t\t address %p\n", a100[1], &a100[1]);
printf("pa100[1] = %d \t address %p\n", pa100[1], pa100[1]);
return 0;
}
Kết quả
pa100 points to 0028fd8c
a100 is on 0028fd8c
a100[1] = 3 address 0028fd90
pa100[1] = 2686748 address 0028ff1c
Tại sao a100[1]
bằng 3 trong khi pa100[1] = 2686748
, trông có vẻ là số rác. Đó là bởi vì địa chỉ mà a100[1]
và pa100[1]
trỏ đến là khác nhau.
Ta thấy:
0028ff1c - 0028fd8c
= 4, đúng bằng kích thước của một int
0028ff1c - 0028fd8c
= 400, đúng bằng kích thước của 100 int
Vậy có nghĩa theo anh Đạt khai báo:
int (*a)[100]; <=> int *a = new int[100]; phải không a.
Không phải @quanghuong1991 có thể in địa chỉ của hai khai báo này và địa chỉ sau khi tăng lên 1 để thấy có giống ví dụ của Đạt không.
Đạt không biết khai báo dùng new
như thế nào để thể hiện được cái vụ thao tác +
lên con trỏ mà tăng 400 địa chỉ. Nên Đạt làm tạm một ví dụ khác sử dụng một struct A100
có chứa int data[100]
#include <iostream>
struct A100{
int data[100];
};
int main()
{
int *pa = new int[100];
std::cout << "address pa: " << pa << std::endl;
std::cout << "address pa+1: " << pa+1 << std::endl;
A100 *psa100 = new A100;
std::cout << "address psa100: " << psa100 << std::endl;
std::cout << "address psa100+1: " << psa100+1 << std::endl;
return 0;
}
Output
address pa: 0x7f2580
address pa+1: 0x7f2584
address psa100: 0x7f2718
address psa100+1: 0x7f28a8
Ta chứng minh được là không phải
pa+1 - pa = 4 bytes
Còn về new một 100 phần tử kiểu int thì Đạt không biết phải new làm sao. Nên Đạt làm tạm cái struct A100
.
Cái này gọi là con trỏ mảng đúng không anh?
ví dụ này thiếu *a[100] với *a nữa a ơi…
Rất có thể. Anh không biết thuật ngữ này, tại lúc anh đi học anh chưa học tới phần này.
Ví dụ cho *a
dễ mà. Ví dụ cho int *a[100]
dở lắm. Anh thấy làm ví dụ cho char *bai_tho_con_coc[100]
hay hơn. Em thử nghiên cứu char * s[100]
rồi làm ví dụ xem. Đấy cũng là một cách học. Tự đặt câu hỏi: "char *s
và char *s[100]
khác nhau như thế nào, khi nào dùng cái nào?"
Em cũng không biết thuật ngữ này, cái này do em tự dịch từ cái “point to array” trong sách ra không biết đúng không, tại trong sách cũng chỉ đề cập sơ qua nó thôi.
E thấy theo định nghĩa thì khai báo:
int *pa = new int[100];(1)
là khai báo mảng gồm 100 phần tử kiểu int, giống với bên trên anh nói với khai báo int (*pa)[100];(2)
Hay nó khác nhau ở chỗ (1) la pa trỏ đến đầu mảng. Còn (2) trỏ đến nguyên cả mảng. Như vậy theo (2) thì e thấy không đúng lắm.
Em đọc định nghĩa bị nhầm rồi. new
không phải là “khai báo mảng”, new
là cấp phát vùng nhớ. Ở đây lệnh new
chỉ cấp 400 bytes of RAM cho *pa
thôi. Không liên quan gì khai báo kiểu dữ liệu *pa
cả.
Về bản chất, *pa
vẫn chỉ là int *pa
, new
không làm thay đổi nó. Anh có thể tách ra làm hai dòng lệnh khác nhau.
int *pa;
pa = new int[100];
Trong khi đó ta thấy khai báo này int (*pa)[100]
hoàn toàn khác với khai báo int *pa
. Đừng để ý tới vế sau dấu =
. Để ý phần khai báo biến.
như vậy có phải
int (*pa)[100] chỉ là một con trỏ , và nó chỉ chứa địa chỉ của một mảng, mảng đó bắt buộc có 100 phần tử.
Vậy thì dùng cái này để làm gì ta. Dùng int *p vẫn linh động hơn nhiều .
ví dụ :
p thì có thể gán địa chỉ một biến int, một mảng một chiêu int bat kì só phần tử.
pa thì bi giới hạn rất nhiều
Đúng
Sai
int (*pa)[100]
là một con trỏ, nó trỏ tới một vùng nhớ có độ dài 100 phần tử kiểu int.
int *p
là một con trỏ, trỏ tới một vùng nhớ có độ dài 1 phần tử kiểu int
Mảng, bản chất là một vùng nhớ liên tiếp. Ví dụ: int mang[100]
là một vùng nhớ 400 bytes liên tiếp nhau. Nếu ta viết int *p = mang
hoặc int *p = mang[0]
tức là ta trỏ p tới vùng nhớ có độ dài 1 phần tử kiểu int.
Nếu ta viết p[1]
hoặc (p+1)
, về bản chất ta trỏ tới phần tử kế tiếp của mang[0]
, phần tử này cũng là một vùng nhớ 4 bytes. Vùng nhớ này nằm trong int mang[100]
Nhưng nếu ta viết int (*p)[100] = mang
hoặc int *p = mang[0]
tức là ta trỏ tới vùng nhớ có độ dài 100 phần tử kiểu int. Lúc này p
bao trùm toàn bộ mang[100]
, tức mang[1]
.
Nếu ta viết p[1]
hoặc (p+1
, về bản chất ta trỏ tới vùng nhớ cách xa vị trí mang[0]
400 bytes và nằm ngoài int mang[100]
.
Xem lại ví dụ ở trên: `int (*a)[100]` khác với `int *a` và `int *a[100]` như thế nào?
Hai công cụ khác nhau, dùng cho hai mục đích khác nhau.
anh Đạt ơi em chưa hiểu int a[100]; thì là 1 con trỏ hằng chỉ vào 1 mảng ô nhớ phía sau mà mỗi phần tử trong a[100] cũng coi như là 1 con trỏ, cho em hỏi nó khác gì với int*a[100] ạ
Đây không phải là con trỏ hằng, khi nào có const mới gọi là hằng. Đây gọi là mảng. Chỉ có điều mảng không gán được sang địa chỉ khác, nên người ta mới nói à, mảng giống như con trỏ hằng. Nhưng nó không phải. Mảng về bản chất nó không phải là con trỏ. Mảng là một địa chỉ.
em thử cái này xem
printf("%p %p\n", mang, &mang);
printf("%p %p\n", a, &a);
Nhưng cái này thuộc về câu hỏi khác rồi.
thank a, em sẽ coi lại ^^