Thread: Understanding Pointers

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    41

    Understanding Pointers

    I'm creating a simple project to better understand pointers.

    I'm trying to scanf some values into an array from a function and then printing them ...
    but when i do, i get the correct words printed except for some symbols tact on to the end of the string... here is the code:

    Code:
    void get_colors(char scanned[][], int n); 
    
    int main(void){
     int n = 6, j, i;  
     char scanned[6][7];
     char color[12][7];
     char *pcolor;
     char *pscanned;
    
     /* Declare pointers to their arrays */
     pcolor = &color[0][0];
     pscanned = &scanned[0][0];
     
     get_colors(pscanned, n);
     
    for(j = 0; j<6; j++){
          for(i = 0; i<7; i++){
             printf("%c", scanned[j][i]);
             } printf("\n");
    }
    
     getch();
     return 0;   
    }
    
    void get_colors(char scanned[6][7], int n){
         printf("Please enter 6 resistor colors: \n");
         scanf("%s %s %s %s %s %s", &scanned[0], &scanned[1], &scanned[2], &scanned[3], &scanned[4], &scanned[5]) ;
    }
    but when i enter this for instance:
    brown green orange yellow black green

    the output looks like:
    brown
    green á <--- that ...?
    orange
    yellow
    black
    green

    and any useful tips to getting my head around pointers would be AMAZING! Pointers are going to be the death of me! lol...

    thanks in advance

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    In order for an array of characters to be considered a string (ie: to work with string functions or functions that assume you are passing a string), you need to nul terminate the array. That means that if you have "dog", you really have "dog\0", where \0 is the terminating nul character. Without that, C doesn't know where your string stops.

    You should also compile with warnings on, because pscanned is not the same as char [6][7] (what your function is expecting).


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    I thought c knows where to terminate a string based on the space in between the scanf ... thats how we have been using them all year.

    but how do i apply the \0 thing mentioned to a multiple input scanf like in the project above?

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    And as for the compile warning, I dont know what I did wrong with the different types. I'm just learning pointers. What is this error being produced from? and how do i fix it?

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by Oonej View Post
    And as for the compile warning, I dont know what I did wrong with the different types. I'm just learning pointers. What is this error being produced from? and how do i fix it?
    You're passing a "pointer to an array" to the function get_colors(). But the argument list of that function has an array declared (not a pointer to an array).

    I would recommend reading up on referencing an array with a pointer. It's not that difficult when you get the hang of it. Here's the gist (hope it's clear):

    Code:
    // this is not actual code, just my attempt to describe the relationship between
    //   an array index and a pointer to that array
    
    char ch_array[10];
    char *pointer_to_ch_array = &ch_array[0];
    
    //------
    
    *pointer_to_ch_array		// points to data at the address of the first element in the array
    //points to data in
    ch_array[0]
    
    *(pointer_to_ch_array + 1)	// points to data at the address of the second element in the array,
    //points to data in		//   which is the address of the first element PLUS 1
    ch_array[1]
    
    *(pointer_to_ch_array + 2)	// and so on.  Note how the dereference operator is being used
    //points to data in		//   around the modified address
    ch_array[2]
    There's a tad more math involved with more than one dimension in the array, but it's pretty much the same idea.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    $ gcc -Wall colors.c
    colors.c:3: error: array type has incomplete element type
    colors.c: In function ‘main’:
    colors.c:16: error: type of formal parameter 1 is incomplete
    colors.c:24: warning: implicit declaration of function ‘getch’
    colors.c: In function ‘get_colors’:
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[7]’
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘char (*)[7]’
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘char (*)[7]’
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘char (*)[7]’
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 6 has type ‘char (*)[7]’
    colors.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 7 has type ‘char (*)[7]’
    You have a few problems:
    1. Your prototype, like your declaration needs some sizes for the array. Technically, you can leave the leftmost [] empty, but you might as well make it match the function.
    2. You need to remove the & from each of the scanned[] elements in your scanf. scanned[0] is the name of the array starting at scanned[0][0], and the name of an array serves as a pointer to it in this case.
    3. You can ditch color, pcolor and pscanned since you don't need them. Just pass scanned directly to get_colors.
    4. You don't need or use n in get_colors, so drop it from the param list and the prototype.
    5. Now the big one. You're getting that junk because you print all 7 characters for each color, even if there's only 5 of them. If the color name has 5 letters, like brown, you have 'b', 'r', 'o', 'w', 'n', '\0' put in there by scanf. It doesn't fill the whole array with null characters, it only puts one at the end of what was entered. That leaves one junk character after the nul terminator that you print out. Just do printf("%s\n", scanned[i]) and you should be fine.
    6. Not a problem per se, but getch() isn't a standard function. Try using getchar() instead, so it's easier for people to paste your code into their editor and compile.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Matticus View Post
    You're passing a "pointer to an array" to the function get_colors(). But the argument list of that function has an array declared (not a pointer to an array).
    No. He's passing a pointer to a character. A pointer to an array would be:
    Code:
    type (*ptr)[X][Y];
    ptr is a pointer to an array of X by Y of type.

    pointer_to_ch_array is in fact a pointer to a character, not a pointer to an array of characters.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I stand corrected, thank you.

    - Matt

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by quzah View Post
    No. He's passing a pointer to a character. A pointer to an array would be:
    Code:
    type (*ptr)[X][Y];
    ptr is a pointer to an array of X by Y of type.

    pointer_to_ch_array is in fact a pointer to a character, not a pointer to an array of characters.


    Quzah.
    This is a confusing thing to say, because pointer_to_ch_array does indeed point to an array of characters.

    I'm not disagreeing with you about the C, but your english could do more to confuse than clarify.
    Last edited by King Mir; 06-17-2011 at 07:10 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    Made some of the recommended changes...

    also figured out a loop to replace random characters!

    Code:
    #include <stdio.h>
    
    void get_colors(char *pointer); 
    
    int main(void){
     int n = 6, j, i;  
     char scanned[6][7];
     char color[12][7];
     char *pcolor;
     char *pscanned;
    
     /* Declare pointers to their arrays */
     pcolor = &color[0][0];
     pscanned = &scanned[0][0];
     
     get_colors(pscanned);
     
    for(j = 0; j<6; j++){
          for(i = 0; i<7; i++){
             printf("%c", scanned[j][i]);
             } printf("\n");
    }
    
     getchar();
     return 0;   
    }
    
    void get_colors(char *pointer){
         int i, j, k;
         char x, y;
         int check;
         x = '\0';
         y = ' ';
         
         
         printf("Please enter 6 resistor colors: \n");
         scanf("%s %s %s %s %s %s", pointer, (pointer+7), (pointer+14), (pointer+21), (pointer+28), (pointer+35)) ;
         
         /* Replace characters after the first \0 with empty spaces */
            for(i = 0; i < 42; i++){
               if(*(pointer+i) == x) { 
                  for(j = i%7; j<7; j++){
                        k = 0;
                        *(pointer+i) = y;
                        i++; 
                  }
               }
       
         }
    }
    thoughts / opinions?

    i got rid of all the weird errors

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by King Mir View Post
    This is a confusing thing to say, because pointer_to_ch_array does indeed point to an array of characters.
    No it doesn't. It points to a single character. If that happens to be part of an array, that's fine, but it doesn't actually point to an array. It points to a single character:
    Code:
    type *foo;
    foo is a pointer to type.
    foo is not a pointer to an array off type.

    You can say that because given just a single pointer, you cannot tell how much memory it points to.
    Code:
    void foo( type *bar )
    {
        ...how much memory is bar pointed at? 
    }
    Did you pass it an array?
    Code:
    type bar[ 10 ];
    foo( bar );
    Or did you pass it a single character?
    Code:
    type bar;
    foo( &bar );
    In either case, bar in function foo is a pointer to a single type.


    Quzah.
    Last edited by quzah; 06-17-2011 at 06:36 PM.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Anyone writing foo would be aware of how much memory that foo is pointing to, and whether it points to an array or a single element.

    But Oonej's new code is ridiculous, and for precisely the reason that it voilates the convention of passing arrays as pointers correctly. If a pointer to type T is passed to a function, any reasonable person would expect that either it serves as pass by reference of a value of type T, or an array (or the middle of one) of type T. Passing a char pointer as what is logically a 2D array or chars is unconventional and therefore confusing.

    Here's a more reasonable version of that function:
    Code:
    void get_colors(char scanned[6][7], int n){/*alternatively:char (*scanned)[7]*/
         printf("Please enter 6 resistor colors: \n");
         scanf("%6s %6s %6s %6s %6s %6s", scanned, scanned+1, scanned+2, scanned+3, scanned+4, scanned+5) ;
    }
    
    //called as:
    char scanned[6][7];
    get_colors(scanned);
    Last edited by King Mir; 06-17-2011 at 07:13 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by King Mir View Post
    Anyone writing foo would be aware of how much memory that foo is pointing to, and whether it points to an array or a single element.
    Not necessarily so.

    The writers of strcat aren't aware of if I pass it a single nul character, and I'm free to do so, because a single nul character is safely considered a string.
    Code:
    char buf[BUFSIZ] = {0}, n = 0;
    strcat( buf, &n );
    Perfectly legal.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    Ok i'm starting to understand how to use pointers with multi-d arrays now how does this look?

    Code:
    void get_colors(char (*scanned)[7]);
    
    
    int main(void){
     int j, i;  
     char scanned[6][7];
     
     get_colors(scanned);
    
    for(j = 0; j<6; j++){
          for(i = 0; i<7; i++){
             printf("%c", scanned[j][i]);
             } printf("\n");
    }
    
     getch();
     return 0;   
    }
    
    /* Get colors from user */
    void get_colors(char (*scanned)[7]){
         int i, j, k;  
         
         printf("Please enter 6 resistor colors: \n");
         scanf("%6s %6s %6s %6s %6s %6s", scanned, scanned+1, scanned+2, scanned+3, scanned+4, scanned+5);
         
         /* Replace characters after the first \0 with empty spaces */
            for(j=0; j<6; j++){
               for(i=0; i<7; i++){ 
                 if(scanned[j][i] == '\0') { 
                   for(k = i; k<7; k++){
                        scanned[j][k] = ' ';
                   }
                 }
               }
            }
             
         /* Make all lower case letters */
         for(j=0; j<6; j++){
            for(i=0; i<7; i++){ 
               scanned[j][i] = tolower(scanned[j][i]); 
            }
         }
    }

  15. #15
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by Oonej View Post
    how does this look?
    It looks like quzah and King Mir are having some kind of code show-down.

    As far as your code; I'm sure we could all find something to nit-pick over, but the important thing is that you seem to have gotten it do to what you want. Take the knowledge you have gained and expand on it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with understanding file pointers
    By hanniballector in forum C Programming
    Replies: 9
    Last Post: 06-30-2010, 04:07 PM
  2. Help with understanding Pointers...
    By kiddo in forum C Programming
    Replies: 12
    Last Post: 03-07-2010, 06:43 PM
  3. understanding pointers
    By princez90 in forum C Programming
    Replies: 14
    Last Post: 04-19-2008, 09:56 AM
  4. Help understanding arrays and pointers
    By James00 in forum C Programming
    Replies: 2
    Last Post: 05-27-2003, 01:41 AM
  5. understanding pointers in my prog
    By Unregistered in forum C Programming
    Replies: 0
    Last Post: 03-22-2002, 12:04 PM