Thread: About arrays and strings

  1. #1
    Registered User
    Join Date
    Feb 2016
    Posts
    20

    About arrays and strings

    Arrays in C - Cprogramming.com
    Let's look at something new here: the scanf function call is a tad different from what we've seen before. First of all, the format string is '%s' instead of '%d'; this just tells scanf to read in a string instead of an integer. Second, we don't use the ampersand! It turns out that when we pass arrays into functions, the compiler automatically converts the array into a pointer to the first element of the array. In short, the array without any brackets will act like a pointer. So we just pass the array directly into scanf without using the ampersand and it works perfectly.
    I tried this with integers instead of string to try understanding what's happening internally.

    Code:
    #include <stdio.h>
    
    
    int main( int argc, char *argv[] )  {
    	
    	int scores[3] = {0,0,0};
    	
    	printf("\n\nYour scores: ");
    	scanf("%d %d %d", scores, scores, scores);
    	
    	printf("Your scores are: %d %d %d\n\n", scores[0], scores[1], scores[2]);
    	
    	return 0;
    }
    Output:
    Your scores: 11 14 20
    Your scores are: 20 0 0
    Code:
    printf("Your scores are: %d %d %d\n\n", scores[0], scores[1], scores[2]);
    If I remove the brackets [], I get addresses! So, I use "dereferencing" (*) and the output is suddenly 20 20 20.

  2. #2
    Registered User camel-man's Avatar
    Join Date
    Jan 2011
    Location
    Under the moon
    Posts
    693
    scores in your scanf is the same thing as saying &scores[0].

    The name of an array is just the address to the first element. So when you enter in your numbers you are overriding the first element 3 times. Leaving the first element = to what the last number you entered in at.
    Code:
    int get_random_number(void)
    {
       return 4; //chosen by fair dice roll.
                 //guaranteed to be random
    }

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You might want to tweak it a bit to:
    Code:
    scanf("%d %d %d", scores, scores + 1, scores + 2);
    Besides, it will actually be more useful this way

    Also, remember to check the return value of scanf before proceeding to use what was read by scanf.

    Quote Originally Posted by camel-man
    The name of an array is just the address to the first element.
    I don't like this way of putting it as it is easily shown to be false when considering &scores and sizeof(scores).
    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

  4. #4
    Registered User
    Join Date
    Feb 2016
    Posts
    20
    Quote Originally Posted by camel-man View Post
    scores in your scanf is the same thing as saying &scores[0].

    The name of an array is just the address to the first element. So when you enter in your numbers you are overriding the first element 3 times. Leaving the first element = to what the last number you entered in at.
    I know that and Alex explained that as well:
    Arrays in C - Cprogramming.com
    compiler automatically converts the array into a pointer to the first element of the array
    But my question is beyond that whereby I'm trying to understand how it works when using different things such as plaint scores, &scores, scores[x], &scores[x], *scores and also ptr->scores if I use pointer to a struct. I see the compiler uses different logics when handling an array like the differences between char str[3] and int i[3].

  5. #5
    Registered User
    Join Date
    Feb 2016
    Posts
    20
    Quote Originally Posted by laserlight View Post
    You might want to tweak it a bit to:
    Code:
    scanf("%d %d %d", scores, scores + 1, scores + 2);
    Besides, it will actually be more useful this way
    and then use *scores, *(scores+1), *(scores+2) to print it. cool!

    now I think the magic resides in the %s, and %c should be the same as %d.

    if we pass %s to read and write functions, these functions make use of auto increment while != null character.

    Also, remember to check the return value of scanf before proceeding to use what was read by scanf.
    I know :

    /* Using scanf isn't really the best way to do this; we'll talk about that
    in the next tutorial, on strings */

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by yvan View Post
    I see the compiler uses different logics when handling an array like the differences between char str[3] and int i[3].
    There is no difference between char str[3] and int i[3], besides the type of the elements. The syntax and semantics are identical for both.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by yvan
    But my question is beyond that whereby I'm trying to understand how it works when using different things such as plaint scores, &scores, scores[x], &scores[x], *scores and also ptr->scores if I use pointer to a struct. I see the compiler uses different logics when handling an array like the differences between char str[3] and int i[3].
    Since scores is an array of 3 ints, &scores is a pointer to an array of 3 ints, i.e., int(*)[3]. Along with sizeof(scores) and assignment (i.e., you cannot assign to an array, whereas you can assign to a non-const lvalue pointer), that is the key difference between saying that scores is an array of int and saying that scores is a pointer to int. Besides these, you can generally gloss over whether scores is an array or scores is a pointer and it would not matter since scores would be converted to a pointer to its first element. Hence, the standard actually defines scores[x] as *(scores + x), hence you can technically write x[scores] and it will be syntactically valid, though bad practice.

    Quote Originally Posted by yvan
    and then use *scores, *(scores+1), *(scores+2) to print it. cool!
    No, don't do that. Generally, scores[i] should be preferred to *(scores + i) because it tends to be more readable. *scores by itself is fine, so what happens is that you might iterate over the array using a pointer:
    Code:
    int *p;
    for (p = scores; p != scores + 3; p++)
    {
        printf("%d ", *p);
    }
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with strings and arrays
    By Le23ron in forum C Programming
    Replies: 8
    Last Post: 02-15-2012, 05:10 AM
  2. Strings in arrays
    By hellogamesmaste in forum C Programming
    Replies: 1
    Last Post: 08-13-2009, 09:15 AM
  3. Replies: 2
    Last Post: 02-23-2004, 06:34 AM
  4. Arrays of Strings are fun
    By kippwinger in forum C++ Programming
    Replies: 9
    Last Post: 07-02-2003, 04:12 PM
  5. Strings And Arrays
    By helbovine in forum C++ Programming
    Replies: 2
    Last Post: 02-10-2002, 03:06 PM