Garbage produced

Discussion in 'C Programming' started by Vikram, Jan 24, 2011.

  1. Vikram

    Vikram Guest

    Hello friends

    the code below will find the mean (average) of some numbers, however it
    produces only garbage. Can you see a problem?

    Kind Regards,
    Vikram


    float mean(int x[])
    {
    int i,n;
    float sum;
    n=sizeof(x);
    for(i=sum=0;i<n;sum+=x[i++]);
    return sum/n;
    }

    main()
    {
    int* x,n;
    printf("how many numbers? ");
    scanf("%d",&n);
    x=malloc(n*sizeof(int));
    printf("enter %d numbers\n",n);
    while(n--)scanf("%d",x+n);
    printf("mean=%f\n",mean(x));
    }
     
    Vikram, Jan 24, 2011
    #1
    1. Advertising

  2. Vikram

    Ian Collins Guest

    On 01/25/11 09:50 AM, Vikram wrote:
    > Hello friends
    >
    > the code below will find the mean (average) of some numbers, however it
    > produces only garbage. Can you see a problem?
    >
    > Kind Regards,
    > Vikram
    >
    >
    > float mean(int x[])
    > {
    > int i,n;
    > float sum;
    > n=sizeof(x);


    This won't do what you expect (it will give you the size of an int*),
    you have to pass in the size.

    --
    Ian Collins
     
    Ian Collins, Jan 24, 2011
    #2
    1. Advertising

  3. Vikram

    Bartc Guest

    Fred wrote:

    > There is a second problem with the code not related to array vs.
    > pointer.
    >
    > for(i=sum=0;i<n;sum+=x[i++]);
    > return sum/n;
    >
    > The above is not a safe way to find the mean of a set of floats.
    > Consider:
    > x[0] = FLT_MAX;
    > x[1] = FLT_MAX / 2.;
    > What is the mean, and what would the above code return?


    Are values near FLT_MAX really likely? If so, then it makes it pretty much
    impossible to do any sort of floating point arithmetic.

    A typical value of FLT_MAX is some 10**38. If values are limited to, say, a
    billion billion billion (which should cover a lot of applications unless
    silly units are being used), you need to add 10 billion such maximums before
    you get overflow.

    And that assumes you can't use double for some reason, if the numbers are
    going to be big, which typically has a maximum of 10**300 or so.

    Anyway, how *would* you calculate the average of lots of numbers near to
    FLT_MAX?

    --
    Bartc
     
    Bartc, Jan 24, 2011
    #3
  4. Vikram

    Vikram Guest

    Ian Collins writes:

    > On 01/25/11 09:50 AM, Vikram wrote:
    >> Hello friends
    >>
    >> the code below will find the mean (average) of some numbers, however it
    >> produces only garbage. Can you see a problem?
    >>
    >> Kind Regards,
    >> Vikram
    >>
    >>
    >> float mean(int x[])


    ^^^^^^^

    NB in this function I am considering the pointer, as an array.

    >> {
    >> int i,n;
    >> float sum;
    >> n=sizeof(x);

    >
    > This won't do what you expect (it will give you the size of an int*),
    > you have to pass in the size.


    Kind Regards,
    Vikram
     
    Vikram, Jan 24, 2011
    #4
  5. On Jan 24, 4:20 pm, Vikram <> wrote:
    > Ian Collins writes:
    > > On 01/25/11 09:50 AM, Vikram wrote:
    > >> Hello friends

    >
    > >> the code below will find the mean (average) of some numbers, however it
    > >> produces only garbage. Can you see a problem?

    >
    > >> Kind Regards,
    > >> Vikram

    >
    > >> float mean(int x[])

    >
    >               ^^^^^^^
    >
    > NB in this function I am considering the pointer, as an array.
    >
    > >> {
    > >>    int i,n;
    > >>    float sum;
    > >>    n=sizeof(x);

    >
    > > This won't do what you expect (it will give you the size of an int*),
    > > you have to pass in the size.

    >


    Try as an experiment doing a printf of the result of sizeof the
    argument, and you will discover Ian is correct...

    -David
     
    David Resnick, Jan 24, 2011
    #5
  6. Vikram

    Willem Guest

    Vikram wrote:
    ) the code below will find the mean (average) of some numbers, however it
    ) produces only garbage. Can you see a problem?
    )
    ) float mean(int x[])
    ) {
    ) int i,n;
    ) float sum;
    ) n=sizeof(x);
    ) for(i=sum=0;i<n;sum+=x[i++]);
    ) return sum/n;
    ) }

    That's not how arrays work in C. They don't know how big they are.
    sizeof() is not meant to find out the number of elements in an array.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Jan 24, 2011
    #6
  7. Vikram

    Bartc Guest

    Keith Thompson wrote:
    > "Bartc" <> writes:
    >> Fred wrote:


    >>> for(i=sum=0;i<n;sum+=x[i++]);
    >>> return sum/n;
    >>>
    >>> The above is not a safe way to find the mean of a set of floats.
    >>> Consider:
    >>> x[0] = FLT_MAX;
    >>> x[1] = FLT_MAX / 2.;
    >>> What is the mean, and what would the above code return?

    >>
    >> Are values near FLT_MAX really likely? If so, then it makes it
    >> pretty much impossible to do any sort of floating point arithmetic.


    >> Anyway, how *would* you calculate the average of lots of numbers
    >> near to FLT_MAX?

    >
    > One solution is to divide *each* number by n, them sum the quotients.


    Doesn't that just move the problem elsewhere? Suppose the numbers are near
    FLT_MIN?

    And isn't this likely to lose accuracy (it would do with integers)?

    --
    Bartc
     
    Bartc, Jan 24, 2011
    #7
  8. Vikram

    Willem Guest

    Vikram wrote:
    )>> float mean(int x[])
    )
    ) ^^^^^^^
    )
    ) NB in this function I am considering the pointer, as an array.

    You're not. You only think you are. That's not how C works.
    In C, the above is exactly 100% equivalent to
    float mean(int *x)

    HTH, HAND.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Jan 24, 2011
    #8
  9. Vikram wrote:
    > Ian Collins writes:
    >
    >> On 01/25/11 09:50 AM, Vikram wrote:
    >>> Hello friends
    >>>
    >>> the code below will find the mean (average) of some numbers, however it
    >>> produces only garbage. Can you see a problem?
    >>>
    >>> Kind Regards,
    >>> Vikram
    >>>
    >>>
    >>> float mean(int x[])

    >
    > ^^^^^^^
    >
    > NB in this function I am considering the pointer, as an array.


    Regardless of how you like to think about it, when you pass
    an array to a function in C, the function receives a pointer to
    the first element of the array. That's just the way passing an array
    works in C. If you take sizeof() the parameter, you'll just get the
    size of the pointer, which is nothing to do with the size of the array.
    There is no sensible way for the function to know the size
    of the array it's been passed, unless you tell it:

    float mean(int *x, int count)
    {
    int i;
    float sum = 0.0;
    for(i = 0; i < count; sum += x[i++])
    ;
    return sum/count;
    }

    main()
    {
    int* x,n;
    int count = 0;
    printf("how many numbers? ");
    scanf("%d",&n);
    count = n;
    x=malloc(n*sizeof(int));
    printf("enter %d numbers\n",n);
    while(n--)
    scanf("%d",x+n);
    printf("mean=%f\n",mean(x, count));
    }

    (untested code, no warranty &c)
    James
     
    James Lothian, Jan 24, 2011
    #9
  10. Vikram

    Paul N Guest

    On Jan 24, 9:28 pm, Willem <> wrote:
    > Vikram wrote:
    >
    > ) the code below will find the mean (average) of some numbers, however it
    > ) produces only garbage. Can you see a problem?
    > )
    > ) float mean(int x[])
    > ) {
    > )   int i,n;
    > )   float sum;
    > )   n=sizeof(x);
    > )   for(i=sum=0;i<n;sum+=x[i++]);
    > )   return sum/n;
    > ) }
    >
    > That's not how arrays work in C.  They don't know how big they are.
    > sizeof() is not meant to find out the number of elements in an array.


    I beg to differ. sizeof can be used to find the number of elements in
    an array. The reasons it's not working here are:

    a) The x in main isn't an array, it's a pointer set using malloc;
    b) Even if it was, it gets turned into a pointer when you pass it to a
    function, so the x in mean is a pointer, and would be even if the x in
    main was an array;
    c) If x was an array of int, you would need to divide sizeof(x) by
    sizeof(int) to get the number of elements.

    Hope this is of use to someone.
    Paul.
     
    Paul N, Jan 24, 2011
    #10
  11. Vikram

    Fred Guest

    On Jan 24, 2:05 pm, Paul N <> wrote:
    > On Jan 24, 9:28 pm, Willem <> wrote:
    >
    >
    >
    >
    >
    > > Vikram wrote:

    >
    > > ) the code below will find the mean (average) of some numbers, however it
    > > ) produces only garbage. Can you see a problem?
    > > )
    > > ) float mean(int x[])
    > > ) {
    > > )   int i,n;
    > > )   float sum;
    > > )   n=sizeof(x);
    > > )   for(i=sum=0;i<n;sum+=x[i++]);
    > > )   return sum/n;
    > > ) }

    >
    > > That's not how arrays work in C.  They don't know how big they are.
    > > sizeof() is not meant to find out the number of elements in an array.

    >
    > I beg to differ. sizeof can be used to find the number of elements in
    > an array. The reasons it's not working here are:
    >
    > a) The x in main isn't an array, it's a pointer set using malloc;
    > b) Even if it was, it gets turned into a pointer when you pass it to a
    > function, so the x in mean is a pointer, and would be even if the x in
    > main was an array;
    > c) If x was an array of int, you would need to divide sizeof(x) by
    > sizeof(int) to get the number of elements.
    >


    There is a second problem with the code not related to array vs.
    pointer.

    for(i=sum=0;i<n;sum+=x[i++]);
    return sum/n;

    The above is not a safe way to find the mean of a set of floats.
    Consider:
    x[0] = FLT_MAX;
    x[1] = FLT_MAX / 2.;
    What is the mean, and what would the above code return?
    --
    Fred K
     
    Fred, Jan 24, 2011
    #11
  12. Vikram <> writes:
    > Ian Collins writes:
    >> On 01/25/11 09:50 AM, Vikram wrote:
    >>> Hello friends
    >>>
    >>> the code below will find the mean (average) of some numbers, however it
    >>> produces only garbage. Can you see a problem?
    >>>
    >>> Kind Regards,
    >>> Vikram
    >>>
    >>>
    >>> float mean(int x[])

    >
    > ^^^^^^^
    >
    > NB in this function I am considering the pointer, as an array.

    [...]

    Read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 24, 2011
    #12
  13. Vikram

    Dann Corbit Guest

    In article <6317e052-c51c-4d7a-88ee-dfce5b2b23d0
    @q8g2000prm.googlegroups.com>, says...
    >
    > On Jan 24, 2:05 pm, Paul N <> wrote:
    > > On Jan 24, 9:28 pm, Willem <> wrote:
    > >
    > >
    > >
    > >
    > >
    > > > Vikram wrote:

    > >
    > > > ) the code below will find the mean (average) of some numbers, however it
    > > > ) produces only garbage. Can you see a problem?
    > > > )
    > > > ) float mean(int x[])
    > > > ) {
    > > > )   int i,n;
    > > > )   float sum;
    > > > )   n=sizeof(x);
    > > > )   for(i=sum=0;i<n;sum+=x[i++]);
    > > > )   return sum/n;
    > > > ) }

    > >
    > > > That's not how arrays work in C.  They don't know how big they are.
    > > > sizeof() is not meant to find out the number of elements in an array.

    > >
    > > I beg to differ. sizeof can be used to find the number of elements in
    > > an array. The reasons it's not working here are:
    > >
    > > a) The x in main isn't an array, it's a pointer set using malloc;
    > > b) Even if it was, it gets turned into a pointer when you pass it to a
    > > function, so the x in mean is a pointer, and would be even if the x in
    > > main was an array;
    > > c) If x was an array of int, you would need to divide sizeof(x) by
    > > sizeof(int) to get the number of elements.
    > >

    >
    > There is a second problem with the code not related to array vs.
    > pointer.
    >
    > for(i=sum=0;i<n;sum+=x[i++]);
    > return sum/n;
    >
    > The above is not a safe way to find the mean of a set of floats.
    > Consider:
    > x[0] = FLT_MAX;
    > x[1] = FLT_MAX / 2.;
    > What is the mean, and what would the above code return?


    That is easily repaired by making sum a double (assuming that double is
    larger than float).

    Welford's accumulation and/or Kahan's accumulation could also prove
    useful.

    His biggest issue is failure to read c-faq section 6. For instance:

    6.21:Why doesn't sizeof properly report the size of an array when the
    array is a parameter to a function?

    A: The compiler pretends that the array parameter was declared as a
    pointer (see question 6.4), and sizeof reports the size of the
    pointer.

    References: H&S Sec. 7.5.2 p. 195.
     
    Dann Corbit, Jan 24, 2011
    #13
  14. "Bartc" <> writes:
    > Fred wrote:
    >> There is a second problem with the code not related to array vs.
    >> pointer.
    >>
    >> for(i=sum=0;i<n;sum+=x[i++]);
    >> return sum/n;
    >>
    >> The above is not a safe way to find the mean of a set of floats.
    >> Consider:
    >> x[0] = FLT_MAX;
    >> x[1] = FLT_MAX / 2.;
    >> What is the mean, and what would the above code return?

    >
    > Are values near FLT_MAX really likely? If so, then it makes it pretty much
    > impossible to do any sort of floating point arithmetic.
    >
    > A typical value of FLT_MAX is some 10**38. If values are limited to, say, a
    > billion billion billion (which should cover a lot of applications unless
    > silly units are being used), you need to add 10 billion such maximums before
    > you get overflow.
    >
    > And that assumes you can't use double for some reason, if the numbers are
    > going to be big, which typically has a maximum of 10**300 or so.
    >
    > Anyway, how *would* you calculate the average of lots of numbers near to
    > FLT_MAX?


    One solution is to divide *each* number by n, them sum the quotients.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 25, 2011
    #14
  15. "Bartc" <> writes:
    > Keith Thompson wrote:
    >> "Bartc" <> writes:
    >>> Fred wrote:

    >
    >>>> for(i=sum=0;i<n;sum+=x[i++]);
    >>>> return sum/n;
    >>>>
    >>>> The above is not a safe way to find the mean of a set of floats.
    >>>> Consider:
    >>>> x[0] = FLT_MAX;
    >>>> x[1] = FLT_MAX / 2.;
    >>>> What is the mean, and what would the above code return?
    >>>
    >>> Are values near FLT_MAX really likely? If so, then it makes it
    >>> pretty much impossible to do any sort of floating point arithmetic.

    >
    >>> Anyway, how *would* you calculate the average of lots of numbers
    >>> near to FLT_MAX?

    >>
    >> One solution is to divide *each* number by n, them sum the quotients.

    >
    > Doesn't that just move the problem elsewhere? Suppose the numbers are near
    > FLT_MIN?


    If only some of them are near FLT_MIN (or -FLT_MIN), there's no problem.
    If all of them are, then yes, you could lose information (though it
    won't overflow).

    > And isn't this likely to lose accuracy (it would do with integers)?


    Barring very small numbers, I don't think so.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 25, 2011
    #15
  16. Vikram

    Vikram Guest

    James Lothian writes:
    > Vikram wrote:
    >> Ian Collins writes:
    >>
    >>> On 01/25/11 09:50 AM, Vikram wrote:
    >>>> Hello friends
    >>>>
    >>>> the code below will find the mean (average) of some numbers, however
    >>>> it produces only garbage. Can you see a problem?
    >>>>
    >>>> Kind Regards,
    >>>> Vikram
    >>>>
    >>>>
    >>>> float mean(int x[])

    >>
    >> ^^^^^^^
    >>
    >> NB in this function I am considering the pointer, as an array.

    >
    > Regardless of how you like to think about it, when you pass an array to
    > a function in C, the function receives a pointer to the first element of
    > the array. That's just the way passing an array works in C. If you take
    > sizeof() the parameter, you'll just get the size of the pointer, which
    > is nothing to do with the size of the array.


    Hello James

    I think you are wrong about this. I have been doing some tests and what I
    discovered is my library's sizeof() function is buggy! For some reason it
    miscalculates all sizes by a multiple of 4. It's easy to correct this,
    see the code below

    #define sizeof(x) (sizeof(x)/4)
    main()
    {
    int a1[1];
    int a2[5];
    int a3[20];
    printf("1=%d\n5=%d\n20=%d\n",sizeof(a1),sizeof(a2),sizeof(a3));
    return(0);
    }

    This now successfully produces:
    1=1
    5=5
    20=20

    Kind Regards,
    Vikram
     
    Vikram, Jan 25, 2011
    #16
  17. Vikram

    Dann Corbit Guest

    In article <ihn8i3$tqj$>, lid
    says...
    >
    > James Lothian writes:
    > > Vikram wrote:
    > >> Ian Collins writes:
    > >>
    > >>> On 01/25/11 09:50 AM, Vikram wrote:
    > >>>> Hello friends
    > >>>>
    > >>>> the code below will find the mean (average) of some numbers, however
    > >>>> it produces only garbage. Can you see a problem?
    > >>>>
    > >>>> Kind Regards,
    > >>>> Vikram
    > >>>>
    > >>>>
    > >>>> float mean(int x[])
    > >>
    > >> ^^^^^^^
    > >>
    > >> NB in this function I am considering the pointer, as an array.

    > >
    > > Regardless of how you like to think about it, when you pass an array to
    > > a function in C, the function receives a pointer to the first element of
    > > the array. That's just the way passing an array works in C. If you take
    > > sizeof() the parameter, you'll just get the size of the pointer, which
    > > is nothing to do with the size of the array.

    >
    > Hello James
    >
    > I think you are wrong about this.


    He is not wrong. You are failing to understand what he told you.

    > I have been doing some tests and what I
    > discovered is my library's sizeof() function is buggy!


    It is your understanding that is buggy.

    > For some reason it
    > miscalculates all sizes by a multiple of 4. It's easy to correct this,
    > see the code below


    Surely, you are a troll.

    > #define sizeof(x) (sizeof(x)/4)
    > main()
    > {
    > int a1[1];
    > int a2[5];
    > int a3[20];
    > printf("1=%d\n5=%d\n20=%d\n",sizeof(a1),sizeof(a2),sizeof(a3));
    > return(0);
    > }
    >
    > This now successfully produces:
    > 1=1
    > 5=5
    > 20=20
    >
    > Kind Regards,


    C:\tmp>type t.c
    #include <stdio.h>

    int main(void)
    {
    int a1[1];
    int a2[5];
    int a3[20];
    printf("1=%d\n5=%d\n20=%d\n", sizeof a1 / sizeof a1[0], sizeof a2 /
    sizeof a2[0], sizeof a3 / sizeof a3[0]);
    printf("1=%d\n5=%d\n20=%d\n", sizeof a1 / sizeof(int), sizeof a2 /
    sizeof(int), sizeof a3 / sizeof(int));

    return 0;
    }

    C:\tmp>cl t.c
    Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    t.c
    Microsoft (R) Incremental Linker Version 10.00.30319.01
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:t.exe
    t.obj

    C:\tmp>t
    1=1
    5=5
    20=20
    1=1
    5=5
    20=20
     
    Dann Corbit, Jan 25, 2011
    #17
  18. Vikram

    Hans Vlems Guest

    On 25 jan, 20:33, Vikram <> wrote:
    > James Lothian writes:
    > > Vikram wrote:
    > >> Ian Collins writes:

    >
    > >>> On 01/25/11 09:50 AM, Vikram wrote:
    > >>>> Hello friends

    >
    > >>>> the code below will find the mean (average) of some numbers, however
    > >>>> it produces only garbage. Can you see a problem?

    >
    > >>>> Kind Regards,
    > >>>> Vikram

    >
    > >>>> float mean(int x[])

    >
    > >>                ^^^^^^^

    >
    > >> NB in this function I am considering the pointer, as an array.

    >
    > > Regardless of how you like to think about it, when you pass an array to
    > > a function in C, the function receives a pointer to the first element of
    > > the array. That's just the way passing an array works in C. If you take
    > > sizeof() the parameter, you'll just get the size of the pointer, which
    > > is nothing to do with the size of the array.

    >
    > Hello James
    >
    > I think you are wrong about this. I have been doing some tests and what I
    > discovered is my library's sizeof() function is buggy! For some reason it
    > miscalculates all sizes by a multiple of 4. It's easy to correct this,
    > see the code below
    >
    > #define sizeof(x) (sizeof(x)/4)
    > main()
    > {
    >   int a1[1];
    >   int a2[5];
    >   int a3[20];
    >   printf("1=%d\n5=%d\n20=%d\n",sizeof(a1),sizeof(a2),sizeof(a3));
    >   return(0);
    >
    > }
    >
    > This now successfully produces:
    > 1=1
    > 5=5
    > 20=20
    >
    > Kind Regards,
    > Vikram


    When a poster breathlesly informs this newsgroup that he/she has found
    a bug in a compiler or its supporting components more ofthen than not
    it proves to be a hole in his/her knowledge. ;-)
    Don't take this personal, it's a fact of life.
    Hans
    BTW the little program seems to prove that your compiler's sizeof() is
    quite alright
     
    Hans Vlems, Jan 25, 2011
    #18
  19. Vikram <> writes:
    > James Lothian writes:
    >> Vikram wrote:
    >>> Ian Collins writes:
    >>>
    >>>> On 01/25/11 09:50 AM, Vikram wrote:
    >>>>> Hello friends
    >>>>>
    >>>>> the code below will find the mean (average) of some numbers, however
    >>>>> it produces only garbage. Can you see a problem?
    >>>>>
    >>>>> Kind Regards,
    >>>>> Vikram
    >>>>>
    >>>>>
    >>>>> float mean(int x[])
    >>>
    >>> ^^^^^^^
    >>>
    >>> NB in this function I am considering the pointer, as an array.

    >>
    >> Regardless of how you like to think about it, when you pass an array to
    >> a function in C, the function receives a pointer to the first element of
    >> the array. That's just the way passing an array works in C. If you take
    >> sizeof() the parameter, you'll just get the size of the pointer, which
    >> is nothing to do with the size of the array.

    >
    > Hello James
    >
    > I think you are wrong about this. I have been doing some tests and what I
    > discovered is my library's sizeof() function is buggy! For some reason it
    > miscalculates all sizes by a multiple of 4. It's easy to correct this,
    > see the code below


    You have misunderstood.

    > #define sizeof(x) (sizeof(x)/4)


    This macro is likely to break things very badly if you try to use it.

    > main()


    This should be "int main(void)". Your compiler will probably let you
    get away with the old-style "main()" declaration. This is not the cause
    of your problems, but you should fix it anyway.

    > {
    > int a1[1];
    > int a2[5];
    > int a3[20];
    > printf("1=%d\n5=%d\n20=%d\n",sizeof(a1),sizeof(a2),sizeof(a3));


    sizeof (either the built-in operator or your macro) yields a result of
    type size_t, which is an unsigned type. The "%d" format requires an
    argument of type int, a signed type. If size_t and int happen to be the
    same size on your system, the above is likely to *appear* to work
    correctly, but it could break badly on a different system. You can
    avoid this by converting each operand to int, or (if your implementation
    supports it), by using the "%zu" format which does require a size_t
    argument.

    printf("1=%d\n5=%d\n20=%d\n", (int)sizeof a1, (int)sizeof a2, (int)sizeof a3);
    or
    printf("1=%zu\n5=%zu\n20=%zu\n", sizeof a1, sizeof a2, sizeof a3);

    This is not the cause of your problems, but you should fix it anyway.

    > return(0);


    The parentheses are unnecessary but harmless.

    > }
    >
    > This now successfully produces:
    > 1=1
    > 5=5
    > 20=20


    That's the output I'd expect on a system with sizeof(int) == 4.

    Some things you should understand:

    sizeof is an operator, not a function. It might seem odd to have an
    operator whose name is a keyword rather than a sequence of one or more
    punctuation characters, but there it is.

    There are actually two forms. One is ``sizeof expr'', which
    yields the size of the result of an expression (without evaluating
    the operand in most cases). If you write ``sizeof(a1)'', you're
    applying sizeof to a parenthesized expression; the parentheses
    are part of the operand, not part of the syntax of sizeof itself,
    just like writing ``-(x)'' rather than ``-x''. If you're more
    comfortable adding parentheses, they won't hurt anything (the same
    applies to your return statement), but you should at least be able to
    understand what's going on when you're reading someone else's code.
    In some cases you might need parentheses just for grouping.

    The other form is ``sizeof ( type-name )'', which yields the size
    of a given type; for that form, the parentheses are required.

    sizeof yields the size of its operand *in bytes*. It does not yield the
    number of elements in an array, unless the array happens to have
    one-byte elements. (A byte is *at least* 8 bits; it will be exactly
    8 bits on any system you're likely to encounter.)

    The reason dividing by 4 gave results that you thought were sensible is
    that sizeof(int) happens to be 4 on your system. It could be 2, or 8,
    or even 1, on another system (the latter is possible only if a byte is
    at least 16 bits).

    It's common to define a macro to determine the number of elements in an
    array:

    #define ARRAY_LENGTH(arr) (sizeof (arr) / sizeof (arr[0]))

    Note that this works only if you apply it to an array object. If you
    try to apply it to a function parameter -- well, read section 6 of
    the comp.lang.c FAQ, <http://www.c-faq.com/>. And browse the rest of it
    while you're there; it's an excellent resource.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 25, 2011
    #19
  20. In article <ihkomc$ehm$>,
    Vikram <> wrote:
    >Hello friends
    >
    >the code below will find the mean (average) of some numbers, however it
    >produces only garbage. Can you see a problem?
    >
    >Kind Regards,
    >Vikram
    >
    >
    >float mean(int x[])
    >{
    > int i,n;
    > float sum;
    > n=sizeof(x);
    > for(i=sum=0;i<n;sum+=x[i++]);
    > return sum/n;
    >}
    >
    >main()
    >{
    > int* x,n;
    > printf("how many numbers? ");
    > scanf("%d",&n);
    > x=malloc(n*sizeof(int));
    > printf("enter %d numbers\n",n);
    > while(n--)scanf("%d",x+n);
    > printf("mean=%f\n",mean(x));
    >}


    Isn't it funny how everybody has posted all this irrelevant stuff about
    sizeof, and pointers, and arrays, and what have you, but nobody has
    actually told you how to fix your program?

    Here's how it should be written:

    /* First, the usual garbage to get past the CLC censors */
    #include <stdio.h>
    int main(void)
    {
    int *x,i,n;
    double sum;

    printf("how many numbers? ");
    scanf("%d",&n);
    x=malloc(n*sizeof(int));
    printf("enter %d numbers\n",n);
    while(n--)scanf("%d",x+n);
    for(i=sum=0;i<n;sum+=x[i++]);
    printf("mean=%f\n",sum/n);
    }

    --
    "We should always be disposed to believe that which appears to us to be
    white is really black, if the hierarchy of the church so decides."

    - Saint Ignatius Loyola (1491-1556) Founder of the Jesuit Order -
     
    Kenny McCormack, Jan 25, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Antonio D'Ottavio

    URL inside a mail produced with aspx

    Antonio D'Ottavio, Aug 30, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    592
  2. Replies:
    0
    Views:
    774
  3. Replies:
    0
    Views:
    349
  4. Medi Montaseri
    Replies:
    2
    Views:
    295
    Gianni Mariani
    Nov 27, 2003
  5. Replies:
    1
    Views:
    461
    mrstephengross
    Jul 25, 2005
Loading...

Share This Page