สร้างตัวชี้ไปยังอาร์เรย์สองมิติ


120

ฉันต้องการตัวชี้ไปยังอาร์เรย์ 2 มิติแบบคงที่ วิธีนี้ทำได้อย่างไร?

static uint8_t l_matrix[10][20];

void test(){
   uint8_t **matrix_ptr = l_matrix; //wrong idea 
}

ฉันได้รับข้อผิดพลาดทุกประเภทเช่น:

  • คำเตือน: การกำหนดจากประเภทตัวชี้ที่เข้ากันไม่ได้
  • ค่าตัวห้อยไม่ใช่อาร์เรย์หรือตัวชี้
  • ข้อผิดพลาด: การใช้สมาชิกอาร์เรย์แบบยืดหยุ่นไม่ถูกต้อง

อ่านstackoverflow.com/questions/423823/…มันอาจช่วยคุณได้
Johannes Schaub - litb

1
@ JohannesSchaub-litb ไม่มีอีกแล้ว (ฉันจะดูอีกครั้งได้อย่างไร ... ฉันรู้ว่าสมาชิกที่มีตัวแทนต่ำสามารถดูได้ แต่ฉันลืมว่า ... )
Mateen Ulhaq

1
@muntoo: นี่คือสำเนาของมัน: gist.github.com/sharth/ede13c0502d5dd8d45bd
Bill Lynch

คำตอบ:


140

ที่นี่คุณต้องการชี้ไปที่องค์ประกอบแรกของอาร์เรย์

uint8_t (*matrix_ptr)[20] = l_matrix;

ด้วย typedef สิ่งนี้จะดูสะอาดขึ้น

typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;

แล้วคุณจะมีความสุขกับชีวิตได้อีกครั้ง :)

matrix_ptr[0][1] = ...;

ระวังโลกของตัวชี้ / อาร์เรย์ใน C ความสับสนรอบนี้


แก้ไข

ตรวจสอบคำตอบอื่น ๆ บางส่วนที่นี่เนื่องจากช่องความคิดเห็นสั้นเกินไปที่จะทำที่นั่น มีการเสนอทางเลือกหลายทาง แต่ไม่ได้แสดงให้เห็นว่าพวกเขาทำงานอย่างไร นี่คือวิธีที่พวกเขาทำ

uint8_t (*matrix_ptr)[][20] = l_matrix;

หากคุณแก้ไขข้อผิดพลาดและเพิ่มแอดเดรสของโอเปอเรเตอร์&ดังตัวอย่างต่อไปนี้

uint8_t (*matrix_ptr)[][20] = &l_matrix;

จากนั้นจะสร้างตัวชี้ไปยังประเภทอาร์เรย์ที่ไม่สมบูรณ์ขององค์ประกอบประเภทอาร์เรย์ 20 uint8_t เนื่องจากตัวชี้อยู่ในอาร์เรย์ของอาร์เรย์คุณจึงต้องเข้าถึงด้วย

(*matrix_ptr)[0][1] = ...;

และเนื่องจากเป็นตัวชี้ไปยังอาร์เรย์ที่ไม่สมบูรณ์คุณจึงไม่สามารถใช้เป็นทางลัดได้

matrix_ptr[0][0][1] = ...;

เนื่องจากการจัดทำดัชนีจำเป็นต้องทราบขนาดของประเภทองค์ประกอบ (การจัดทำดัชนีหมายถึงการเพิ่มจำนวนเต็มให้กับตัวชี้ดังนั้นจึงใช้ไม่ได้กับประเภทที่ไม่สมบูรณ์) โปรดทราบว่าสิ่งนี้ใช้ได้เฉพาะในCเนื่องจากT[]และT[N]เป็นประเภทที่เข้ากันได้ C ++ ไม่มีแนวคิดเกี่ยวกับประเภทที่เข้ากันได้ดังนั้นจะปฏิเสธรหัสนั้นเนื่องจากT[]และT[10]เป็นประเภทที่แตกต่างกัน


ทางเลือกต่อไปนี้ใช้ไม่ได้เลยเนื่องจากประเภทองค์ประกอบของอาร์เรย์เมื่อคุณดูเป็นอาร์เรย์มิติเดียวไม่ได้ uint8_tแต่uint8_t[20]

uint8_t *matrix_ptr = l_matrix; // fail

ต่อไปนี้เป็นทางเลือกที่ดี

uint8_t (*matrix_ptr)[10][20] = &l_matrix;

คุณเข้าถึงได้ด้วย

(*matrix_ptr)[0][1] = ...;
matrix_ptr[0][0][1] = ...; // also possible now

มีประโยชน์ที่จะรักษาขนาดของมิติภายนอก คุณสามารถใช้ sizeof กับมันได้

sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20

มีอีกคำตอบหนึ่งที่ใช้ประโยชน์จากข้อเท็จจริงที่ว่ารายการในอาร์เรย์ถูกเก็บไว้อย่างต่อเนื่อง

uint8_t *matrix_ptr = l_matrix[0];

ตอนนี้ที่เป็นทางการอนุญาตให้คุณเข้าถึงองค์ประกอบขององค์ประกอบแรกของอาร์เรย์สองมิติเท่านั้น นั่นคือเงื่อนไขต่อไปนี้ถือ

matrix_ptr[0] = ...; // valid
matrix_ptr[19] = ...; // valid

matrix_ptr[20] = ...; // undefined behavior
matrix_ptr[10*20-1] = ...; // undefined behavior

คุณจะสังเกตเห็นว่ามันอาจใช้งานได้10*20-1ดี แต่ถ้าคุณใช้การวิเคราะห์นามแฝงและการเพิ่มประสิทธิภาพเชิงรุกอื่น ๆ คอมไพเลอร์บางตัวอาจตั้งสมมติฐานว่าอาจทำลายโค้ดนั้นได้ ต้องบอกว่าฉันไม่เคยพบคอมไพเลอร์ที่ล้มเหลวเลย (แต่อีกครั้งฉันไม่ได้ใช้เทคนิคนั้นในโค้ดจริง) และแม้แต่คำถามที่พบบ่อย C ก็มีเทคนิคนั้นอยู่ (พร้อมคำเตือนเกี่ยวกับ UB'ness ) และหากคุณไม่สามารถเปลี่ยนประเภทอาร์เรย์ได้นี่คือตัวเลือกสุดท้ายที่จะช่วยคุณประหยัด :)


+1 - ข้อมูลที่ดีเกี่ยวกับการแยกย่อย int (*) [] [20] - ไม่สามารถทำได้ใน C ++
Faisal Vali

@litb ฉันขอโทษ แต่นี่ไม่ถูกต้องเนื่องจากโซลูชันของคุณไม่มีการจัดสรรพื้นที่เก็บข้อมูลใด ๆ สำหรับอาร์เรย์
Rob Wells

2
@ ร็อบฉันไม่ค่อยเข้าใจคุณ ที่เก็บข้อมูลในทุกกรณีเหล่านี้จัดเตรียมโดยอาร์เรย์ l_matix เอง พอยน์เตอร์สำหรับพวกเขาใช้พื้นที่จัดเก็บจากที่ที่เคยมีการประกาศในและเป็น (สแต็ก, เซ็กเมนต์ข้อมูลแบบคงที่, ... )
Johannes Schaub - litb

แค่สงสัยว่าทำไมเราถึงต้องการ "&" ที่อยู่ของ l_matrix
electro

1
@Sohaib - ไม่ที่สร้างตัวชี้เพียงตัวเดียว คุณอาจสับสนกับมันuint8_t *d[20]ซึ่งสร้างอาร์เรย์ของพอยน์เตอร์ 3 ตัวไปยัง uint8_t แต่จะใช้ไม่ได้ในกรณีนี้
Palo

28

เพื่อให้เข้าใจอย่างถ่องแท้คุณต้องเข้าใจแนวคิดต่อไปนี้:

อาร์เรย์ไม่ใช่ตัวชี้!

ครั้งแรกของทั้งหมด (และจะได้รับเทศน์พอ), อาร์เรย์จะไม่ชี้ ในการใช้งานส่วนใหญ่พวกเขาจะ 'สลาย' ไปยังที่อยู่ไปยังองค์ประกอบแรกซึ่งสามารถกำหนดให้กับตัวชี้:

int a[] = {1, 2, 3};

int *p = a; // p now points to a[0]

ฉันคิดว่ามันทำงานในลักษณะนี้เพื่อให้สามารถเข้าถึงเนื้อหาของอาร์เรย์ได้โดยไม่ต้องคัดลอกทั้งหมด นั่นเป็นเพียงพฤติกรรมของประเภทอาร์เรย์และไม่ได้หมายถึงการบอกเป็นนัยว่าเป็นสิ่งเดียวกัน



อาร์เรย์หลายมิติ

อาร์เรย์หลายมิติเป็นเพียงวิธีหนึ่งในการ 'แบ่งพาร์ติชัน' หน่วยความจำในลักษณะที่คอมไพเลอร์ / เครื่องสามารถเข้าใจและดำเนินการได้

ตัวอย่างเช่นint a[4][3][5]= อาร์เรย์ที่มี 4 * 3 * 5 (60) 'ชิ้นส่วน' ของหน่วยความจำขนาดจำนวนเต็ม

ข้อได้เปรียบของการใช้int a[4][3][5]vs ธรรมดาint b[60]คือตอนนี้พวกเขา 'แบ่งพาร์ติชัน' แล้ว (ทำงานกับ 'ชิ้นส่วน' ได้ง่ายขึ้นหากจำเป็น) และโปรแกรมสามารถทำการตรวจสอบแบบผูกมัดได้แล้ว

ในความเป็นจริงint a[4][3][5]จะถูกเก็บไว้ว่าเหมือนint b[60]ในความทรงจำ - เดอะเพียงความแตกต่างคือว่าโปรแกรมที่ตอนนี้จัดการมันราวกับว่าพวกเขากำลังแยกหน่วยงานที่มีขนาดบางอย่าง (โดยเฉพาะสี่กลุ่มสามกลุ่มห้า)

ข้อควรจำ: ทั้งสองอย่างint a[4][3][5]และint b[60]เหมือนกันในหน่วยความจำและความแตกต่างเพียงอย่างเดียวคือวิธีจัดการโดยแอปพลิเคชัน / คอมไพเลอร์

{
  {1, 2, 3, 4, 5}
  {6, 7, 8, 9, 10}
  {11, 12, 13, 14, 15}
}
{
  {16, 17, 18, 19, 20}
  {21, 22, 23, 24, 25}
  {26, 27, 28, 29, 30}
}
{
  {31, 32, 33, 34, 35}
  {36, 37, 38, 39, 40}
  {41, 42, 43, 44, 45}
}
{
  {46, 47, 48, 49, 50}
  {51, 52, 53, 54, 55}
  {56, 57, 58, 59, 60}
}

จากนี้จะเห็นได้ชัดเจนว่า "พาร์ติชั่น" แต่ละตัวเป็นเพียงอาร์เรย์ที่โปรแกรมติดตาม



วากยสัมพันธ์

ตอนนี้อาร์เรย์มีความแตกต่างทางวากยสัมพันธ์จากพอยน์เตอร์ โดยเฉพาะหมายความว่าคอมไพเลอร์ / เครื่องจะปฏิบัติแตกต่างกัน สิ่งนี้อาจดูเหมือนไม่ใช่เกมง่ายๆ แต่ลองดูสิ่งนี้:

int a[3][3];

printf("%p %p", a, a[0]);

ตัวอย่างข้างต้นพิมพ์ที่อยู่หน่วยความจำเดียวกันสองครั้งดังนี้:

0x7eb5a3b4 0x7eb5a3b4

อย่างไรก็ตามสามารถกำหนดเพียงตัวเดียวให้กับตัวชี้ได้โดยตรง :

int *p1 = a[0]; // RIGHT !

int *p2 = a; // WRONG !

เหตุใดจึงไม่ a สามารถกำหนดให้กับตัวชี้ได้ แต่ a[0] ทำได้?

นี่เป็นผลมาจากอาร์เรย์หลายมิติและฉันจะอธิบายว่าทำไม:

ในระดับ ' a' เรายังคงเห็นว่าเรามี 'มิติ' อื่นที่จะมองไปข้างหน้า อย่างไรก็ตามที่ระดับ ' a[0]' เราอยู่ในมิติด้านบนแล้วดังนั้นเท่าที่โปรแกรมเกี่ยวข้องเราแค่ดูอาร์เรย์ปกติ

คุณอาจจะถาม:

เหตุใดจึงมีความสำคัญหากอาร์เรย์มีหลายมิติเกี่ยวกับการสร้างตัวชี้

คิดอย่างนี้ดีที่สุด:

'การสลายตัว' จากอาร์เรย์หลายมิติไม่ใช่แค่แอดเดรส แต่เป็นแอดเดรสที่มีข้อมูลพาร์ติชัน (AKA ยังคงเข้าใจว่าข้อมูลพื้นฐานนั้นสร้างจากอาร์เรย์อื่น) ซึ่งประกอบด้วยขอบเขตที่อาร์เรย์กำหนดไว้นอกเหนือจากมิติแรก

ตรรกะ 'พาร์ติชัน' นี้ไม่สามารถมีอยู่ในตัวชี้ได้เว้นแต่เราจะระบุ:

int a[4][5][95][8];

int (*p)[5][95][8];

p = a; // p = *a[0] // p = a+0

มิฉะนั้นความหมายของคุณสมบัติการเรียงลำดับของอาร์เรย์จะหายไป

สังเกตการใช้วงเล็บรอบ ๆ ด้วย*p: int (*p)[5][95][8]- นั่นคือเพื่อระบุว่าเรากำลังสร้างตัวชี้ด้วยขอบเขตเหล่านี้ไม่ใช่อาร์เรย์ของพอยน์เตอร์ที่มีขอบเขตเหล่านี้:int *p[5][95][8]



ข้อสรุป

มาทบทวนกัน:

  • อาร์เรย์จะสลายไปเป็นแอดเดรสหากไม่มีจุดประสงค์อื่นในบริบทที่ใช้
  • อาร์เรย์หลายมิติเป็นเพียงอาร์เรย์ของอาร์เรย์ - ดังนั้นแอดเดรสที่ 'ผุพัง' จะรับภาระของ "ฉันมีมิติย่อย"
  • ข้อมูลขนาดไม่สามารถอยู่ในตัวชี้จนกว่าคุณจะให้มันไป

โดยย่อ: อาร์เรย์หลายมิติสลายตัวเป็นที่อยู่ที่มีความสามารถในการทำความเข้าใจเนื้อหา


1
ส่วนแรกของคำตอบนั้นยอดเยี่ยม แต่ส่วนที่สองไม่ใช่ สิ่งนี้ไม่ถูกต้อง: int *p1 = &(a[0]); // RIGHT !จริง ๆ แล้วก็เหมือนกับint *p1 = a;
2501

@ 2501 ขอบคุณสำหรับการตรวจพบข้อผิดพลาดเราได้แก้ไขแล้ว ฉันไม่สามารถพูดได้อย่างแน่ชัดว่าเหตุใดตัวอย่างที่กำหนด "กฎ" นี้จึงท้าทายด้วย สิ่งที่ควรค่าแก่การกล่าวซ้ำก็คือเพียงเพราะสองเอนทิตีสามารถตีความเป็นพอยน์เตอร์และให้ค่าเดียวกันไม่ได้หมายความว่าเอนทิตีมีความหมายเดียวกัน
Super Cat

7

ใน

int *ptr= l_matrix[0];

คุณสามารถเข้าถึงเช่น

*p
*(p+1)
*(p+2)

หลังจากอาร์เรย์ 2 มิติทั้งหมดจะถูกจัดเก็บเป็น 1-d


5

G'day,

คำประกาศ

static uint8_t l_matrix[10][20];

ได้จัดสรรพื้นที่จัดเก็บไว้ 10 แถวจาก 20 ตำแหน่งหน่วย 8_t เช่นตำแหน่งขนาด 200 uint8_t โดยแต่ละองค์ประกอบจะถูกหาโดยการคำนวณ 20 x row + column

ดังนั้นไม่

uint8_t (*matrix_ptr)[20] = l_matrix;

ให้สิ่งที่คุณต้องการและชี้ไปที่องค์ประกอบคอลัมน์ศูนย์ของแถวแรกของอาร์เรย์

แก้ไข:คิดเกี่ยวกับสิ่งนี้ต่อไปอีกนิดชื่ออาร์เรย์ตามความหมายตัวชี้ไม่ใช่หรือ นั่นคือชื่อของอาร์เรย์เป็นคำพ้องความหมายของตำแหน่งขององค์ประกอบแรกคือ l_matrix [0] [0]?

แก้ไข 2:ตามที่ผู้อื่นกล่าวไว้พื้นที่แสดงความคิดเห็นมีขนาดเล็กเกินไปสำหรับการสนทนาเพิ่มเติม อย่างไรก็ตาม:

typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;

ไม่มีการจัดสรรพื้นที่เก็บข้อมูลสำหรับอาร์เรย์ที่เป็นปัญหา

ดังที่กล่าวไว้ข้างต้นและตามที่กำหนดโดยมาตรฐานคำสั่ง:

static uint8_t l_matrix[10][20];

ได้จัดสรรตำแหน่งตามลำดับไว้ 200 ตำแหน่งประเภท uint8_t

อ้างถึง l_matrix โดยใช้คำสั่งของแบบฟอร์ม:

(*l_matrix + (20 * rowno) + colno)

จะให้เนื้อหาขององค์ประกอบ colno'th ที่พบในแถว rowno

การปรับแต่งตัวชี้ทั้งหมดจะคำนึงถึงขนาดของวัตถุที่ชี้ไปโดยอัตโนมัติ - K&R มาตรา 5.4, น. 103

นอกจากนี้ยังเป็นกรณีนี้หากมีการขยับช่องว่างภายในหรือการปรับตำแหน่งไบต์ที่เกี่ยวข้องกับการจัดเก็บวัตถุที่อยู่ในมือ คอมไพเลอร์จะปรับให้โดยอัตโนมัติสำหรับสิ่งเหล่านี้ ตามความหมายของมาตรฐาน C ANSI

HTH

เสียงเชียร์


1
uint8_t (* matrix_ptr) [] [20] << วงเล็บแรกต้องถูกทิ้งไว้ที่ถูกต้องคือ uint8_t (* matrix_ptr) [20]
Aconcagua

5

ใน C99 (รองรับโดย clang และ gcc) มีไวยากรณ์ที่คลุมเครือสำหรับการส่งอาร์เรย์หลายมิติไปยังฟังก์ชันโดยการอ้างอิง:

int l_matrix[10][20];

void test(int matrix_ptr[static 10][20]) {
}

int main(void) {
    test(l_matrix);
}

ซึ่งแตกต่างจากตัวชี้ธรรมดาคำใบ้เกี่ยวกับขนาดอาร์เรย์ในทางทฤษฎีอนุญาตให้คอมไพเลอร์เตือนเกี่ยวกับการส่งอาร์เรย์ที่เล็กเกินไปและมองเห็นได้ชัดเจนจากการเข้าถึงขอบเขต

น่าเศร้าที่มันไม่สามารถแก้ไขได้sizeof()และดูเหมือนว่าคอมไพเลอร์จะยังไม่ใช้ข้อมูลดังกล่าวดังนั้นจึงยังคงเป็นความอยากรู้


1
คำตอบนี้ทำให้เข้าใจผิด: นั่นไม่ได้ทำให้อาร์กิวเมนต์เป็นอาร์เรย์ขนาดคงที่ แต่ยังคงเป็นตัวชี้ static 10เป็นการรับประกันบางอย่างว่ามีองค์ประกอบอย่างน้อย 10 รายการซึ่งหมายความว่าขนาดจะไม่คงที่อีกครั้ง
bluss

1
@bluss คำถามนั้นเกี่ยวกับตัวชี้ดังนั้นฉันจึงไม่เห็นว่าการตอบด้วยตัวชี้ (สังเกตโดยการอ้างอิง ) นั้นทำให้เข้าใจผิดได้อย่างไร อาร์เรย์มีขนาดคงที่จากมุมมองของฟังก์ชันเนื่องจากไม่ได้กำหนดการเข้าถึงองค์ประกอบที่อยู่นอกเหนือขอบเขตเหล่านี้
Kornel

ฉันไม่คิดว่าการเข้าถึงเกิน 10 นั้นไม่ได้กำหนดไว้ฉันไม่เห็นอะไรที่บ่งบอกถึงสิ่งนั้น
bluss

คำตอบนี้ดูเหมือนจะแนะนำว่าหากไม่มีคีย์เวิร์ดstaticอาร์เรย์จะไม่ถูกส่งผ่านโดยการอ้างอิงซึ่งไม่เป็นความจริง อาร์เรย์จะถูกส่งผ่านโดยการอ้างอิงอยู่ดี คำถามเดิมถามเกี่ยวกับกรณีการใช้งานที่แตกต่างกัน - การเข้าถึงองค์ประกอบของอาร์เรย์ 2 มิติโดยใช้ตัวชี้เสริมภายในฟังก์ชัน / เนมสเปซเดียวกัน
Palo

4

คุณสามารถหลีกเลี่ยงการเล่นซอกับคอมไพเลอร์ได้โดยการประกาศอาร์เรย์เป็นเชิงเส้นและทำการคำนวณ (row, col) เพื่อคำนวณดัชนีอาร์เรย์ด้วยตัวเอง

static uint8_t l_matrix[200];

void test(int row, int col, uint8_t val)

{

   uint8_t* matrix_ptr = l_matrix;
   matrix_ptr [col+y*row] = val; // to assign a value

}

นี่คือสิ่งที่คอมไพเลอร์จะทำต่อไป


1
นี่คือสิ่งที่คอมไพเลอร์ C ทำอยู่แล้ว C ไม่มีความคิดที่แท้จริงเกี่ยวกับ "อาร์เรย์" - สัญกรณ์ [] เป็นเพียงน้ำตาลวากยสัมพันธ์สำหรับเลขคณิตตัวชี้
Ken Keenan

7
วิธีแก้ปัญหานี้มีข้อเสียคือไม่เคยหาวิธีที่ถูกต้อง
Craig McQueen

2

ไวยากรณ์พื้นฐานของการกำหนดค่าเริ่มต้นตัวชี้ที่ชี้ไปยังอาร์เรย์หลายองค์ประกอบคือ

type (*pointer)[1st dimension size][2nd dimension size][..] = &array_name

ไวยากรณ์พื้นฐานสำหรับการเรียกมันคือ

(*pointer_name)[1st index][2nd index][...]

นี่คือตัวอย่าง:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
   // The multidimentional array...
   char balance[5][100] = {
       "Subham",
       "Messi"
   };

   char (*p)[5][100] = &balance; // Pointer initialization...

   printf("%s\n",(*p)[0]); // Calling...
   printf("%s\n",(*p)[1]); // Calling...

  return 0;
}

ผลลัพธ์คือ:

Subham
Messi

มันได้ผล ...


1

คุณสามารถทำได้ดังนี้:

uint8_t (*matrix_ptr)[10][20] = &l_matrix;

1
สิ่งนี้ไม่ใช้ ram 10 * 20 ไบต์? (ฉันใช้ไมโครคอนโทรลเลอร์)
Dill

จะใช้พื้นที่ 4 ไบต์หรือขนาดใดก็ได้ที่ตัวชี้ใหญ่ในกล่องของคุณ แต่จำไว้ว่าถ้าคุณมีอันนี้คุณต้องสร้างดัชนีด้วย matrix_ptr [0] [x] [y] หรือ (* matrix_ptr) [x] [y] เป็นการตีความ "ตัวชี้ไปยังอาร์เรย์สองมิติ" โดยตรงและแบบคำต่อคำ: p
Johannes Schaub - litb

ขอบคุณ litb ฉันลืมพูดถึงวิธีการเข้าถึง ไม่มีจุดที่จะแก้ไขคำตอบของฉันเนื่องจากคุณทำได้ดีมากกับคำตอบของคุณ :)
Nick Dandoulakis

ดังนั้นสิ่งนี้ใช้ RAM ขนาด 10 * 20 ไบต์หรือไม่?
Danijel

@Danijel เนื่องจากเป็นตัวชี้ไปยังอาร์เรย์สองมิติจึงใช้เพียง 4 ไบต์หรือขนาดใดก็ได้ที่ตัวชี้อยู่ในกล่องของคุณเช่น 16 บิต 32 บิต 64 บิตเป็นต้น
Nick Dandoulakis

1

คุณต้องการตัวชี้ไปยังองค์ประกอบแรกดังนั้น

static uint8_t l_matrix[10][20];

void test(){
   uint8_t *matrix_ptr = l_matrix[0]; //wrong idea 
}

0

คุณยังสามารถเพิ่มออฟเซ็ตได้หากคุณต้องการใช้ดัชนีเชิงลบ:

uint8_t l_matrix[10][20];
uint8_t (*matrix_ptr)[20] = l_matrix+5;
matrix_ptr[-4][1]=7;

หากคอมไพเลอร์ของคุณแสดงข้อผิดพลาดหรือคำเตือนคุณสามารถใช้:

uint8_t (*matrix_ptr)[20] = (uint8_t (*)[20]) l_matrix;

สวัสดี. คำถามนี้ถูกแท็กด้วยcดังนั้นคำตอบควรเป็นภาษาเดียวกัน โปรดสังเกตแท็ก
2501
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.