Thread: stupid question time

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    662

    stupid question time

    how do i pass a 2d array of characters to a function as a whole thing
    many thanks
    coop

  2. #2
    Registered User
    Join Date
    Apr 2019
    Posts
    57
    What kind of 2D array? C has 2 kinds of 2D arrays, contiguous and jagged.

    Code:
    int contiguous[8][8];
    int **jagged;
    A contiguous array is really just a 1D array, but C needs to know the width of the array (the second dimension) in order to pass it to a function. Otherwise it can't know how wide the rows are, and won't know where the 2nd, 3rd, etc rows start. The second parameter in this function is necessary to know the number of rows in the array. This type of parameter is only useful when the number of columns is known at compile-time. For anything dynamically allocated, see the next example.

    Code:
    void act_on_contiguous(int a[][10], int n) {
    }
    The other type, a jagged array, is actually just an array of integer pointers. You just pass it as a normal **. Note that n is the number of rows, but I don't specify the number of columns. The number of columns can change from row to row in a jagged array.

    Code:
    void act_on_jagged(int **a, int n) {
    }
    
    int main(void) {
      int **jagged = malloc(sizeof(int) * 10);
      for(int i = 0; i < 10; i++)
        jagged[i] = malloc(sizeof(int) * 10);
      act_on_jagged(jagged);
    }
    But I prefer to use a 1D array as a 2D array. It's the same as the normal 2D array, but the indexing is done manually. These are just normal pointers or 1D arrays which makes them easier to allocate than jagged arrays but are more flexible than 2D arrays. Again, it needs to know the number of columns in the array to generate the offsets into the 1D array.

    Code:
    void act_on_1D_as_2D(int *a, int n) {
      // Set x5,y2 to 7
      a[2*n+5] = 7;
    }
    
    int main(void) {
      int *a = malloc(sizeof(int) * 20 * 20); // 20x20 array
      act_on_1D_as_2D(a, 20);
    }

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    57
    And there are no stupid questions, but I think we'd all prefer if your subject lines were more meaningful

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    sorry i guess i haven't been very clear here is an example of what i mean
    Code:
    void myfunc(char str1[]);
    
    int main()
    {
        char str1[2][11];
    
        strcpy(str1[0][11], "hello world");
        strcpy(str1[1][11], "goodbye you");
        myfunc(str1);
        return 0;
    }
    void myfunc(char str1[])
    {
        int i,j;
        for (j=0; j<1; j++)
        {
            for (i=0; i<11;i++)
            {
                printf("%c", str1[i]);
            }
            printf("\n");
        }
    
    
    }
    i get warnings about making pointers from int without cast and stack overflow if i run it
    many thanks
    coop

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    57
    You're getting warnings because they're not the same type, you're passing a char a[][11] and it's expecting a char a[]. See my act_on_contiguous example.

    The first thing to understand here is that 2D arrays don't really "exist," they're just 1D arrays. All that's needed to operate on them is the address of their start and the number of columns. In memory, your array just looks like this.

    Code:
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |h|e|l|l|o| |w|o|r|l|d|g|o|o|d|b|y|e| |y|o|u|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    The more rows you add, the further it just extends out to the right. C just knows that each row is 11 characters long and for every row it just makes the array another 11 elements longer. It's also how it calculates the offset to any row, it knows they're 11 characters long so the second row starts at offset 11, the next at offset 22, etc.

    The next thing you have to understand is that every time you pass an array to a function, it "decays" into a pointer to that type. For example, if you pass an int a[3] to a function, it becomes an int a[], which is the same thing as an int *. This was a design decision early in C's history and there are probably better ways to handle it, but it's what we have.

    So how does this work with 2D arrays? Your char a[2][11] decays to a pointer to a 2D array of 11 character columns and becomes a char [][11]. C can't tell from that type how many rows it has, but it knows that it has 11 columns. So the type for the parameter you should be using is char str1[][11]. It's also good practice and a common idiom to pass the array length along with the function, so your code should look something like this.

    Code:
    #define arraylen(a) (sizeof(a)/sizeof(a[0]))
    
    void func(int a[][11], int n) {
    }
    
    int main(void) {
      int a[4][11] = {0};
      func(a, arraylen(a));
    }
    I hope I'm explaining this well. This is one of the more confusing corners of C so don't be discouraged if you don't get this right away.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Probably a stupid question
    By Homunculus in forum Windows Programming
    Replies: 1
    Last Post: 01-27-2011, 08:35 PM
  2. Stupid question
    By c++0x in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-13-2008, 10:56 AM
  3. stupid, stupid question
    By xelitex in forum C++ Programming
    Replies: 5
    Last Post: 12-22-2004, 08:22 PM
  4. Stupid Math Question....really stupid
    By ToLazytoSignIn in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 01-16-2003, 07:36 PM
  5. Stupid Cursor (I spelled it right htis time)
    By tim545666 in forum C++ Programming
    Replies: 2
    Last Post: 04-26-2002, 07:55 AM

Tags for this Thread