#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    2
    Rep Power
    0

    Use of pointers? Little problem!


    Hello! I'm a newbie of C programmation and I got some problems with pointers. Here is the function I tried to program:
    Code:
    void trans(int *matrans[], int n) {
    int i,k;
    int copied[n][n];
    for (i=0; i<n; i++, *((*matrans)++))
    	for (k=0; k<=2; copied[i.][k]=*matrans[k++]);
    
    for (i=0; i<n; i++, *((*matrans)++))
    	for (k=0; k<=2; *matrans[k]=copied[k++][i.]);
    }
    It should transpose a matrix nxn. First FOR iteration copies user's matrix into "copied"; second FOR iteration transposes user's matrix. The problem I get is during compiling and it's (I think) an error due to my inexperience! In paticular the error is Segmentation fault (core dumped) at line in which the program does
    Code:
     copied[i][k]=*matrans[k++]
    How may I fix this?

    Thank you so much! :D
    P.S. In the code I had to put a dot close to the "i" in brackets because without it they are taken as italic tags, obviously the mustn't be there!
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    I would suggest you write
    Code:
    	for (k=0; k<=2; k++ ) *matrans[k]=copied[k][i.];
    http://c-faq.com/expr/index.html

    In short, concentrating on writing simple code which is easy to follow.

    Trying to compress code into as few lines as possible by combining lots of side effects is a sure way of messing with your mind.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    What salem said. I migrated from Pascal, which was designed as a teaching tool for structured programming, to C, which was designed by programmers who didn't like to type to do what they wanted to do as tersely as possible. I knew that I had started thinking like a C programmer when I tried to write a for-loop that used embedded for-loops in both the initialization and increment expressions -- no, the compiler didn't let me do that, even though it made sense to me.

    You're not just writing in C for yourself, but also for others. If you try to compact too much into a statement, your code will be harder for others to understand, plus you are more likely to confuse yourself as well. It is far better to give for-loops code bodies rather than to put everything into the for-statement itself, and doing so will have very little effect on the resulting code, so there's no real savings in being more terse. And when you do write more tersely, you need to add more comments that explain just what it is that you are doing and to let those who will read that code later that you intended to write what you did (eg, there are uses for for-loops without bodies, but since added stray semicolons is a common error you need to explicitly comment that, yes, you really did intend to place that semicolon there), mainly to prevent others from "fixing" your code.

    Originally Posted by pietro_b
    P.S. In the code I had to put a dot close to the "i" in brackets because without it they are taken as italic tags, obviously the mustn't be there!
    That's a common problem. On another forum (though not a programming forum), its codes include a noparse tag that allows code tags to display and not be interpreted, but we don't have that here.

    What I do is to break the "tag" up by inserting a do-nothing tag pair. For example, to display copied[i][k] I insert open and close italic tags with nothing between them into the [i] array subscript -- for some odd reason I couldn't do that same with the pair of tags, so instead of being able to show you I had to describe it; maybe you can see it if you click on the Reply button.

    That way, someone can copy-and-paste the code from the message into their editor and it will still be ready to compile. Of course, I have to make sure to make a separate copy to doctor up that way so that I will still have my own code that I can compile.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    2
    Rep Power
    0
    Code:
    void trans(int *matrans[], int n) {
    int i,k;
    int copied[n][n]; /*This is the temporary Matrix with same dimensions of the user's Matrix */
    
    /*Initializing copied[n][n] with same values of *matrans[]*/
    
    for (i=0; i<n; i++, *((*matrans)++)) /*i represents the row, so this cycle make the i row index rise from the first to the last row; it make also the pointer(row)-to-pointer(column) point to the next row*/
                 {
    	for (k=0; k<n; k++) copied[i.][k]=*matrans[k]; /*We are on the i-th row and k-th column of matrans is copied into k-th column of copied[][]*/
    }
    
    for (i=0; i<n; i++, *((*matrans)++)) { /*Same of above*/
    	for (k=0; k<n; k++) *matrans[k]=copied[k][i.]; /*Here matrans's k-th column is changed into copied's k-th row, which is the definition of Matrix transposed*/
    }
    
    }
    I tried to clarify the code, which I admit was a bit cryptic. The problem actually comes when copied[i][k]=*matrans[k] is executed, so I guess it's a pointer syntax problem due to my inexperience!

    Replying to dwise_aol, I actually migrated to C from Pascal too when I just came to university, so I still sometimes have some progamming habits which are difficult to remove and don't fit well in C! And you're completely right when you say we're not programming for ourselves only, then I seize the day to apologise, I hope now you'll be able to understand better!
    P.S. I tried to fix the italic problem but your trick seems not work in the code :S
  8. #5
  9. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > for (i=0; i<n; i++, *((*matrans)++))
    I see you didn't appreciate the hint fully, and only changed half of the cryptic nonsense.

    The problem for you is you moved your matrans pointer in the first loop.
    So the second time you tried to do it, you were in the weeds.

    Code:
    #include <stdio.h>
    
    void trans(int *matrans[], int n) {
      int i,k;
      int copied[n][n]; 
    
      for (i=0; i<n; i++) {
        for (k=0; k<n; k++) copied[i][k]=matrans[i][k]; 
      }
      for (i=0; i<n; i++) {
        for (k=0; k<n; k++) matrans[i][k]=copied[k][i];
      }
    }
    
    int main ( ) {
      int m[3][3] = {
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 },
      };
      int *mat[3] = {
        m[0], m[1], m[2]
      };
      trans(mat,3);
    //  trans(m,3);
      return 0;
    }
    It also depends greatly on HOW you call it.

    Code:
    $ gcc foo.c
    foo.c: In function ‘main’:
    foo.c:25:3: warning: passing argument 1 of ‘trans’ from incompatible pointer type [enabled by default]
    foo.c:3:6: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
    If you're trying to pass in a true 2D array (and not an array of pointers), and ignoring the warning (but running anyway), then just stop. It just won't work.

    If you're new to C, then compile with maximum warnings (-Wall -Werror) and don't run code with warnings.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo