30/09/2018, 18:21

Thắc mắc về khai báo con trỏ và mảng hai chiều

#include <stdio.h>
#define D 3
#define C 4
int main()
{
        int a[D][C]; //câu lệnh 1
        int i;
	int *p = (int *)a; //câu lệnh 2
	//printf("%p", &a[0]);
	for (i = 0; i < D*C; i++)
	{
		printf("Nhap phan tu thu %d: ", i);
		scanf("%d", p + i);
	}

	for (i = 0; i < D*C; i++)
		printf("%d ", *(p + i));
}

Em hiểu như thế này

  • câu lệnh 1:
    a là con trỏ cấp 2 trỏ đến a[0], a[0] là con trỏ đến a[0][0]
  • câu lệnh 2:
    em nghĩ là ép kiểu a về kiểu con trỏ int, không hiểu chổ này vì lúc này a được hiểu là con trỏ cấp 2, ép về con trỏ cấp 1 liệu ổn không, và có mục đích gì, gán thẳng int *p = &a[0][0]; luôn khoẻ hơn không vì int *p = (int *)a; <=>int *p = *a ; mà *a trỏ về phần tử a[0][0] nên p = &a[0][0];

Mọi người xem giúp em nói có đúng không

viết 20:23 ngày 30/09/2018

Bạn nói đúng hết, chỉ nhầm một chút ở đây.

int *p = *a

*p = &a[0][0];

Interns viết 20:37 ngày 30/09/2018

Đã sửa. vậy có nên dùng ép kiểu không @vietha1996 gán thẳng luôn có khoẻ hơn không

viết 20:33 ngày 30/09/2018

Ý kiến cá nhân mình nghĩ là gán thẳng như bạn cũng được. Con trỏ và lấy giá trị mà con trỏ giữ có rất nhiều cách, bạn thấy cách nào tiện thì dùng ạ.

*grab popcorn* viết 20:32 ngày 30/09/2018

Cả 3 đều đúng nhưng với trường hợp mảng tĩnh.
Còn nếu là mảng động thì khôngI!

Vì sao?
Mảng tĩnh dù 2 chiều, 3 chiều đi nữa thì cũng được quy về 1 chiều trong bộ nhớ.
Mãng tĩnh thu gom 1 block byte liên tiếp nhau theo thứ tự liên tiếp nhau.
Nên khi trỏ p tới vị trí đầu tiên của block đó là có thể truy xuất toàn bộ mảng.
Và cả 3 phương pháp trên đều trỏ về vị trí đầu tiên của mảng a.

Ideone.com

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.

Array: A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4
       ^p points here (A1)

//Phần này khỏi đọc cũng đc
Còn mảng động thì, với các phép gán trên, p sẽ bắt đầu khác.

int * p = *a = p trỏ tới a[0][0] <=> int * p = &a[0][0];
int * p = a = p trỏ tới a[0] <=> int * p = (int *)a

Hiểu rõ hơn:
Do đâu thì do mảng động phân cách block dữ liệu không liên tục nhau.

Dynamic Array: A1 A2 A3 A4 [...] B1 B2 B3 B4 [...] C1 C2 C4 C4
               ^p points here

Mà khi lấy được địa chỉ của A1 thì p sẽ thấy như thế này:

P: A1 A2 A3 A4 A5 A6 [...]

Tức p sẽ thấy từ A1 là 1 dãy liên tục các địa chỉ liền kề nhau. Chứ ko phân đoạn ra như trên. Từ đó không thể in đúng dữ liệu đc.

Ideone.com

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.


Nói chung mình viết dựa theo kinh nghiệm thôi nên có thể ko hẳn là đúng 100%

Bài liên quan
0