c - Pointers, Arrays and Functions -
i programmed function can rotate 4 x 4 arrays, , want output it... bunch warnings, compiles , works, guess did "minor/formal" mistakes.
#include <stdio.h> //----------------------------------------------------------------------------- /// /// function prints 4 4x4 matrix /// /// @param m1, m2, m3, m4 input matrix want print. /// /// @return 0 //----------------------------------------------------------------------------- void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4]) { for(int = 0; < 4; i++) { for(int j = 0; j < 4; j++) { printf("%c ", m1[i][j]); } printf(" "); for(int j = 0; j < 4; j++) { printf("%c ", m2[i][j]); } printf(" "); for(int j = 0; j < 4; j++) { printf("%c ", m3[i][j]); } printf(" "); for(int j = 0; j < 4; j++) { printf("%c ", m4[i][j]); } printf("\n"); } printf("\n"); return 0; } //----------------------------------------------------------------------------- /// /// function rotates 4x4 matrix /// (and collects tears overworked students @2am, because wtf ) /// /// @param m, matrix want rotate /// /// @return m_r rotated matrix //----------------------------------------------------------------------------- char *rotate_matrix(char m[4][4]) { static char m_r[4][4]; for(int = 0; < 4; i++) { for(int j = 0; j < 4; j++) { m_r[i][j] = m[3-j][i]; } } return *m_r; } int main(void) { char matrix_t [4][4] = {{ '-', '-', '-', '-' }, { '-', 'o', '-', '-' }, { 'o', 'o', 'o', '-' }, { '-', '-', '-', '-' } }; char matrix_z [4][4] = {{ '-', '-', '-', '-' }, { '-', 'o', 'o', '-' }, { 'o', 'o', '-', '-' }, { '-', '-', '-', '-' } }; char matrix_l [4][4] = {{ '-', '-', '-', '-' }, { '-', 'o', '-', '-' }, { '-', 'o', '-', '-' }, { '-', 'o', 'o', '-' } }; char matrix_i [4][4] = {{ '-', '-', 'o', '-' }, { '-', '-', 'o', '-' }, { '-', '-', 'o', '-' }, { '-', '-', 'o', '-' } }; char (*array)[4][4]; print_matrix(matrix_t, matrix_z, matrix_l, matrix_i); array = rotate_matrix(matrix_t); print_matrix(array, matrix_z, matrix_l, matrix_i); return 0; }
this errors get:
102:9: warning: assignment incompatible pointer type [-wincompatible-pointer-types] array = rotate_matrix(matrix_t);
,
103:16: warning: passing argument 1 of ‘print_matrix’ incompatible pointer type [-wincompatible-pointer-types] print_matrix(array, matrix_z, matrix_l, matrix_i);
and
note: expected ‘char (*)[4]’ argument of type ‘char (*)[4][4]’ void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4])
and honest, don't these errors, because code seems work, i'm never out of boundaries , i'm not doing memory violations...
the warnings because these:
char * // pointer char or first element of char[] char (*)[4] // pointer char[4] or first element of char[][4] char (*)[4][4] // pointer char[4][4] or first element of char[][4][4]
are different types. pointer doesn't denote memory location, (via type) how memory location should interpreted.
one tricky bit array name (or other expression evaluates array) decays pointer. example, valid:
char abc[4] = "abc"; // abc array of 4 characters char = *abc; // 'a', first character of abc
. . . , conversely, can use array notation on pointer (to perform pointer arithmetic , dereference result):
char * abc = "abc"; // abc pointer (into static memory) char c = abc[2]; // c 'c', third character of abc
so char *
interconvertible char ()[]
, char (*)[4]
interconvertible char ()[][4]
, , char (*)[4][4]
interconvertible char ()[][4][4]
.
and makes extra tricky c doesn't quite support passing array function parameter (though if want that, can achieve same effect wrapping array in struct , passing that). let declare function parameter having array type, syntactic sugar function parameter pointer type. these 3 signatures equivalent:
void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4]) void *print_matrix(char m1[][4], char m2[][4], char m3[][4], char m4[][4]) void *print_matrix(char (*m1)[4], char (*m2)[4], char (*m3)[4], char (*m4)[4])
your code works because various warnings sort of cancel out:
rotate_matrix
should return eitherchar (*)[4]
(a pointer first row ofchar[][4]
) orchar (*)[4][4]
(a pointer completechar[4][4]
). instead, have returnchar *
, , accomplish that, dereference desired pointer, thereby getting (after array-to-pointer decay) pointer first element of first row of matrix. of course, of these pointers point same memory location, different types.- to declare return-type
char (*)[4]
, can writechar (*rotate_matrix(char m[4][4]))[4]
. . . it's better declarerow
type,typedef char row[4]
, , writerow * rotate_matrix(char m[4][4])
. in case returnm_r
@ end, decays pointer first row ofm_r
. - to declare return-type
char (*)[4][4]
, same thing,[4]
's (and namematrix
ratherrow
). in case return&m_r
@ end, meaning pointer entirety ofm_r
. - either of above approaches fine imho, though of course you'll have adjust calling sites match. rest of answer, i'm going assume we're doing second version, 1 return-type
char (*)[4][4]
.
- to declare return-type
array
has typechar (*)[4][4]
, fine. code warning inarray = rotate_matrix(matrix_t)
because of mis-declaration ofrotate_matrix
. actual value of returned pointer fine, @ least on typical platforms.- that said, if you're going use type
array
, should callarray_ptr
, since it's pointer usual array type.
- that said, if you're going use type
- but pass
array
argumentprint_matrix
, takes parameter of typechar [4][4]
, meaningchar (*)[4]
. can't convertchar (*)[4][4]
(pointer array of 4 rows of 4 chars)char (*)[4]
(pointer array of 4 chars). fix this, need dereferencearray
, passing*array
instead.
(note: i'm not sure of above implicit conversions guaranteed work; pointers different types of objects might not interconvertible on platforms. , on typical modern platforms, are interconvertible, might run afoul of strict aliasing rules, means compiler might end performing optimizations totally break code. usually work.)
Comments
Post a Comment