Unused Variable Error - c

I am new to programming and I am currently learning the C language. This is my code. I have tried different fixes, such as making sure I have my semicolons. However, when I go to check my code in the online compiler, I always get unused variable and data definition has no type or storage class. Any information would help me, I assure you, so please let me know what you think a possible solution could be.
//C code
//This program will calculate the average speed of passing cars using a WHILE-END loop
//Developer: Jasmine Tucker
//Date: 7 Sept 2014
#include <stdio.h>
Int main ()
{
/* define variable */
int average_speed;
int car_count;
int car_speed;
};
/* set variable values */
average_speed= 0;
car_count=0;
car_speed=0;
/*WHILE-END loop */
WHILE (car_count > 0)
{
printf (“Enter the car’s speed %s:”, car_count);
scanf (“%d”, & car_speed);
average_speed= car_speed/ car_count
car_count++;
}
printf (“\n The average speed is %d miles per hour. \n”, (average_speed));
return 0;
}

A Few Things:
Int main()
should be
int main()
This is perhaps an easy typo, or the unfortunate side effect of a grammar check.
You could probably do well by studying the standard types in C.
Modifiers aside, there are not very many, and except for special types, _Bool, _Complex, _Imaginary, they are lowercase. (The same holds true for keywords).
Storage class refers to something less commonly used, or at least out of the scope of this program (auto,register,static,extern).
The following definitions use the int type as well, so I will reproduce them here [sic].
/* define variable */
int average_speed;
int car_count;
int car_speed;
};
/* set variable values */
average_speed= 0;
car_count=0;
car_speed=0;
As others have mentioned, there is an extraneous curly brace after the three variables are declared. };
(Notice how sad he looks.)
If you are coming from a language that requires semi-colons after curly braces, you have some hard habits to break.
In any case, commenting that out should remove several errors:
/* }; */
as this is effectively closing the block for main().
As user haini pointed out, you could actually pull the variable definitions outside of main(), allowing them to be accessible to any function. (Use across source files would bring up the aforementioned extern).
Some programmers use special varaible [pre|suf]fixes to distinguish global from local variables.
int g_average_speed;
int g_car_count;
int g_car_speed;
As these variables need to be initialized before use, you can do this in the definition:
int g_average_speed = 0;
int g_car_count = 0;
int g_car_speed = 0;
Often, the use of global variables is discouraged, preferring instead parameter-based sharing of variables, which makes more sense once you introduce multiple functions.
As mentioned, 'WHILE' is not a keyword, while while is. As with the variable types, the list of keywords is very short, and mostly lowercase. It is good to know the keywords so as to avoid using them for variable/function naming.
As far as logic is concerned, your while-loop will never begin, as the expression car_count > 0 will not be satisfied as you've initialised car_count to 0.
While it's easy to hard-code a value, you may probably want to set another variable such as max_cars to an upper limit and check for car_count < max_cars. (Don't forget you're counting from 0).
/* define variable */
int max_cars = 10;
/* rest of variables, init */
while( car_count < max_cars )
Now, aside from the interesting quotations '“' which will give you trouble, and the missing semicolon at average_speed = car_speed / car_count as pointed out again by haini, you should try to step through your loop mentally. Don't ever forget that users are inherently evil and will attempt possibly unforseen values when allowed to interact with the program (scanf()). Negative values and 0 are not out of the question with int and %d, though you may expect some cars to be 'parked' and thus speed 0. Down the line, the unsigned modifier and %u may be of use.
In any case, it's good to get in the habit of sanitizing user input, and/or giving the user an option to opt-out (i.e. "TYPE -1 to break..." ), and checking for invalid or exit codes with an if. (break may be the keyword to pursue in this case)
Your average_speed calculation doesn't quite seem right. Don't forget you're storing values into integers, so you're gonna have some rounding errors.
First think about what happens when your initial case arrives -- what is car_count, and what happens when you divide by that value?
Then, think about the final case, (assuming your upper boundary is 10) in which car_count == 9. You will be assigning car_speed / car_count to average_speed. Is this really what you want?
You can minimize rounding errors and more difficult calculation by maybe 'keeping track' of the total of the speeds, and only one average calculation.
/* define variable */
int total_speed = 0;
In your while loop:
total_speed += car_speed;
or
total_speed = total_speed + car_speed;
And then outside of the loop:
average_speed = total_speed / (car_count - 1);
(The adjustment to car_count is necessary because the value increments after the final loop.)
NOTE: in this limited example, the average_speed variable may not be necessary, unless used outside of the printf().

There are a few issues in your code that I see.
The code will never get in the while loop. If you initialize it to 0, it will never be greater than 0, so will never enter the loop.
Even if it gets into the loop, this is an infinite loop. Keep adding one to a variable would make it so the variable is always greater than 0, so will never exit the loop.
MAJOR ONE: your variables are inside main, but you are using them outside of main!
#include <stdio.h>
Int main ()
{
/* define variable */
int average_speed;
int car_count;
int car_speed;
**};**
(Not sure about this one) but you have an uppercase I in the word int in your method declaration, and uppercase WHILE, should be while.

Code that is not within the main() function causes your errors.
//C code
//This program will calculate the average speed of passing cars using a WHILE-END loop
//Developer: Jasmine Tucker
//Date: 7 Sept 2014
#include <stdio.h>
/* define variable */
//You Can define global variables or local variables. If you want to use them outside your
//function you Need to declare them globally as done here
int average_speed;
int car_count;
int car_speed;
//This is where the Magic happens. If you execute your program it will jump to the main
//function and execute whatever is in there
int main ()
{
/* set variable values */
average_speed= 0;
car_count=0;
car_speed=0;
/*WHILE-END loop */
//The while Loop is not a function, you Need to put it in main() so it gets executed
while(car_count > 0)
{
//You did use very strange signs here. The correct ones are These: ""
printf("Enter the car’s speed %s:", car_count);
scanf("%d", &car_speed);
average_speed= car_speed / car_count; //You Forget a semicolon indeed ;-)
car_count++;
}
printf("\n The average speed is %d miles per hour. \n", average_speed);
return 0;
} //semicolons at the end of a function are not used in C. They are used if you want to define a structure.
I strongly suggest that you start off with basic books / a wiki to C programming. Here is a good (at least it was for me) start into that: http://en.wikibooks.org/wiki/C_Programming/Intro_exercise

Related

Understanding the reason behind a output

I am a beginner is Computer Science and I recently started learning the language C.
I was studying the for loop and in the book it was written that even if we replace the initialization;testing;incrementation statement of a for loop by any valid statement the compiler will not show any syntax error.
So now I run the following program:
#include<stdio.h>
int main()
{
int i;
int j;
for(i<4;j=5;j=0)
printf("%d",i);
return 0;
}
I have got the following output.
OUTPUT:
1616161616161616161616161616161616161616.........indefinitely
I understood why this is an indefinite loop but i am unable to understand why my PC is printing this specific output? Is there any way to understand in these above kind of programs what the system will provide us as output?
This is a case of undefined behaviour.
You have declared i so it has a memory address but haven't set the value so its value is just whatever was already in that memory address (in this case 16)
I'd guess if you ran the code multiple times (maybe with restarts between) the outputs would change.
Some more information on uninitialized variables and undefined behaviour: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/
Looks like i was never initialized, and happens to contain 16, which the for loop is printing continuously. Note that printf does not add a new line automatically. Probably want to read the manual on how to use for.
To better understand what is going on, you can add additional debugging output to see what other variables are set to (don't forget the \n newline!) but really problem is the for loop doesn't seem right. Unless there's something going on with j that you aren't showing us, it really doesn't belong there at all.
You are defining the variable i but never initializing it, instead, you are defining the value for j but never using it.
On a for loop, first you initialize the control variable, if you haven't already done it. Then you specify the condition you use to know if you should run another iteration or not. And last but not least, change the value of the control variable so you won't have infinite loops.
An example:
#include <stdio.h>
int main()
{
// 1. we declare i as an integer starting from 1
// 2. we will keep iterating as long as i is smaller than 10
// 3. at the end of each iteration, we increment it's value by 1
for (int i = 1; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}

Global variable reads inside tight loops in C

Say I have a tight loop in C, within which I use the value of a global variable to do some arithmetics, e.g.
double c;
// ... initialize c somehow ...
double f(double*a, int n) {
double sum = 0.0;
int i;
for (i = 0; i < n; i++) {
sum += a[i]*c;
}
return sum;
}
with c the global variable. Is c "read anew from global scope" in each loop iteration? After all, it could've been changed by some other thread executing some other function, right? Hence would the code be faster by taking a local (function stack) copy of c prior to the loop and only use this copy?
double f(double*a, int n) {
double sum = 0.0;
int i;
double c_cp = c;
for (i = 0; i < n; i++) {
sum += a[i]*c_cp;
}
return sum;
}
Though I haven't specified how c is initialized, let's assume it's done in some way such that the value is unknown at compile time. Also, c is really a constant throughout runtime, i.e. I as the programmer knows that its value won't change. Can I let the compiler in on this information, e.g. using static double c in the global scope? Does this change the a[i]*c vs. a[i]*c_cp question?
My own research
Reading e.g. the "Global variables" section of this, it seems clear that taking a local copy of the global variable is the way to go. However, they want to update the value of the global variable, whereas I only ever want to read its value.
Using godbolt I fail to notice any real difference in the assembly for both c vs. c_cp and double c vs. static double c.
Any decently smart compiler will optimize your code so it will behave as your second code snippet. Using static won't change much, but if you want to ensure read on each iteration then use volatile.
Great point there about changes from a different thread. Compiler will maintain integrity of your code as far as single-threaded execution goes. That means that it can reorder your code, skip something, add something -- as long as the end result is still the same.
With multiple threads it is your job to ensure that things still happen in a specific order, not just that the end result is right. The way to ensure that are memory barriers. It's a fun topic to read, but one that is best avoided unless you're an expert.
Once everything translated to machine code, you will get no difference whatsoever. If c is global, any access to c will reference the address of c or most probably, in a tight loop c will be kept in a register, or in the worst case the L1 cache.
On a Linux machine you can easily generate the assembly and examine the resultant code.
You can also run benchmarks.

C for loop, supposed to be able to omit initialization inside loop itself, doesn't work as intended

so I'm slowly trying to learn C from scratch.
I'm at a point in the book I'm using where an exercise is proposed: use nested loops to find Pythagorean triplets. Now I'll show the code.
#include <stdio.h>
int main(void){
int lato1=1;
int lato2=1;
int ipotenusa=1;
for(;lato1 <= 500; lato1++){
for(;lato2 <= 500; lato2++){
for(;ipotenusa <= 500; ipotenusa++){
if (((lato1 * lato1)+(lato2 * lato2))==(ipotenusa*ipotenusa)){
printf("Tripletta %10d %10d %10d\n",lato1,lato2,ipotenusa);
}
}
}
}
return 0;
}
now, apart from terrible formatting and style, apart from the shi*t optimization,
the code as shown, doesnt work.
It only execute the inner most loop, and then the program ends.
If, however, I initialize each variable/counter inside each loop then it works.
Why?
I read that for loop initialization is valid even whitout no arguments (;;) but in this case I just wanted to initialize those variables before the loop, let's say because I wanted to access those value after the loop is done, it just doesn't seem to work like it's supposed to.
English is not my primary language so apologies in advance for any mystake.
Can somebody explain what is the problem?
Edit 1: So, I don't know if it was my bad English or something else.
I said, if I declare and initialize the variables before the loop, like in the code I've shown you, it only goes through the inner most loop (ipotenusa) and it does so with the following output values: 1 1 1 then 1 1 2 then 1 1 3 and so on, where the only increasing number is the last one (ipotenusa); AFTER we reach 1 1 500 the programs abruptily ends.
I then said that if I initialize the variables as normal, meaning inside the for loop instruction, then it works as intended.
Even if declared earlier there is NO reason it should't work. The variable's value it's supposed to increase. Up until now the only useful answer was to initialize a variable outside the loop but assign a value to it in the loop statement, but this is not at the end the answer I need, because I should be able to skip the initialization inside the loop statement altogether.
EDIT 2: I was wrong and You guys were right, language barrier (most likely foolishness, rather) was certainly the cause of the misunderstanding lol. Sorry and Thanks for the help!
You accidentally answered your own question:
...in this case I just wanted to initialize those variables before the loop, let's say because I wanted to access those value after the loop is done...
Think about the value of ipotenusa...or have your program print out the value of each variable at the start of each loop for debugging purposes. It'll look something like the following log.
lato1: 1
lato2: 1
ipotenusa: 1
ipotenusa: 2
ipotenusa: 3
ipotenusa: 4
ipotenusa: 5
lato2: 2
lato2: 3
lato2: 4
lato2: 5
lato1: 2
lato1: 3
lato1: 4
lato1: 5
The inner loops never "reset," because you're saving the value. You're not wrong on either count, but you've set up two requirements that conflict with each other, and the C runtime can only give you one.
Basically, lato2 and ipotenusa need to be initialized (but not necessarily declared) in their for statements, so that they're set up to run again.
int lato1=1;
int lato2;
int ipotenusa;
for(;lato1 <= 5; lato1++){
for(lato2 = 1;lato2 <= 5; lato2++){
for(ipotenusa = 1;ipotenusa <= 5; ipotenusa++){
if (((lato1 * lato1)+(lato2 * lato2))==(ipotenusa*ipotenusa)){
printf("Tripletta %10d %10d %10d\n",lato1,lato2,ipotenusa);
}
}
}
}
It's worth pointing out that, even though the specification might (or might not; I don't remember and am too fuzzy to look it up, right now) say that the loop variables only exist during the loop, I've never seen an implementation actually do that, so you'll see a lot of code out there that defines the variable inside of for and uses it after. It's probably not great and a static checker like lint might complain, but it's common enough that it'll pass most code reviewers, to give you a sense of whether it can be done.
Your code does exactly what you told it to do.
If you initialise lato2 with a value of 1, what makes you think that the initialisation will be repeated at the start of the inner for loop? Of course it isn't. You told the compiler that you didn't want it to be initialised again. After that loop executed the first time, lato2 has a value of 501, and it will keep that value forever.
Even if it hadn't produced a bug, putting the initialisation and the for loop so far apart is very, very bad style (wouldn't pass a code review in a professional setting and therefore would have to be changed).
for (int lato2 = 1; lato2 <= 500; ++lato2) is clear, obvious, and works.
One approach would be - declaring variables outside of the loop and initialize them inside. This way, you can access the variables after the loops.
#include <stdio.h>
int main(void){
int lato1, lato2, ipotenusa;
for(lato1=1; lato1 <= 500; lato1++){
for(lato2=1; lato2 <= 500; lato2++){
for(ipotenusa=1; ipotenusa <= 500; ipotenusa++){
if (((lato1 * lato1)+(lato2 * lato2))==(ipotenusa*ipotenusa)){
printf("Tripletta %10d %10d %10d\n",lato1,lato2,ipotenusa);
}
}
}
}
return 0;
}
You are using variables that are initialized outside of the for loops. Usually what happens is when we use inner loops(nested loops) we intended to initialize it with base value everytime but in your case it is never going to do that. Since you have initialized variable out side of the for loops so it will persist its value through out its life time of course which is main function in this case.

Is it possible to use a for loop to change a variable name in C?

This is a generic question, so there is no actual code that I am trying to troubleshoot. But what I want to know is, can I use a for loop to change the name of a variable in C? For instance, if I have part1, part2, part3, part..., as my variable names; is there a way to attach it to my loop counter so that it will increment with each passing? I toyed around with some things, nothing seemed to work.
In C, you can't 'change the name of the loop variable' but your loop variable does not have to be determined at compile time as a single variable.
For instance, there is no reason in C why you can't do this:
int i[10];
int j;
j = /* something */;
for (i[j] = 0 ; i[j] < 123 ; i[j]++)
{
...
}
or event supply a pointer
void
somefunc f(int *i)
{
for (*i = 0; *i<10; *i++)
{
...
}
}
It's not obvious why you want to do this, which means it's hard to post more useful examples, but here's an example that uses recursion to iterate a definable number of levels deep and pass the innermost function all the counter variables:
void
recurse (int levels, int level, int max, int *counters)
{
if (level < levels)
{
for (counters[level] = 0;
counters[level] < max;
counters[level]++)
{
recurse (levels, level+1, max, counters);
}
return;
}
/* compute something using counters[0] .. counters[levels-1] */
/* each of which will have a value 0 .. max */
}
Also note that in C, there is really no such thing as a loop variable. In a for statement, the form is:
for ( A ; B ; C ) BODY
Expression A gets evaluated once at the start. Expression B is evaluated prior to each execution of BODY and the loop statement will terminate (and not execute BODY) if it evaluates to 0. Expression C is evaluated after each execution of BODY. So you can if you like write:
int a;
int b = /* something */;
int c = /* something */;
for ( a=0; b<5 ; c++ ) { ... }
though it will not usually be a good idea.
The answer is, as #user2682768 correctly remarked, an array. I am not sure whether you are aware of that and consciously do not want to use an array for some reason; your little experience doesn't give me enough information. If so, please bear with me.
But you'll recognize the structural similarity between part1, part2, part3... and part[1], part[2], part[3]. The difference is that the subscript of an array is variable and can be changed programmatically, while the subscript part of a variable name cannot because it is burned in at compile time. (Using macros introduces a meta compiling stage which lets you programmatically change the source before actually compiling it, but that's a different matter.)
So let's compare code. Say you want to store the square of a value in a variable whose name has the value as a suffix. You would like to do something like
int square1, square2, square3;
int i;
for(i=1; i<=3; i++)
{
square/i/ = i*i; /* /i/ to be replaced by suffix "i".
}
With arrays, that changes to
int square[4];
int i;
for(i=1; i<=3; i++)
{
/* the (value of) i is now used as an index in the array.*/
square[i] = i*i;
}
Your idea to change the variable name programmatically implies that all variables have the same type (because they would have to work in the same piece of code, like in my example). This requirement makes them ideally suited for array elements which all have to be of the same type. If that is too restrictive, you need to do something fancier, like using unions (but how do you know what's in it at any given moment? It's almost as if you had different variables to begin with), void pointers to untyped storage or C++ with templates.
In C You cannot append to a variable name an expression that expands to a number and use it as a sort of suffix to access different variables that begin in the same way.
The closest you can get, is to "emulate" this behaviour using a switch construct, but there wouldn't be much of a point to try to do this.
What you asked for is more suited to scripting languages.

Why is this inconsequential variable initialized within a for loop?

In the program I have pasted below, I was just wondering why the pointer "p" was initialized within the for loop? I am used to reading the conditions of a for loop as: starting from this value of a variable; until it reaches this value; increment it by this much. So it seems strange to have another variable that does not determine the ending condition and is not being incremented during each iteration in there at all.
I would have just put p=&a[0]; above the for loop and left the rest. Is this just a stylistic thing or are there differences in the way things are processed depending on where you initialize p? Is one way preferred over the other?
#include <stdio.h>
#define PRD(a) printf("%d", (a) )
int a[]={0, 1, 2, 3, 4};
int main()
{
int i;
int* p;
for (p=&a[0], i=0; i<=4; i++) PRD(p[i]);
return 0;
}
This appears to be just a style thing. I would probably have also put the initialisation of p outside the for statement, since cramming everything in there makes the code harder to read. (Because the pattern of that for loop is different from what you might usually expect, an experienced programmer will have to stop, back up, and think about what's in there before it will make sense. I initially thought there were four clauses in the for control statements until I noticed that the first separator was a comma.)
Writing the code like this (instead of initialising p outside the loop) will have no effect on performance.

Resources