Thread: 10 x 10 Array

  1. #1
    Registered User
    Join Date
    Feb 2014
    Posts
    9

    10 x 10 Array

    Hello,
    I have written a code that:
    1) Constructs a 10x10 2d array filled with random numbers between 0 and 9
    2) Takes the sum of the first row
    3) Takes the average of the diagonal
    4) Counts the number of zeros in the first column

    The next step which I am having much difficulty with is generating a new array whose diagonal has numbers greater than or equal to 7. I have attempted many modifications to the code, however nothing seems to be working. I will post my code along with the output I am recieving.
    Code:
    int main (void)
    {
        srand((int)time(NULL));
        int my_array[10][10],my_array2[10][10],i,j,k,l,sum=0,sumdiag=0,zerocount=0,diagcount=0,diag=0;
        double avg;
        for (i = 0; i<10; i++)
        {
        for (j = 0; j<10; j++)
        {
        my_array[i][j] = rand() % 10;
        printf("%d\t",my_array[i][j]);
        }
        printf("\n");
        }
        for(i=0;i<1;i++)
        {
        for (j=0;j<10;j++)
        {
        sum=my_array[i][j]+sum;
        }
        }
    printf("\nThe sum of the first row is %d.\n",sum);
        for(i=0;i<10;i++)
        {
        for (j=0;j<10;j++)
        {
        if(i==j)
        {
        sumdiag=my_array[i][j]+sumdiag;
        }
        }
        }
        avg=(double)sumdiag/10;
    printf("The average of the diagonal is %.3lf.\n",avg);
        for(i=0;i<10;i++)
        {
        for (j=0;j<10;j++)
        {
        if(j==0&&(my_array[i][j]==0))
        {
        zerocount=zerocount+1;
        }
        }
        }
    printf("The amount of zeros in the first column is %d.\n\n",zerocount);
        do
        {
            for (k = 0; k<10; k++)
        {
            for (l = 0; l<10; l++)
            {
                my_array2[k][l] = rand() % 10;
                diag=(k==l);
                printf("%d\t",my_array2[k][l]);
            }
            printf("\n");
        }
        }while((diag)&&(my_array2[k][l]<7));
       
    
    
        return(0);
        
    }
    
    


    The output I received was:
    1 4 5 8 1 3 9 8 6 9
    7 5 8 8 5 0 9 9 9 9
    0 2 3 6 2 2 0 7 8 2
    4 0 7 8 1 1 4 2 8 1
    0 4 8 6 8 3 5 6 1 0
    3 1 9 1 2 7 2 2 7 8
    6 5 0 9 1 2 3 5 0 3
    8 3 3 5 8 7 0 9 3 1
    1 5 4 9 2 3 2 3 7 7
    8 0 8 5 7 3 0 0 9 7


    The sum of the first row is 54.
    The average of the diagonal is 5.800.
    The amount of zeros in the first column is 2.


    5 3 0 7 1 6 4 8 7 4
    3 7 5 4 7 5 3 1 7 2
    8 8 8 4 4 5 6 3 3 2
    7 5 8 1 8 1 2 5 7 8
    6 8 4 0 0 0 5 0 1 8
    5 1 0 9 3 7 6 4 0 4
    3 6 4 8 6 9 4 4 4 2
    9 5 9 4 0 3 9 4 2 0
    6 4 4 9 1 0 8 7 2 7
    3 0 2 2 4 9 1 7 9 5

    The issue arises when I construct my new array... the condition is not displayed properly.
    What I tried doing for the second array was create a do while loop which initially creates the array and then checks the condition.
    Any tips on how I can get this to work are greatly appreciated!
    Thank you to everyone in advance.


  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Firstly, you need to work on your indentation. As you have it, your indentation increases chances of getting confused about what brace goes with what.

    Code like this (which is a direct copy of some of yours)
    Code:
    for(i=0;i<10;i++)
        {
        for (j=0;j<10;j++)
        {
        if(i==j)
        {
        sumdiag=my_array[i][j]+sumdiag;
        }
        }
        }
    is more understandable like
    Code:
    for(i=0;i<10;i++)
    {
        for (j=0;j<10;j++)
        {
             if(i==j)
            {
                 sumdiag=my_array[i][j]+sumdiag;
            }
        }
    }
    is exactly the same (I've only improved indenting, for readability) but it is clearer which braces do what.

    To pick on this snippet a bit more, why have two loops in this case? The inner loop is only doing stuff when i and j are equal. So the inner loop is not needed at all. (A classic symptom that you simply copied a previous loop and modified it, without thinking too much about what the code needed to do).



    As to the problem you're asking about, look at the last loop, which I recreate here with hopefully better indenting.
    Code:
    do
    {
         for (k = 0; k<10; k++)
        {
            for (l = 0; l<10; l++)
            {
                my_array2[k][l] = rand() % 10;
                diag=(k==l);
                printf("%d\t",my_array2[k][l]);
            }
            printf("\n");
        }
    }while((diag)&&(my_array2[k][l]<7));
    Look particularly at what is happening with k and l. After the inner for loops are done, k and l will both be 10 - always (variables used in for loops keep their last value). So, effectively, the while condition is
    Code:
    } while (diag && my_array2[10][10] < 7);
    my_array2[10][10] does not exist (for a 10x10 array), so accessing it gives undefined behaviour.

    Somehow you need to rework the "less than 7" test so it is within the contained for loops (and presumably so it tests every diagonal, rather than a non-existent one). I'll leave that as an exercise.

    I also suggest that rather than declaring all your variables at the top, only introduce them when needed. So, instead of
    Code:
    int main()
    {
         int k,l;
    
         do
         {
             for (k = 0; k < 10; ++k)
            {
                for (l = 0; l < 1; ++l)
                {
                    /* stuff */
                }
            }
       } while (something_with(k,l));
    do this
    Code:
    int main()
    {
         /*  Don't define loop variables here */
         do
         {
             for (int k = 0; k < 10; ++k)     /*   Define loop variable only when needed */
            {
                for (int l = 0; l < 1; ++l)
                {
                    /* stuff */
                }
            }
       } while (something_with(k,l));
    The two are actually (almost) equivalent, except that the scope of k and l is constrained (i.e. they can only be used in their respective loops). This would cause the compiler to complain about the while loop, since k and l no longer exist in the "while(something_with(k,l));" This would have allowed the compiler to detect your problem, rather than confusing you. In short: hoisting loop control variables to the top of the containing function is a REALLY bad habit, since it allows bugs like yours to go unnoticed (using a variable in the wrong place).


    Use more descriptive variable names than i,j,k,l, my_array. The compiler doesn't care (within limits) how you name your variables. But using meaningless names is an easy way to increase your confusion, so use names that convey information about what the variable is and what is done with it (instead of i and j use something like row and column).

    Also, avoid one-letter variable names if you can. Apart from the fact that naming a variable row conveys more information - to the programmer - than naming it i, single letters can look like other things. For example, 'l' and '1' look a lot a like, so it is really easy to make a mistake of using one when you intend the other. "row = 1" and "row = l" have very different meanings but look very similar to human eyes.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    The only thing with waiting for the computer to find a valid array is that it will only be practical for smallish array sizes.

    The run time for even a 30 30 will be looooooong.

    Whereas its possible to create a valid array in one pass by using rand() modified for the diagonal.

  4. #4
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    Is it possible to do this with an if statement? This was something else I tried:

    Code:
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    
    
    int main (void)
    {
        srand((int)time(NULL));
        int my_array[10][10],my_array2[10][10],i,j,k,l,sum=0,sumdiag=0,zerocount=0,diagcount=0,diag=0;
        double avg;
            for (i = 0; i<10; i++)
            {
                for (j = 0; j<10; j++)
            {
                my_array[i][j] = rand() % 10;
                printf("%d\t",my_array[i][j]);
            }
                printf("\n");
            }
            for(i=0;i<1;i++)
            {
                for (j=0;j<10;j++)
                {
                    sum=my_array[i][j]+sum;
                }
            }
    printf("\nThe sum of the first row is %d.\n",sum);
            for(i=0;i<10;i++)
            {
                for (j=0;j<10;j++)
                {
                    if(i==j)
                    {
                        sumdiag=my_array[i][j]+sumdiag;
                    }
                }
            }
            avg=(double)sumdiag/10;
    printf("The average of the diagonal is %.3lf.\n",avg);
            for(i=0;i<10;i++)
            {
                for (j=0;j<10;j++)
                {
                    if(j==0&&(my_array[i][j]==0))
                    {
                        zerocount=zerocount+1;
                    }
                }
            }
    printf("The amount of zeros in the first column is %d.\n\n",zerocount);
    
            for (k = 0; k<10; k++)
            {
                for (l = 0; l<10; l++)
                {
                    my_array2[k][l] = rand() % 10;
                    if(my_array2[k][k]>=7)
                    {printf("%d\t",my_array2[k][l]);}
                }
                printf("\n");
            }
    
        return(0);
    
    }
    


    However, the output was the following:

    8 5 0 5 4 2 3 4 2 8
    7 2 7 5 3 2 1 9 6 0
    7 7 1 3 9 5 9 4 2 4
    9 8 9 8 7 3 0 3 3 3
    1 2 1 4 7 6 0 2 3 9
    2 1 2 3 7 7 8 7 3 8
    7 6 5 9 3 3 7 8 2 7
    5 7 4 6 4 9 6 4 4 5
    0 6 6 9 4 4 0 4 9 1
    2 0 9 2 5 7 0 3 1 5


    The sum of the first row is 41.
    The average of the diagonal is 5.800.
    The amount of zeros in the first column is 1.


    9 5 0 4 8 9 8 0 2 3


    7 5 5 1 2 4 0 9


    7 3 4 6 0 6


    7 3 4 8




    8
    Program ended with exit code: 0

    Was what I had before (using a do while loop) the more correct way of finding the correct diagonal?

  5. #5
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,767
    I can't read code formatted like that

    One command line program, and one edit (removed the parenthesis around the return value -- return is an operator not a function)

    See: Artistic Style - Index There's pre-compiled binaries for Linux, OSX and Windows.

    Code:
    $ astyle -A1 -p nic.c 
    Formatted nic.c
    Of course it's better to indent properly from scratch. It's not for the compiler it's to help your comprehension (and other people's as well) of the code. Get into the habit of properly indenting and you don't even think about it.



    Code:
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    
    
    int main (void)
    {
        srand((int)time(NULL));
        int my_array[10][10], my_array2[10][10], i, j, k, l, sum = 0, sumdiag = 0, zerocount = 0, diagcount = 0, diag = 0;
        double avg;
    
        for (i = 0; i < 10; i++)
        {
            for (j = 0; j < 10; j++)
            {
                my_array[i][j] = rand() % 10;
                printf("%d\t", my_array[i][j]);
            }
            printf("\n");
        }
        for(i = 0; i < 1; i++)
        {
            for (j = 0; j < 10; j++)
            {
                sum = my_array[i][j] + sum;
            }
        }
        printf("\nThe sum of the first row is %d.\n", sum);
        for(i = 0; i < 10; i++)
        {
            for (j = 0; j < 10; j++)
            {
                if(i == j)
                {
                    sumdiag = my_array[i][j] + sumdiag;
                }
            }
        }
        avg = (double)sumdiag / 10;
        printf("The average of the diagonal is %.3lf.\n", avg);
        for(i = 0; i < 10; i++)
        {
            for (j = 0; j < 10; j++)
            {
                if(j == 0 && (my_array[i][j] == 0))
                {
                    zerocount = zerocount + 1;
                }
            }
        }
        printf("The amount of zeros in the first column is %d.\n\n", zerocount);
    
        for (k = 0; k < 10; k++)
        {
            for (l = 0; l < 10; l++)
            {
                my_array2[k][l] = rand() % 10;
                if(my_array2[k][k] >= 7)
                {
                    printf("%d\t", my_array2[k][l]);
                }
            }
            printf("\n");
        }
    
        return 0;
    
    }

  6. #6
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    I'm just wondering if I am on the right track...
    These would be the loops that would check the condition:
    Code:
    for (k = 0; k<10; k++)
        {
            for (l= 0; l<10; l++)
            {
                my_array2[k][l] = rand() % 10;
            }
        }
            while(my_array2[k][k]<7)
            {
            diagcount= diagcount +1;
            }
    
    


    Is this correct? I know that I somehow need to combine them.

    **Note: I am also counting how many times the array is generated until it successfully satisfies the condition.
    Last edited by nicole0808; 03-29-2014 at 01:10 PM.

  7. #7
    Registered User
    Join Date
    Feb 2014
    Posts
    9
    Thanks for the help, I finally got it to work!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 07-31-2013, 12:15 AM
  2. Replies: 4
    Last Post: 05-30-2013, 05:45 PM
  3. Replies: 2
    Last Post: 03-20-2012, 08:41 AM
  4. Replies: 9
    Last Post: 08-23-2010, 02:31 PM
  5. Replies: 6
    Last Post: 11-09-2006, 03:28 AM