J.Doe J.Doe - 1 month ago 43
C Question

How to pass pointers in a function?

I'm writing a program that does the following. I'm done with my code and I think is good however I'm trying to do the following which I I can't figure out.

1.Pass a pointer to the matrix to a function, and have the function change the matrix. The main function should define the array, initialize it, then call (a) function(s) to manipulate it.

2.Use letters 'A' through 'Z', then letters 'a' through 'z'. This means that the random walk will go up to 52 places. For this one I already have letters A through Z but don't know how to have 'a' to 'z'

Write a program that generates a “random walk” across a 10 x 10 array. The array will contain character (all ‘.’ Initially). The program must randomly “walk” from element to element, always going up, down, left, or right by one element. Z, in the order visited. Here’s an example of the desired output:
A . . . . . . . . .
B C D . . . . . . .
. F E . . . . . . .
H G . . . . . . . .
I . . . . . . . . .
J . . . . . . . . .
K . . R S T U V Y .
L M P Q . . . W X .
. N O . . . . . . .
. . . . . . . . . .

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


int main ()
{


void printarray(char array[12][12], int x, int y); /*Function prototype*/



int i = 0, roll = 0, row = 0, col = 0, rowcheck = 0, colcheck = 0; /*i = number of moves. roll = value generated by the random number generator. r = row location. col = column location. rowcheck and colcheck are the incremented and decremented values of row and col respectively, used to check whether a legal move can be performed*/
char position[12][12], chtr = 'A'; /*position[12][12] = Grid for the walking. chtr = the letters of the Alphabet.*/

for (row = 0; row < 12; row++) /*Fills the 12 x 12 array with the "." character*/
{
for (col = 0; col < 12; col++)
{
position[row][col] = '.';
}
}

srand(5000); /*Seeds the random number function*/

for (i = 0, row = 0, col = 0, rowcheck = 0, colcheck = 0; i < 25;)
{
rowcheck = row;
colcheck = col;
roll = rand() % 4;
switch (roll) /*Determines what direction to move starting from the top left corner of the grid (bird's eye view)*/
{
case 0: /*Move up*/
{
rowcheck--;
}
case 1: /*Move left*/
{
colcheck--;
}
case 2: /*Move down*/
{
rowcheck++;
}
case 3: /*Move right*/
{
colcheck++;
}
}
if ((rowcheck < 0 || rowcheck > 9) || (colcheck < 0 || colcheck > 9) || (position[rowcheck][colcheck] != '.'))
{
continue;
}
else
{
row = rowcheck;
col = colcheck;
position[row][col] = chtr;
chtr++;
printarray(position, row, col);
i++;
}
}

exit (0);
}

/*Function declaration*/
void printarray(char array[12][12], int x, int y){

printf("CURRENT POSITION %d %d\n", x, y);
for (x = 0; x < 12; x++) /*Prints out the values of the array*/
{
for (y = 0; y < 12; y++)
{
printf("%c", array[x][y]);
}
printf("\n");
}
printf("\n");





}

Answer

OK, your issues are pure logic issues. The primary issue you have is:

if ((rowcheck < 0 || rowcheck > 9) || 
    (colcheck < 0 || colcheck > 9) || 
    (position[rowcheck][colcheck] != '.'))

This will invoke undefined behavior any time rowcheck or colcheck is less than 0 or greater than 11. (you set position[rowcheck][colcheck] regardless of the values, which can easily be set outside the limits of position)

The remainder of your issues are similar failures to control the values of rowcheck or colcheck within the switch statement itself. You need to test the values before you increment or decrement them -- forcing the values to remain within limits, e.g.:

    switch (roll) {
    case 0:                /*Move up */
        if (rowcheck > 0)
            rowcheck--;
        break;
    ...

I'm not entirely sure what you are attempting to accomplish, but the following would be a cleanup on your code that seems to be what you are looking for (although I'm not sure it iterates or increments over your full intended range) You also do not need math.h as your code is written, and I included string.h for memset eliminating your '.' initialization loops.

You will also get a much better random distribution if you use something other than srand (5000); One simple option is to include time.h and use srand (time (NULL));

Lastly, avoid magic numbers in your code (e.g. 12, and 9). If you need constants #define them or use an enum to set global constants (shown below):

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

enum { MAXC = 9, DIM = 12 };

void printarray (char array[DIM][DIM], int x, int y);   /*Function prototype */

int main (void) {

    int i = 0, roll = 0, row = 0, col = 0, rowcheck = 0, colcheck = 0;
    char position[DIM][DIM], chtr = 'A';

    /*Fills the DIM x DIM array with the '.' character */
    memset (position, '.', sizeof position);

    srand (time (NULL));       /* Seeds the random number function */

    for (i = 0, row = 0, col = 0, rowcheck = 0, colcheck = 0; i < 25; i++) {
        rowcheck = row;
        colcheck = col;
        roll = rand () % 4;

        switch (roll) {
        case 0:                /*Move up */
            if (rowcheck > 0)
                rowcheck--;
            break;
        case 1:                /*Move left */
            if (colcheck > 0)
                colcheck--;
            break;
        case 2:                /*Move down */
            if (rowcheck < DIM - 2)
                rowcheck++;
            break;
        case 3:                /*Move right */
            if (colcheck < DIM - 2)
                colcheck++;
            break;
        }

        if (rowcheck > MAXC || colcheck > MAXC || 
            position[rowcheck][colcheck] != '.')
            continue;

        row = rowcheck;
        col = colcheck;
        position[row][col] = chtr;

        if (chtr < 'Y')     /* allow lower and upper case */
            chtr++;
        else if (chtr == 'Z')
            chtr = 'a';
        else if (chtr > 'a' && chtr < 'z')
            chtr++;
        else
            chtr = 'A';

        printarray (position, row, col);
    }

    exit (0);
}

/*Function declaration */
void printarray (char array[DIM][DIM], int x, int y)
{
    printf ("CURRENT POSITION %d %d\n", x, y);
    for (x = 0; x < DIM; x++) { /*Prints out the values of the array */
        for (y = 0; y < DIM; y++) {
            printf ("%c", array[x][y]);
        }
        printf ("\n");
    }
    printf ("\n");
}

Look it over and let me know if you have further questions, or if you want to add additional information to what you are intending to do.