Thread: Transposing matrix

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    19

    Talking Transposing matrix

    Hi all,
    I'm learning C by myself and, as exercise, I was trying to make a program able to transpose a matrix[a][b] to matrix[b][a]. I can't really understand what's wrong and sadly this exercise has no solution posted on the net that i could check. It compiles fine on Pelles C, but the displayed result is a bit strange.
    Code:
    #include <stdio.h>
    
    void displayMatrix (int x, int y, int M3[x][y])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= x; ++a) {
    		for ( b = 0; b <= y; ++b)
    			printf("&#37;5i", M3[a][b]);
    	printf("\n");
    	}
    }
    
    void transposeMatrix (int x, int y, int M1[x][y], int w, int z,int M2[w][z])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= x; ++a) {
    		for ( b = 0; b <= y; ++b)
    			M2[b][a] = M1[a][b];
    	}
    }
    
    
    int main (void)
    {
    	void transposeMatrix (int x, int y, int M1[x][y], int w, int z,int M2[w][z]);
    	void displayMatrix (int x, int y, int M3[x][y]);
    	
    	int Matrix2[5][4];
    
    	int Matrix1[4][5] = 
    	{ 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }
    	};
    
    	displayMatrix(4, 5, Matrix1);  //test display function -- seems to work yahoo..
    
    	printf("\n\n-----------------------------------\n\nTransposed matrix:\n\n");  // some space
    
    	transposeMatrix(4, 5, Matrix1, 5, 4, Matrix2);
    
    	displayMatrix(5, 4, Matrix2);
    
    	return 0;
    }
    I used void as return value for transposeMatrix cause I guess matrix behave like arrays, the matrix gets directly modified by the function? no need to return in theory? (even it might be good practice) Sorry for the maybe silly question but i just arrived to multi dimensional arrays and i can't quite figure it out myself.
    Thanks in advance.
    Last edited by 2112; 02-08-2008 at 08:25 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you don't have to (and it's probably meaningless to) return anything from transposeMatrix.


    However, I'd like to point out: The C language doesn't normally allow variable size arrays, so
    Code:
    void transposeMatrix (int x, int y, int M1[x][y], int w, int z,int M2[w][z])
    wouldn't be valid in all compilers - not sure if it is in ANY compiler, really, since even newer compilers expect y and z to be constants [x and w are not even needed in the parameter declaration].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Feb 2008
    Posts
    19
    Thanks for the answer Mats.
    Although if i use normal declaration not only i get funny results but i get "application error" and this is a first for me eheheh. I dont know there's still something wrong I cannot see. Still looking into it. I wonder if that a = 0 must be a = 1 but it doesn't sem to work either...
    Code:
    #include <stdio.h>
    
    void displayMatrix (int M3[5][4])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= 5; ++a) {
    		for ( b = 0; b <= 4; ++b)
    			printf("%5i", M3[a][b]);
    	printf("\n");
    	}
    }
    
    void transposeMatrix (int M1[4][5], int M2[5][4])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= 4; ++a) {
    		for ( b = 0; b <= 5; ++b)
    			M2[b][a] = M1[a][b];
    	}
    }
    
    
    int main (void)
    {
    	void transposeMatrix (int M1[4][5], int M2[5][4]);
    	void displayMatrix (int M3[5][4]);
    	
    	int Matrix2[5][4];
    
    	int Matrix1[4][5] = 
    	{ 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }
    	};
    
    	// displayMatrix(Matrix1);  //test display function -- seems to work yahoo..
    
    	printf("\n\n-----------------------------------\n\nTransposed matrix:\n\n");  // some space
    
    	transposeMatrix(Matrix1, Matrix2);
    
    	displayMatrix(Matrix2);
    
    	return 0;
    }

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    	for ( a = 0; a <= 4; ++a) {
    		for ( b = 0; b <= 5; ++b)
    			M2[b][a] = M1[a][b];
    	}
    You are copying one cell too many in each direction, since you use a <= 4 and b <= 5. Cells are 0..3 when you have array[4], and 0..4 if you use array[5] - you are setting cells 0..4 and 0..5 respectively.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Posts
    19
    Ah damn how could I forget that, that's a basic of arrays...whoops it's that i studied arrays and functions all in a few days and I have yet to get used to it. Thanks!

  6. #6
    Registered User
    Join Date
    Feb 2008
    Posts
    19
    On a side note, with that corrected, it seems to work also using variable length arrays:
    Code:
    #include <stdio.h>
    
    void displayMatrix (int x, int y, int M3[x][y])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= x; ++a) {
    		for ( b = 0; b <= y; ++b)
    			printf("&#37;5i", M3[a][b]);
    	printf("\n");
    	}
    }
    
    void transposeMatrix (int x, int y, int M1[x][y], int w, int z,int M2[w][z])
    {
    	int a = 0, b = 0;
    
    	for ( a = 0; a <= x; ++a) {
    		for ( b = 0; b <= y; ++b)
    			M2[b][a] = M1[a][b];
    	}
    }
    
    
    int main (void)
    {
    	void transposeMatrix (int x, int y, int M1[x][y], int w, int z,int M2[w][z]);
    	void displayMatrix (int x, int y, int M3[x][y]);
    	
    	int Matrix2[5][4];
    
    	int Matrix1[4][5] = 
    	{ 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }, 
    		{ 1, 2 , 3, 4, 5 }
    	};
    
    	displayMatrix(4, 5, Matrix1);  //test display function -- seems to work yahoo..
    
    	printf("\n\n-----------------------------------\n\nTransposed matrix:\n\n");  // some space
    
    	transposeMatrix(4, 5, Matrix1, 5, 4, Matrix2);
    
    	displayMatrix(5, 4, Matrix2);
    
    	return 0;
    }
    compiles on Pelles C but not on GCC stable, maybe using the candidate package dont know
    Last edited by 2112; 02-08-2008 at 09:16 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sure, if you want to lock yourself into gcc, then fine.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Feb 2008
    Posts
    19
    locked in GCC? not really

    In GCC i get "internal compiler error: in put_pending_sizes, at stor-layout.c:140"
    Well that surely doesn't make me wanna swap from Pelles to GCC...although in newer version it's probably fixed. The stable is pretty old by now.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What I mean is that you are locked into some particular compiler versions that allow this construct. Many compilers won't.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Feb 2008
    Posts
    19
    ahhh yea but it's fine for now, i'm only learning so i need also to test out features like variable size arrays,
    When i will make my first real project, then ill take that into account for sure

  11. #11
    Registered User
    Join Date
    Feb 2008
    Location
    USA, Oklahoma
    Posts
    2
    I'm stunned that the code works at all. If you understand how multidimensional arrays actually work (and that can be a pretty confusing subject), then you understand why, when passing an array to a function, only the first index can be left blank; all the others must be populated with constants.

    Multidimensional arrays are actually stored in contiguous memory as though it was a single-dimensional array. The compiler must know the size of all the last dimensions in order to locate the element you are referencing.

    I long ago quit using multidimensional arrays, and instead went to macros that emulate the same behavior, but are more "dynamic".

    Code:
    void matrixprocess( double* matrix, size_t numrows, size_t numcols )
    {
       #define M(i,j) (matrix[(i)*numcols + (j)])
    /*Note that i and j are zero-based indices, not like in Fortran. */
    ...
       #undef M
    }
    This code works regardless of the number of columns and rows.

    DQNOK
    Last edited by DQNOK; 02-08-2008 at 05:27 PM. Reason: grammatical error

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In C, you can only leave the first index blank; all the last dimensions must be specified. Your macro at least gets it right.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, it's the FIRST dimension that can be left out (and is not checked by the compiler anyways). All other dimensions need to be passed.

    Apparently the compiler used in this case can cope with variable size arrays, and that should work both with passed arguments and local variables. But this is, as far as I know, an extension on top of C99.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Apparently the compiler used in this case can cope with variable size arrays, and that should work both with passed arguments and local variables. But this is, as far as I know, an extension on top of C99.
    I had the impression that variable length arrays were a feature, not extension, of C99.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by laserlight View Post
    I had the impression that variable length arrays were a feature, not extension, of C99.
    Yes, but only with constant values, no?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C - access violation
    By uber in forum C Programming
    Replies: 2
    Last Post: 07-08-2009, 01:30 PM
  2. Matrix Help
    By HelpmeMark in forum C++ Programming
    Replies: 27
    Last Post: 03-06-2008, 05:57 PM
  3. Matrix and vector operations on computers
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 05-11-2004, 06:36 AM
  4. Matrix Reloaded Questions (SPOILERS_
    By Xei in forum A Brief History of Cprogramming.com
    Replies: 73
    Last Post: 10-19-2003, 02:21 PM