Thread: "subscript requires array or pointer type"?

  1. #1
    Registered User
    Join Date
    Sep 2002
    Posts
    37

    "subscript requires array or pointer type"?

    I tried to look for an answer using search the forum, but it hasn't been working for the last couple of days, unfortunately...
    Maybe someone could point out where is the problem with this two dimensional array pointer? The problem arises in the function sumsquares, it supposed to take address of the array , rows and columns as parameters. However, compiler tells me there is no notation of an array pointer inside the function. I tried different things over the last 2 days and still nothing. What is the problem?
    Code:
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    
    
    /* function prototypes */
    void GetData( int num[][4]);
    double sumsquares ( int *, int, int );
    
    
    
    int main( void )
    {
    	int num[3][4] = {0};
    	int rows = 3;
    	int col = 4;
        double sumsq = 0.0;
    	int *num_ptr;
    	num_ptr= &num[3][4];
    
    GetData(num);
    
    sumsq = sumsquares( &num[3][4], rows, col );
    printf( "The sum of squares of each integer is: %.0f.\n", sumsq);
    
    return 0;
    }
    
    
    
    /******************************* sumsquares() *********************************/
    double sumsquares( int *num_ptr, int rows, int col )
    {
    	double sum = 0;
    	double temp1 = 0;
    	double temp2 = 0;
    	double temp3 = 0;
    
    	for ( rows = 0, col = 0; col < 4; col++)
    	{
    		temp1 += pow( num_ptr[rows][col], 2.0 );
    	}
    
    	for ( rows = 1, col = 0; col < 4; col++)
    	{
    		temp2 += pow( num_ptr[rows][col], 2.0 );
    	}
    
    	for ( rows = 2, col = 0; col < 4; col++)
    	{
    		temp3 += pow( num_ptr[rows][col], 2.0 );
    	}
    
    	sum = temp1 + temp2 + temp3;
    
    return sum;
    }
    
    /******************************* GetData() ***************************/
    void GetData( int num[][4] )
    {
    	int i = 0;	
    	char instring[15] = {0};
    
        printf( "Please enter the first row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[0][i] = atoi( gets( instring ) );
    	}
    
    	
    	printf( "Please enter the second row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[1][i] = atoi( gets( instring ) );
    	}
    
    	printf( "Please enter the third row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[2][i] = atoi( gets( instring ) );
    	}
    		
    }
    Thanks in advance...

  2. #2
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    There're quite a few problems:

    Firstly, you're refering to your arrays with their dimensions attached, which is wrong. If you want to pass the array you just pass the name by itself, not with the dimension lengths. Otherwise you are accessing an offset from the array (that's out of bounds of the array too).

    Firstly, you aren't realizing the fact that an int pointer just holds a memory location, not whether it points to the first element of a single dimensional array or of a multidimensional array or anything else.

    This is why you can't use 2 subscipts on it when tying to access an element of the array. This is because in order to do that you have to know how many colums there are.

    Think about it like this:

    Memory is in a line. You make an array that has "6 row" and "3 columns."

    How do you think that is put in memory? In a row. So, what happens when you try to access row 3 column 2 of that array?

    Internally, what the compiler does is multiplies the row you want to access by the number of columns and adds to that the column you want to access. That number is then multiplied by the sizeof the datatype of the elements and is then used as an offset from the first location in memory.

    It knows how many columns there are from the declaration of the array.

    The problem is that if you use a pointer to an int to store the first element of that array, you lose all that information about the number of columns! How is it going to be able to figure out the offset if it doesn't know how many elements there are per row?

    It can't.

    Instead, you'd either have to pass a pointer to array with that number of columns, or a pointer to an array of that many columns and rows, or you can pass to the function info about the columns and use it to perform the above offset calculation yourself.

    Before I go any further it looks as though, in your sumsquares function, you ONLY want to work with an array with 3 rows and 4 columns. Also, you apparently don't use any of the information from the other two parameters (rows and col).

    So, make the parameter a pointer to an array of 3 rows and 4 columns and get rid of the other 2!

    Then, when you call it, just use the array name.

    But to be honest, you seem to just be messing up a lot of logic in that function. What I'm guessing you wanted to do was account for arrays of multiple dimensions and use rows and cols as the information about the dimensions to access the elements in the arrays, but if that's the case, you are doing something extremely different. Get back to me on exactly what you want somesquares to do and if it should account for arrays with varying dimensional lengths.

    here's a fixed version of the code:

    Code:
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    
    
    /* function prototypes */
    void GetData( int num[][4]);
    double sumsquares( int (*num_ptr)[3][4] );
    
    
    
    int main( void )
    {
    	int num[3][4] = {0};
        double sumsq = 0.0;
    
    GetData(num);
    
    sumsq = sumsquares( &num );
    printf( "The sum of squares of each integer is: %.0f.\n", sumsq);
    
    return 0;
    }
    
    
    
    /******************************* sumsquares() *********************************/
    double sumsquares( int (*num_ptr)[3][4] )
    {
    	double sum = 0;
    	double temp1 = 0;
    	double temp2 = 0;
    	double temp3 = 0;
    
    	int rows, col;
    
    	for ( rows = 0, col = 0; col < 4; col++)
    	{
    		temp1 += pow( (*num_ptr)[rows][col], 2.0 );
    	}
    
    	for ( rows = 1, col = 0; col < 4; col++)
    	{
    		temp2 += pow( (*num_ptr)[rows][col], 2.0 );
    	}
    
    	for ( rows = 2, col = 0; col < 4; col++)
    	{
    		temp3 += pow( (*num_ptr)[rows][col], 2.0 );
    	}
    
    	sum = temp1 + temp2 + temp3;
    
    return sum;
    }
    
    /******************************* GetData() ***************************/
    void GetData( int num[][4] )
    {
    	int i = 0;	
    	char instring[15] = {0};
    
        printf( "Please enter the first row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[0][i] = atoi( gets( instring ) );
    	}
    
    	
    	printf( "Please enter the second row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[1][i] = atoi( gets( instring ) );
    	}
    
    	printf( "Please enter the third row of four integers now: \n" );
    	for ( i = 0; i < 4; i++ )
    	{
    		printf( "#%2d: ", i + 1 );
    		num[2][i] = atoi( gets( instring ) );
    	}
    		
    }
    Last edited by Polymorphic OOP; 12-05-2002 at 10:51 PM.

  3. #3
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    You're using an int * to access a 2D array with array subscripts. This won't work too well, so you need to calculate the spot in the array you want to be at. You can do this by saying array[cols * x + y], and it works fine!
    Code:
    #include <stdio.h>
    
    show(int *num, int rows, int cols){
        int x, y;
    
        for (x = 0; x < rows; x++){
            for (y = 0; y < cols; y++)
                printf("%d ", num[cols * x + y]);
            printf("\n");
        }
    }
    
    main(){
        int num[3][4] = {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
        };
    
        int *p = num[0];
    
        show(p, 3, 4);
    }

  4. #4
    Registered User
    Join Date
    Sep 2002
    Posts
    37
    You see, I am a total beginner, thrown into a deep sea trying to swim...
    Let me then explain what the program is supposed to do:
    user enters all the integers to fill in an array num[3][4] (these dimensions only). Then I have to write a function to use in this program with 3 parameters: address of the array, no of rows and no of columns... The function calculates the sum of squares of all integers in the array (each int is squared and then they are all added up). That's what sumsquares is supposed to do.

    When I initially tried to avoid giving all the dimensions, I keep getting either an error message (syntax error) or at least a warning. That's why I am so confused.

  5. #5
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    Code:
    double sumsquares( int *num_ptr, int rows, int col )
    {
        double sum = 0;
        double temp1 = 0;
        double temp2 = 0;
        double temp3 = 0;
        
        int x, y;
        
        for ( x = 0, y = 0; y < 4; y++)
        {
            temp1 += pow( num_ptr[col * x + y], 2.0 );
        }
        
        for ( x = 1, y = 0; y < 4; y++)
        {
            temp2 += pow( num_ptr[col * x + y], 2.0 );
        }
        
        for ( x = 2, y = 0; y < 4; y++)
        {
            temp3 += pow( num_ptr[col * x + y], 2.0 );
        }
        
        sum = temp1 + temp2 + temp3;
        
        return sum;
    }
    Then make the call like this:
    Code:
    sumsq = sumsquares( num[0], rows, col );
    Like magic, it works! There might be more problems though, I didn't look real hard.

  6. #6
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Here're the functions to be able to accept varying numbers of dimension lengths.


    Code:
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    
    
    /* function prototypes */
    void GetData( int* num_ptr, int numrows, int numcols );
    double sumsquares( int* num_ptr, int numrows, int numcols );
    
    
    int main( void )
    {
    	int num[3][4] = {0};
    	double sumsq = 0.0;
    
    	GetData( *num, 3, 4 );
    
    	sumsq = sumsquares( *num, 3, 4 );
    	printf( "The sum of squares of each integer is: %.0f.\n", sumsq);
    
    	return 0;
    }
    
    
    
    /******************************* sumsquares() *********************************/
    double sumsquares( int* num_ptr, int numrows, int numcols )
    {
    	double sum = 0.0;
    
    	for ( int row = 0; row < numrows; ++row )
    		for ( int col = 0; col < numcols; ++col )
    			sum +=pow( num_ptr[row * numcols + col], 2.0 );
    
    	return sum;
    }
    
    /******************************* GetData() ***************************/
    void GetData( int* num_ptr, int numrows, int numcols )
    {
    	int row, col;
    
    	for ( row = 0; row < numrows; ++row )
    	{
    		printf( "Please input row %d of %d integers now: \n", row + 1, numcols );
    		for ( col = 0; col < numcols; ++col )
    		{
    			printf( "#%d: ", col + 1 );
    			scanf( "%d", &num_ptr[row * numcols + col] );
    		}
    	}	
    }

  7. #7
    Registered User
    Join Date
    Sep 2002
    Posts
    37
    Thanks to both of you, I need to do some more extensive reading ion the subject and be more careful too
    Thanks again!

  8. #8
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Salem, the reason why we did is because he specifically stated that you should be able to pass a 2 dimensional array with each dimension being of any length. The only way he can do that is if he calculates the index himself! If you noticed my first example, i actually told him to do what you said, however, in the next post, he said the function had to allow for all different combinations of dimension lengths so I posted another response! You can't do it the way you want and I want. It's got to account for all situations!
    Last edited by Polymorphic OOP; 12-06-2002 at 03:54 AM.

  9. #9
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    i strongly discourage against this "flattening of the array" technique (as outlined in question 6.19 of that faq); it is not guaranteed to work.
    hello, internet!

  10. #10
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    Link:
    It must be noted, however, that a program which performs multidimensional array subscripting ``by hand'' in this way is not in strict conformance with the ANSI C Standard; according to an official interpretation, the behavior of accessing (&array[0][0])[x] is not defined for x >= NCOLUMNS.
    Hammer:
    i strongly discourage against this "flattening of the array" technique (as outlined in question 6.19 of that faq); it is not guaranteed to work.
    Could someone explain to me why it's not guaranteed to work? I don't quite understand the details of the link and Hammer was pretty vague.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >Could someone explain to me why it's not guaranteed to work?
    It must be noted, however, that a program which performs multidimensional array subscripting "by hand" in this way is not in strict conformance with the ANSI C Standard; according to an official interpretation, the behavior of accessing (&array[0][0])[x] is not defined for x >= NCOLUMNS.
    Undefined behavior (accessing the array beyond its bounds) cannot be guaranteed to work correctly. After all, its behavior is undefined. The following is another related example.
    J.2 Undefined behavior
    The behavior is undefined in the following circumstances:
    — An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

  12. #12
    Registered User
    Join Date
    Sep 2002
    Posts
    37

    Smile

    Thanks, Salem, for explanation, and everybody else too for your input.
    It seems to me there was a misunderstanding at the beginning. I tried to say that the array is [3][4] and that it is the address of this particular array to be a parameter...
    Thanks again!

  13. #13
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>... and Hammer was pretty vague.
    Very vague, considering I didn't actually write anything Mistaken identity, I believe.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Replies: 6
    Last Post: 05-15-2009, 08:38 AM
  3. Pointer with Multi-dimensional Array
    By whichet in forum C Programming
    Replies: 7
    Last Post: 11-28-2007, 12:26 AM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM