简体   繁体   中英

What's the difference between &table[0][0] and &table?

I've been successfully trying to pass a 2D-array to a function, see code below. What I don't get: Why does my "method C" (see code below) not work?

What's the difference between &table[0][0] and &table ? Both of them point to the same memory address. The former works as argument passed to my function, the latter doesn't, error message:

"no known conversion from 'int (*)[3][2]' to 'int *' for 1st argument void print_table(int *table, const int ROWS, const int COLUMNS)

Thanks in advance! Alex

#include <iostream>
void print_table(int *table, const int ROWS, const int COLUMNS)
{
    for (int i = 0; i < ROWS; i++)
    {
        for (int j = 0; j < COLUMNS; j++)
        {
            std::cout << table[i * COLUMNS + j] << "\t";
        }
        std::cout << "\n";
    }
}

int main()
{
    const int ROWS = 3;
    const int COLUMNS = 2;
    int table[ROWS][COLUMNS] = {{1,2},{3,4},{5,6}};

    std::cout << (int*)table << "\n";     // these 3 couts all deliver the same memory address      
    std::cout << &table[0][0] << "\n";    // these 3 couts all deliver the same memory address
    std::cout << &table << "\n";          // these 3 couts all deliver the same memory address

    print_table((int*)table, ROWS, COLUMNS);   // method A: Works.
    print_table(&table[0][0], ROWS, COLUMNS);  // method B: Works too.
    print_table(&table, ROWS, COLUMNS);        // method C: Doesn't work! Why?
    
    return 0;
}

Main difference: What is actually being pointed to, and from that its type.

The expression &table points to the array table itself, and it will have the type int(*)[3][2] .

The expression &table[0][0] is a pointer to a single element in the sub-array table[0] , and will have the type int* .

The reason "method A" works, even though it's wrong, is because both pointers just happen to be pointing to the same location.

If we draw out your array then it will look something like this (with "pointers" added):

+-------------+-------------+-------------+-------------+-------------+-------------+
| table[0][0] | table[0][1] | table[1][0] | table[1][1] | table[2][0] | table[2][1] |
+-------------+-------------+-------------+-------------+-------------+-------------+
^
|
&table
|
&table[0]
|
&table[0][0]

I added &table[0] because this is what plain table will be decaying to. It will have the type int(*)[2] . This is the pointer you pass as "method A". Without the casting to int* that method would also fail.

Generally speaking: Whenever you need to do a C-style casting (like for "method A") then you should take that as a sign that you're doing something wrong.

In short: Only "method B" is really correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM