I have a function that calculates geometric mean (nth root of product of terms, where n is number of terms), and the only thing I'm having trouble with is figuring out how to keep track of how many terms there were. The only thing I could come up with was a global variable, but I know I shouldn't do that. How can I do it without the global variable?
float count;
float geometricMean(float n) {
char again;
float j;
printf("Input a number: ");
scanf("%f", &j);
printf("Another number? (y/n) ");
scanf(" %c", &again);
if (again == 'y') {
j *= geometricMean(n+1);
if (n==1)
return pow(j, (1/count));
else {
return j;
}
}
else {
count = n;
return j;
}
}
Use a static variable. Static variables don't change between function calls.
At the start of your function, write something like:
float geometricMean(float n) {
static int count = 0;
count ++;
// Rest of the code;
}
Each time you call your function, count will increase by 1 (it won't go back to 0).
Go here: What does "static" mean?
if you want to know more about static variables.
EDIT: Please don't go out using static variables just like if it was a global, just with a smaller scope. It will lead to undesired results! If you're planning to change the value of a static variable in each iteration of your function, like I did here, please make you sure you make crystal clear what those alterations are and use them right after defining your static if possible.
Related
In a block of code, I need to get an input from the user and print it right away. I'm a bit confused with good practice between these two snippets.
Snippet #1:
int i;
while(){
scanf("%d", &i);
printf("%d", i);
}
I'm using the variable i only within the loop. So, should I declare and use it within the loop itself to maintain good practice of using scopes?
If I do the same,
Snippet #2:
while(){
int i;
scanf("%d", &i);
printf("%d", i);
}
the variable i is declared on every iteration of the loop! These re-declarations consume more processing power and re-allocation of memory again and again
Which approach is better and why?
You said:
the variable i is declared on every iteration of the loop! These re-declarations consume more processing power and re-allocation of memory again and again
This is an invalid assumption on your part. The C compiler will calculate the total memory the function needs and allocate for that usage up front. For local variables, that allocation is actually just a shift of a pointer.
To illustrate, if I have a function:
void a_function () {
extern int x, n1, n2;
while (--n1) {
int i;
scanf("%d", &i);
x += i;
}
while (--n2) {
int i, j;
scanf("%d %d", &i, &j);
x += i + j;
}
}
The compiler will allocate space for 2 integers on entry into the function (or none, if it decides it can do everything in registers).
First, I am a total beginner, so the question is probably very obvious for all of you, but i don't get what's wrong with the while loop in this program. Te aim of the program is to calculate the average between numbers where the user inputs 0 when he wants to continue putting numbers in and inputs 1 when he wants to stop, so the loop is supposed to stop when the user puts 1 and to compute a sum of the values when he enters 0 at the end. So this is what i wrote, i used stdio.h and stdlib.h as libraries :
int decision;
int value;
int sum = 0;
float av;
int order = 1;
printf ("for continue press: 0\n ");
printf ("for stopping press: 1\n ");
while (decision == 0) {
printf("input value:");
scanf("%d", &value);
sum = sum + value;
printf ("continue?");
scanf("%d", &decision);
order = order + 1;
}
av = (float) sum / (float) order;
printf("the average is: %.2f", av);
return EXIT_SUCCESS;
what the terminal displays is just "the average is:0.00", it skips the whole operation above.
You should initialize decision to 0
int decision = 0;
so that the while loop is true
while (decision == 0) {
on the first iteration.
In C, simply declaring a variable does not assign it a value of 0. You have to do that. In fact, actually using a variable that has not been initialized is undefined behavior. Most likely, the variable contains whatever contents was in the memory location assigned to it.
The solution is to actually define decision.
int decision = 0;
In C, declaring a variable does not initialize it. So the initial value of decision is more or less random. If it's not zero (and it likely is not), the cycle is never entered.
Perversely, when in "debug mode" or using some instrumentation such as valgrind, memory might be either zeroed or initialized consistently, leading to "unreproducible" bugs that may be difficult to track. That is why you really want to always initialize your variables
Try with:
int decision = 0;
Also, turn on all compiler warning flags. You want to be warned when such things happen, and the compiler can do so if you tell it to.
Another way
You do not need decision anywhere else, so it's good to have one less variable in the outer scope:
for (;;) {
int decision; /* The variable only lives inside this loop */
printf("input value:");
scanf("%d", &value);
sum = sum + value;
printf ("continue?");
scanf("%d", &decision);
if (0 == decision) {
break;
}
order = order + 1;
}
Notice
If you start order from 1, and enter only one value, order will be increased to 2, and this will get your calculation off. Either start from 0 or increase the value after decision confirmation.
You have not initialized the decision variable and that is why the error.
int decision = 0;
#include <stdio.h>
int main () {
int days, flights, t, b;
float length, mean, sum;
printf("How many days has your dragon been practicing?\n");
scanf("%d", &days);
for(t=1; t<=days; t++) {
printf("How many flights were completed in day #%d?\n", t);
scanf("%d", &flights);
for(b=1; b<=flights; b++) {
printf("How long was flight #%d?\n", b);
scanf("%f", &length);
sum+=length;
}
mean = sum/flights;
printf("Day #%d: The average distance is %.3f.\n", t, mean);
}
}
the sum used to calculate the mean is supposed to be only the number from one iteration of the loop added together. instead the sum used numbers from the new iteration and old iteration added together.
If I understood your problem correctly, after the last printf() statement, you should reset sum to 0, like sum = 0;.
That said, the major issue in your code is that, you're using sum (an automatic storage local variable) while uninitialized. You should be initializing sum to some value (0, maybe) before making use (sum+=) of it. Otherwise, it it invokes undefined behavior.
To quote C11 standard, chapter ยง6.7.9
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. [...]
sum won't clear because you don't clear it ! The point of writing code is to make your dumb machine(yeah dumb!) know when it's got to do what!
So immediately after
for(t=1;t<=days;t++)
{
Add this:
sum=0;
This will ensure that your sum value is reset every day your dragon takes a flight! Otherwise C will use some random garbage value as your sum and you would receive weird answers!
Some suggestions:
1) If you call scanf() just after you call printf(), there is no reason to use '\n' inside that printf at the end.
2) Always check scanf() for errors or your code is useless if errors occurs.
Now about your code:
When you use something like x+=y this means x = x + y.
So, in your case sum+=length means sum=sum+length. Do you know the value of sum? Yes is a garbage value.
About this line mean = sum/flights;, what is mean, sum and what is flights? Yes, first are float but second is int.
Now putting all together:
#include <stdio.h>
int main (void){
int days, flights, t, b;
float length, mean, sum=0;
printf("How many days has your dragon been practicing?: ");
if((scanf("%d", &days)) != 1){
printf("Error\n");
}
for(t=1; t<=days; t++) {
printf("How many flights were completed in day #%d?: ", t);
if((scanf("%d", &flights)) != 1){
printf("Error\n");
}
for(b=1; b<=flights; b++) {
printf("How long was flight #%d?\n", b);
if((scanf("%f", &length)) != 1){
printf("Error\n");
}
sum+=length;
}
mean = sum/(float)flights;
printf("Day #%d: The average distance is %.3f.\n", t, mean);
}
return 0;
}
I am doing a simple function that returns the minimum integer from numbers given from the user(array).
However, it always print 2686916 at the end. Here is my code:
int function()
{
int ar[100];
int i;
int smallest = INT_MAX;
int nums;
int num;
int sum=0;
printf("\nenter array size\n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
if (nums <smallest){
smallest=nums;
printf("the smallest %d\n,smallest);
return 0;
}
}
I'm not sure what I'm doing wrong.
My friend, it seems you are new to C, and before you ask questions like this one you should try to follow some tutorials for C. You might try something like this.
If the question you ask is not clear or the code you post won't compile anyway it is very hard to help you out. For now this is all I can do:
int function()
{
int ar[100];
int i;
int smallest = INT_MAX;
int nums = 0; //Always Initialize your variables!
int num = 0;
int sum= 0;
printf("\nenter array size\n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
if (nums <smallest)
{
smallest=nums;
printf("the smallest %d\n",smallest);
}
return 0; //Don't put this in a place that might not be executed!
}
Now it should at least compile, it still doesn't do anything useful as far as I can see. You compare "nums", a variable you didn't use before, with the biggest value of an int, set it to the never used "nums" and print it.
You might want use "sums" or "ar[i]" in the if statement instead, and printing one of these values.(still not 100% sure what you want to do).
Some tips for next time (before you ask a question!):
Variables should always be initialized
In your code you try to use the value of "nums" before it gets a value, this might cause errors or strange results in your code.
Don't put a return in a place that might be skipped,
In your code, "nums" would be bigger than "smallest" (unlikely, bit for example), the code would skip the if statement and never reach the return.
Read your compiler warnings
The code you posted can't compile, read your errors and warnings, and fix them.
(tip) Use better variable names, using names like nums, num and sum make it easy to overlook a mistake.
I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!