1

This is my code:

double values[8], cumulative[8];

printf("Enter first decimal number: ");
scanf("%f", values[0]);
printf("values[0] = %g", values[0]);

My problem is that the scanf statement crashes the program, and the second printf is never executed. My original attempt was to fill each slot of the array with a double, but since that didn't work I simplified the program to this, but this doesn't work either.

I'm a beginner learning C, so I probably made a stupid mistake I just can't see. Any help would be appreciated, thanks!

Edit:

Okay, so apparently I need to add an ampersand to the scanf statement. But I thought an array was just a pointer to the first element of the array? Why do I have to use the ampersand?

thePurpleMonkey
  • 778
  • 2
  • 13
  • 16
  • 1
    `scanf("%lf", &values[0]); // note the ampersand and the "%lf"` – Michael Burr Feb 02 '13 at 20:36
  • Re Edit: Because `values[0]` is an array _element_, not an array. To get it's address, you write `&values[0]`. – vonbrand Feb 02 '13 at 23:46
  • Possible duplicate of [Why does scanf() need & operator (address-of) in some cases, and not others?](https://stackoverflow.com/questions/3440406/why-does-scanf-need-operator-address-of-in-some-cases-and-not-others) – phuclv Sep 09 '18 at 04:43
  • and duplicate of [scanf not working. need to read double from console](https://stackoverflow.com/q/9860615/995714). Also read [Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?](https://stackoverflow.com/q/210590/995714) – phuclv Sep 09 '18 at 04:47

3 Answers3

1

scanf("%f", values[0]); - Here address of first element should be passed to scanf. You are passing value of first element which is a garbage value so that it crashed.

values[0] is *(values + 0), so this will give value of the first element not the address of the first element.

Do scanf("%lf", &values[0]); or scanf("%lf", (values + 0)); or scanf("%lf", values);

As it is double use %lf instead of %f.

One more problem in your program is uninitlized variables. Try to initialize the variable to zero while declaring.

double values[8] = {0};
double cumulative[8] = {0};

Acessing some wrong pointer in some place of your code will leads to 100% crash if its initiliazed to zero. Otherwise it will try to access some garbage value pointer which will leads to memory corruption, this sometimes will not crash instead will give unexpected output. But this also has a 50% chance of getting crash, which you are getting now.

rashok
  • 12,790
  • 16
  • 88
  • 100
0
scanf("%f", values[0]);

You need to pass the address of a location to store in to scanf(). It needs to be:

scanf("%f", &values[0]);

Otherwise, you're just telling scanf() to store the input value to whatever memory location is pointed at by the integer representation of the initialized value of values[0] -- which is most definitely not what you want.

sheu
  • 5,653
  • 17
  • 32
0

The format for scanning a double is %lf; %f is for float. This is different from printf(), which confuses people — me too. You also need to pass a pointer to the variable.

If you use GCC, it should be warning you about a format mismatch. If it doesn't, you aren't compiling with enough warning options enabled (-Wall is a good start point; add -Wextra and -Werror if you can). The explicit option for checking printf() and scanf() formats is -Wformat, but it is included with -Wall.

#include <stdio.h>

int main(void)
{
    double values[8];

    printf("Enter first decimal number: ");
    if (scanf("%lf", &values[0]) != 1)
        printf("Scan failed!\n");
    else 
        printf("values[0] = %g\n", values[0]);
    return(0);
}

Note that this includes a newline at the end of the output, and also diagnoses when there is a problem (such as no data, or invalid data) on the input.

I thought an array was just a pointer to the first element of the array? Why do I have to use the ampersand?

  1. An array is not just a pointer to the first element of the array, but when an array name is used in an expression other than as an argument of sizeof(), it changes to the pointer to the first element of the array.
  2. You have to use the ampersand because values[0] is the value of the first element of the array, not the address of the first element of the array, and scanf() needs the address, not the value. Remember: a[i] == *(a + i) for an array name or pointer a and an index i, and note the * to dereference the pointer. If you wrote scanf("%lf", values) or scanf("%lf", values + 0), you are passing a pointer. Note that passing scanf("%lf", &values) would be a type mismatch (though the value passed as the address is the same — so it coincidentally 'works'). The type passed would be 'pointer to array of 8 double', which is not the same as 'pointer to double'.
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278