469,649 Members | 1,209 Online

Assignment: Print 2D array

Assignment: Create a 3x4 2-dimensional array of integers. Populate each
element using some non-random scheme so that no two elemens contain the
same value. Then create two functions for printing the 2D array. One
should only work for set column size, accepting only the number of rows
as an additional argument, one should accept both the number of rows
and columns as arguments.

So, I came up with:
#include <stdio.h>

static void print_2d_array(int[][4], int);
static void print_2d_array_2(const int *, int, int);

int
main(void)
{
int array[3][4] =
{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
int num_rows = sizeof(array) / sizeof(array[0]);
int num_cols = sizeof(array[0]) / sizeof(array[0][0]);

print_2d_array(array, num_rows);
print_2d_array_2(&array[0][0], num_rows, num_cols);

return 0;
}

/* Even if specify int array[2][4], the compiler would
happily accept our 3x4 array. Therefore we leave
that dimension empty, passing the number of rows
as an argument. However, if we try to pass a 2D-array
where the number of columns is not 4, the compiler
will complain. */
static void
print_2d_array(int array[][4], int num_rows)
{
int row = 0;
int column = 0;

for(row = 0; row < num_rows; ++row)
for(column = 0; column < 4; ++column)
printf("[%i][%i] = %i\n", row, column, array[row][column]);
}

static void
print_2d_array_2(const int *ptr, int num_rows, int num_columns)
{
int currow = 0;
int curcol = 0;
int offset = 0;

for(; currow < num_rows; ++currow)
{
for(curcol = 0; curcol < num_columns; ++curcol) /* curcol = 0
needed! */
{
/* The layout of the 2D-array is linear as seen by our
program,
on a row-by-row basis. All rows have the same number of
columns.
Rows and columns are indexed starting from 0.
So if we have five colums per row and we want the element
in
the second column of the second row, we want element with
offset
six (offset 0 gives us the element at [0][0]).
offset = index_of_wanted_row * num_cols_per_row +
index_of_wanted_column
or
offset = 1 * 5 + 1 = 6 */
offset = currow * num_columns + curcol;
printf("[%i][%i] = %i\n", currow, curcol, *(ptr + offset));
}
}
}
Output when run:
\$ ./foo.exe
Calling print_2d_array().
[0][0] = 0
[0][1] = 1
[0][2] = 2
[0][3] = 3
[1][0] = 4
[1][1] = 5
[1][2] = 6
[1][3] = 7
[2][0] = 8
[2][1] = 9
[2][2] = 10
[2][3] = 11
Calling print_2d_array_2().
[0][0] = 0
[0][1] = 1
[0][2] = 2
[0][3] = 3
[1][0] = 4
[1][1] = 5
[1][2] = 6
[1][3] = 7
[2][0] = 8
[2][1] = 9
[2][2] = 10
[2][3] = 11

Is this what my instructor is after?

/ E

Apr 12 '06 #1
3 10374
Eric Lilja wrote:
Assignment: Create a 3x4 2-dimensional array of integers. Populate each
element using some non-random scheme so that no two elemens contain the
same value. Then create two functions for printing the 2D array. One
should only work for set column size, accepting only the number of rows
as an additional argument, one should accept both the number of rows
and columns as arguments.
Good, you've given us the problem statement for the program and you are
not trying to hide that it is homework. A pleasant change.
So, I came up with:
#include <stdio.h>

static void print_2d_array(int[][4], int);
I would avoid using a magic number. Use a #define instead:
#define NO_COLS 4
static void print_2d_array(int[][NO_COLS], int);
static void print_2d_array_2(const int *, int, int);
As a matter of style I would prefer having the parameters names in the
prototype. Also, why only specify const in one of the two functions?
int
main(void)
{
int array[3][4] =
You did not need to specify the number of rows. You could have used:
int array[][4] =
Or, with the change above:
int array[][NO_COLS] =
{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
int num_rows = sizeof(array) / sizeof(array[0]);
int num_cols = sizeof(array[0]) / sizeof(array[0][0]);

print_2d_array(array, num_rows);
print_2d_array_2(&array[0][0], num_rows, num_cols);

return 0;
}

/* Even if specify int array[2][4], the compiler would
happily accept our 3x4 array. Therefore we leave
that dimension empty, passing the number of rows
as an argument. However, if we try to pass a 2D-array
where the number of columns is not 4, the compiler
will complain. */
static void
print_2d_array(int array[][4], int num_rows)
Again with the magic number.
{
int row = 0;
int column = 0;

for(row = 0; row < num_rows; ++row)
for(column = 0; column < 4; ++column)
And again. Lots of changes if you want to change the number of columns!
printf("[%i][%i] = %i\n", row, column, array[row][column]);
}

static void
print_2d_array_2(const int *ptr, int num_rows, int num_columns)
{
int currow = 0;
int curcol = 0;
int offset = 0;
I would not bother initialising these here.
for(; currow < num_rows; ++currow)
As a matter of style I would initialise currow in the for loop rather
than on declaration. Then it does not matter if things change.
for(currow = 0; currow < num_rows; ++currow)
{
for(curcol = 0; curcol < num_columns; ++curcol) /* curcol = 0
needed! */
{
/* The layout of the 2D-array is linear as seen by our
program,
on a row-by-row basis. All rows have the same number of
columns.
Rows and columns are indexed starting from 0.
So if we have five colums per row and we want the element
in
the second column of the second row, we want element with
offset
six (offset 0 gives us the element at [0][0]).
offset = index_of_wanted_row * num_cols_per_row +
index_of_wanted_column
or
offset = 1 * 5 + 1 = 6 */
offset = currow * num_columns + curcol;
printf("[%i][%i] = %i\n", currow, curcol, *(ptr + offset));
Array notation would be easier to read IMHO:
printf("[%i][%i] = %i\n", currow, curcol, ptr[offset]);
Alternatively, assuming there is no risk of wanting to use some other
order, you could get rid of offset all together and use
printf("[%i][%i] = %i\n", currow, curcol, *ptr++);
}
}
}

Output when run:
\$ ./foo.exe
Calling print_2d_array().
[0][0] = 0
<snip>
Is this what my instructor is after?

It looks good to me. I've suggested a few style changes/improvements,
but functionally what you've done seems correct.

Also, you are to be congratulated for your posting style. You've
provided your complete program, the output you get, the original problem
statement, and your question. Feel free to ask further questions here
and good luck with your course.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 12 '06 #2

Flash Gordon wrote:
Eric Lilja wrote:
Assignment: Create a 3x4 2-dimensional array of integers. Populate each
element using some non-random scheme so that no two elemens contain the
same value. Then create two functions for printing the 2D array. One
should only work for set column size, accepting only the number of rows
as an additional argument, one should accept both the number of rows
and columns as arguments.
Good, you've given us the problem statement for the program and you are
not trying to hide that it is homework. A pleasant change.
So, I came up with:
#include <stdio.h>

static void print_2d_array(int[][4], int);

I would avoid using a magic number. Use a #define instead:
#define NO_COLS 4

Good point. I prefer symbolic names.
static void print_2d_array(int[][NO_COLS], int);
static void print_2d_array_2(const int *, int, int);
As a matter of style I would prefer having the parameters names in the
prototype. Also, why only specify const in one of the two functions?

Some gnu style iirc my instructor uses. So I use it too. :-)
int
main(void)
{
int array[3][4] =
You did not need to specify the number of rows. You could have used:
int array[][4] =
Or, with the change above:
int array[][NO_COLS] =
{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
int num_rows = sizeof(array) / sizeof(array[0]);
int num_cols = sizeof(array[0]) / sizeof(array[0][0]);

print_2d_array(array, num_rows);
print_2d_array_2(&array[0][0], num_rows, num_cols);

return 0;
}

/* Even if specify int array[2][4], the compiler would
happily accept our 3x4 array. Therefore we leave
that dimension empty, passing the number of rows
as an argument. However, if we try to pass a 2D-array
where the number of columns is not 4, the compiler
will complain. */
static void
print_2d_array(int array[][4], int num_rows)

Again with the magic number.
{
int row = 0;
int column = 0;

for(row = 0; row < num_rows; ++row)
for(column = 0; column < 4; ++column)

And again. Lots of changes if you want to change the number of columns!
printf("[%i][%i] = %i\n", row, column, array[row][column]);
}

static void
print_2d_array_2(const int *ptr, int num_rows, int num_columns)
{
int currow = 0;
int curcol = 0;
int offset = 0;

I would not bother initialising these here.

Well, I always like to initialize my variables.
for(; currow < num_rows; ++currow)
As a matter of style I would initialise currow in the for loop rather
than on declaration. Then it does not matter if things change.
for(currow = 0; currow < num_rows; ++currow)
{
for(curcol = 0; curcol < num_columns; ++curcol) /* curcol = 0
needed! */
{
/* The layout of the 2D-array is linear as seen by our
program,
on a row-by-row basis. All rows have the same number of
columns.
Rows and columns are indexed starting from 0.
So if we have five colums per row and we want the element
in
the second column of the second row, we want element with
offset
six (offset 0 gives us the element at [0][0]).
offset = index_of_wanted_row * num_cols_per_row +
index_of_wanted_column
or
offset = 1 * 5 + 1 = 6 */
offset = currow * num_columns + curcol;
printf("[%i][%i] = %i\n", currow, curcol, *(ptr + offset));

Array notation would be easier to read IMHO:
printf("[%i][%i] = %i\n", currow, curcol, ptr[offset]);

Right, I didn't realise I could do that. Any maybe rename offset to
index?
Alternatively, assuming there is no risk of wanting to use some other
order, you could get rid of offset all together and use
printf("[%i][%i] = %i\n", currow, curcol, *ptr++);
}
}
}

Output when run:
\$ ./foo.exe
Calling print_2d_array().
[0][0] = 0
<snip>
Is this what my instructor is after?

It looks good to me. I've suggested a few style changes/improvements,
but functionally what you've done seems correct.

Feels good the core program was correct! The changes you pointed out
concerns style mostly. Important to me, but a user couldn't have telled
the difference.

Also, you are to be congratulated for your posting style. You've
provided your complete program, the output you get, the original problem
statement, and your question. Feel free to ask further questions here
and good luck with your course.
Thanks alot!
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

/ E

Apr 12 '06 #3
Eric Lilja wrote:
Flash Gordon wrote:
Eric Lilja wrote:
<snip>
static void
print_2d_array_2(const int *ptr, int num_rows, int num_columns)
{
int currow = 0;
int curcol = 0;
int offset = 0; I would not bother initialising these here.

Well, I always like to initialize my variables.

Others agree, I don't if from the usage it is obvious that is will be
set before use.

<snip>
offset = currow * num_columns + curcol;
printf("[%i][%i] = %i\n", currow, curcol, *(ptr + offset));

Array notation would be easier to read IMHO:
printf("[%i][%i] = %i\n", currow, curcol, ptr[offset]);

Right, I didn't realise I could do that. Any maybe rename offset to
index?

Indeed.

<snip>
Feels good the core program was correct! The changes you pointed out
concerns style mostly. Important to me, but a user couldn't have telled
the difference.

Style is important too. After all, in real projects you might have to go
back to the code 10 years later and understand it. I'm not kidding here,
at work I've had to modify (Pascal) code I wrote 10 years or more
earlier due to new requirements, and based on the contracts when I left
the company others could still have to maintain it another 20 years down
the line!

<snip>
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

/ E

One small point. Please don't quote signatures (e.g. the bit after the
"-- " in my post or the "/ E" in yours unless you are commenting on them.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 13 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.