Suppose I have the variable counter. If I need to:
access and modify the variable from many places in the code
make sure that the variable is modified in the "correct" way,
is this solution adequate, or are there more efficient/cleaner ways to do it?
int counter_access(int value) {
static int counter = 0;
if (value > 100) {
printf("there is a bug in the code");
return counter;
}
counter += value;
return counter;
}
And then when I need to modify the variable:
counter_access(10); /* increase counter by 10 */
counter_access(-2); /* decrease counter by 2 */
And when I need to access the variable:
if (counter_access(0) == 100) do_something();
This solution seems rather kludgy to me. However, I can't think of very many good ways to do this. I could use global variables (which cause bugs). I could pass the address of counter to the functions which need it, but that doesn't make sure that the variable isn't modified in an incorrect way (in the example above, if counter is incremented by more than 100, there is an error).
Essentially, the problem with using a function to access the variable is that there isn't a satisfactory way to tell the caller that the value is incorrect.
Using a single function for things like this is a good option for single threaded programs, you just need to set up things in the proper way.
To signal that something went wrong you can use some "out of the range" value. In your case the counter range is 0 .. 100.
You may have something like:
#define COUNT_OVERFLOW -1
#define COUNT_UNDERFLOW -2
#define counter_get() counter_add(0)
int counter_add(int incr)
{
static int counter = 0;
int counter_temp;
counter_temp = counter +incr;
if (counter_temp < 0) return COUNT_UNDERFLOW;
if (counte_temp > 100) return COUNT_OVERFLOW;
counter = counter_temp;
return counter;
}
Now, to detect an error you may check if the return value is < 0:
cnt = counter_add(x);
if (cnt < 0) {
fprintf(stderr,"There is a bug in the code\n");
}
....
if (counter_get() == 100) {
printf("DONE!\n");
}
Note as the value of counter is preserved even if there's an error. Also, it's better not to have functions like your counter_access() printing error messages, it's better to check the return value and make the caller print it (if it is so inclined).
I added the macro counter_get() to avoid having the user remember that adding 0 has the side effect of returning the current counter value.
As mentioned before, in more complicated cases you shouldn't use static variables (or equivalently, global variables). In those cases the proper way is to have a struct that is instatiated for each thread and keeps the variables that are relevant for that thread state. You will have to pass a pointer to that structure around and having the counter_access() function accepting it as a parameter.
Looking closely, you can see that here we are trying to mimick the object-oriented approach of encapsulating data and operations. In this case we implemented (implicitly) a single instance of an object (the counter) that has two methods: one to change the value and one to get the value.
Related
As a good practice, do you think one should verify passed parameters within a function to which the parameters are being passed, or simply make sure the function will always accept correct parameters?
Consider the following code:
Matrix * add_matrices(const Matrix * left, const Matrix * right)
{
assert(left->rowsCount == right->rowsCount
&& left->colsCount == right->colsCount);
int rowsCount = left->rowsCount;
int colsCount = left->colsCount;
Matrix * matOut = create_matrix(rowsCount, colsCount);
int i = 0;
int j = 0;
for (i; i < rowsCount; ++i)
{
for (j; j < colsCount; ++j)
{
matOut->matrix[i][j] = left->matrix[i][j] + right->matrix[i][j];
}
}
return matOut;
}
Do you think I should check the parameters before passing them to the function or after, ie. in the function? What is a better practice or is it programmer dependant?
Inside. The function can be viewed as an individual component.
Its author is best placed to define any preconditions and check them.
Checking them outside presupposes the caller knows the preconditions which may not be the case.
Also by placing them inside the function you're assured every call is checked.
You should also check any post-conditions before leaving the function.
For example if you have a function called int assertValid(const Matrix*matrix) that checks integrity of the object (e.g. the data is not a NULL pointer) you could call it on entry to all functions and before returning from functions that modify a Matrix.
Consistently use of pre- and post- condition integrity are an enormously effective way of ensuring quality and localising faults.
In practice zealous conformance to this rule usually results in unacceptable performance. The assert() macro or a similar conditional compilation construct is a great asset. See <assert.h>.
Depends if the function is global in scope or local static.
A global function cannot control what calls it. Defensive coding will perform validation of the arguments received. But how much validation to do?
int my_abs(int x) {
assert(x >= -INT_MAX);
return abs(x);
}
The above example, in a debug build, checks to insure the absolute value function will succeed as abs(INT_MIN) may be a problem. Now if this checking should be in production builds is another question.
int some_string(char *s) {
assert(s != NULL);
...
}
In some_string() the test for NULL-ness may be dropped as function definition may state that s must be a string. Even though NULL is not a C string, testing for NULL-ness is only 1 of many bad pointers that could be passed which do not point to a string. So this test has limited validation.
With static functions, the code is under local control. Argument validation could occur by the function, the caller, both or neither. That selection is code dependent.
A counter-example exist with user/file input. Basic data qualification should occur promptly.
int GetDriversAge(FILE *inf) {
int age;
if (fscanf("%d", &age) != 1) Handle_Error();
if (age < 16 || age > 122) Handle_Error();
return age
}
In OP's example, parameter checking is done by the function, not the caller. Without the equivalence test, the function can easily fail in mysterious ways. The cost of this check here is a small fraction of the code's work. That makes it a good check as expensive checks (time, complexity) can cause more trouble than they solve. Note that if the calling code did this test and add_matrices() was called from N places, then that checking code is replicated N times in various, perhaps, inconsistent ways.
Matrix * add_matrices(const Matrix * left, const Matrix * right) {
assert(left->rowsCount == right->rowsCount
&& left->colsCount == right->colsCount);
Conclusion: more compelling reasons to check the parameters in the function than in the caller though exceptions exist.
What I do is to check the parameters inside the function and act accordingly (throw exceptions, return error messages, etc.). I suppose it's the function's job to check whether the passed parameters are of the correct data type and contain valid values.
The function should perform its task correctly, otherwise, it should throw an exception. The client/consuming code may or may not do a check, it depends on the data source and how much you trust it, either way, you should also enclose the function call in a catch-try block to catch invalid argument exception.
EDIT:
Sorry, I confused C for C++. Instead of throwing an exception, you can return null. The client doesn't necessarily have to check the data before calling (depending on the data source and other factors like performance constraints), but must always check for null as a return value.
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.
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
I have some code that should do a simple thing :
if the value of the parameter is -1 then I should change the value.
else - do nothing
I have a list of 20 parameters, but I wanted to know if there is any way of checking it without doing :
if param1 == -1 then ... else...
if param2 == -1 then.... else...
anyone has any idea what can I do to make it more efficient ?
thanks!
If parameters are all variables (it's not in array or something), you can make a function and write
change_or_let_it_be( ¶m1, value );
change_or_let_it_be( ¶m2, value );
change_or_let_it_be( ¶m3, value );
and there you have only one if (in function) and a lot of calls.
Better would be to store it in some structure (array, list etc) and avoid calling this function 20 times.
Not sure if I'm understanding what you want, but how about this?
void func(int params[20]) {
for (int i = 0; i < 20; ++i) {
if (params[i] == -1)
params[i] = NEW_VALUE;
}
}
Checks every value with a for, so you don't need to hardcode all the different values, and then changes the parameter when it's -1. Also note that I'm supposing with "efficient" you mean more code-writing-time efficient here!
To be honest the series of if/then statements is the most efficient, if not the prettiest solution! Embedding the tests in a loop and storing the parameters as an array requires the following additional calculations:
- testing that the loop counter does not exceed the maximum
- incrementing the loop counter
- using pointer arithmetic to access each parameter
Of course these speed considerations are only a factor if you have to perform those 20 tests man many times. But in fact you've already written it as efficiently as possible :)
Another cleaner solution:
int *p[] = {¶m1, ¶m2, ¶m3, NULL};
int i = 0;
for(;p[i] != NULL; i++) {
if(*p[i] == -1) *p[i] = SOME_VALUE;
}
I have two functions for allocating and deallocating timers.
Allocate timer allocates a timer and returns an int to the timer that has been allocated
int allocate_timer(void)
{
int count = 0;
int allocated = 0;
/*Loop to find the first timer that is not allocated*/
for(count = 0; count< ARRAY_SIZE; count++)
{
if(allocated_timers[count] == '0')
{
/*When the next timer available timer is found it is set to allocated and timer is set to zero*/
allocated_timers[count] = '1';
timers[count] = 0;
break;
}
else if(allocated > ARRAY_SIZE - 1)
{
printf("No timers available\n");
exit(0);
}
else
{
allocated++;
}
}
/*Position of the allocated timer is returned*/
return count;
}
Deallocating timer, takes in an int to the position that is going to be deallocated
void deallocate_one_timer(int position)
{
if(TIMER_ALLOCATED == allocated_timers[position])
{
allocated_timers[position] = '0';
timers[position] = 0;
}
}
I can't see away to make them anymore robust than they already they are.
Any advice on how to make them better?
The variable allocated is always equal to count (so could be removed), and IMO it's potentially confusing to use '0' and '1' as the values in the allocated_timers array. Usually it would be 0 and 1.
Neither of them affects the robustness of the code as it is, but the easier the code is to understand, the more robust it is against future modification.
When you have two "parallel" arrays, like you do here where each timer has an entry in timers and a corresponding entry in allocated_timers, it is worth considering whether it would be better to have a single array of a struct with two members (in this case perhaps named value and allocated). Sometimes it isn't better, but often it aids understanding of the code because readers don't have to discover and remember that these two arrays are closely related.
deallocate_one_timer could be made slightly more robust against erroneous use by callers, if it checked that position is within the range 0 to ARRAY_SIZE before using it as an array index. I'm not saying that functions have a responsibility to do those checks, but they sometimes help diagnose bugs elsewhere. You can use assert for non-essential checks like this. assert has two benefits. First it self-documents that the check isn't this function's responsibility to handle, merely that you're checking someone else did what they should have. Second, you can easily disable all asserts in non-debug builds of your program if you need to make it smaller or faster.
Similarly it might be helpful to exit with an error message if a timer is deallocated that is not currently allocated, because that's likely to indicate a potential problem. Whoever deallocates it twice might do so either side of somebody else allocating it, which means that somebody else suddenly finds they no longer have exclusive use of their timer.
Finally, you set timers[index] to 0 both on allocate and on deallocate. Nothing particularly wrong with that except that it confuses the issue of which function is actually responsible for ensuring that a newly-allocated timer has the correct initial value. The deallocate function could do nothing, or it could set the timer to a value that's impossible for an allocated timer to hold (maybe -1, assuming timers go up from 0), so that when debugging you can know immediately that if you're using a timer whose value is -1, something has gone wrong.
Finally finally, this code (obviously) isn't thread-safe, which I suppose is a kind of non-robustness. There's no shame in writing code that can't be used in multi-threaded programs, especially with embedded systems that may not even have the capacity to create threads. Just so long as it's a deliberate decision, and is documented.
decide whether you want to use '0' and '1' or constants such as
TIMER_ALLOCATED, used in deallocate_one_timer, and be consistent.
your use of the allocated variable is redundant. The loop would be
better as:
int allocate_timer(void)
{
int count;
for (count = 0; count < ARRAY_SIZE; count++)
{
if (allocated_timers[count] == '0')
{
allocated_timers[count] = '1';
timers[count] = 0;
return count;
}
}
fprintf(stderr, "No timers available\n");
exit(EXIT_FAILURE);
}
Or perhaps better still not to exit on failure but to return and error.