I'm looking a way to flip an integer value (8bits) using it as a boolean (0 -> False, 1 -> True).
On many languages you can do val = !val to change the value. The only thing I have done is val = (val == 1) ? 0 : 1. I don't know if in C can work with a bite value.
It is for an old hardware with a 8bit processor, so the idea of use boolean is not possible, and I can't install external libraries.
In C a value of 0 is considered "false", and any other (nonzero) value is considered "true". So one, very explicit way to convert an arbitrary int value to an explicitly true-or-false Boolean value is to use the (C99 and later) bool type:
#include <stdbool.h>
int i;
bool b;
b = (i != 0) ? true : false;
But since the != operator essentially "returns" a Boolean value, you can also do
b = (i != 0);
And since the zero/nonzero definition is built in to the language, you can also just do
b = i;
But you don't have to use type bool. If you have an arbitrary-value int and you want to force it to 0/1 "in place", you have the same sorts of options:
i = (i != 0) ? 1 : 0;
Or
i = (i != 0);
Or there's another common trick:
i = !!i;
This last is concise, popular, and somewhat obscure. It changes zero/nonzero to 1/0 and then back to 0/1.
I've shown these examples using type int, but they would all work just as well with short int or char (i.e. byte).
One more thing. In your question you wrote val = (val == 1) ? 0 : 1, but that's basically meaningless. In C, at least, everything (everything!) follows from whether a value is zero or nonzero. Explicit comparisons with 1 are almost always a bad idea, if not a downright error.
I posted one answer, but I may have misread the question. If you have an integer variable -- it might be int, short int, or char -- and you want to have it cycle back and forth 0, 1, 0, 1 (which you can interpret as false, true, false, true), there are two about equally good ways to do it. You could do:
i = !a;
This first way emphasize the "Boolean" nature of the variable.
Or, you could do:
i = 1 - i;
This second way is purely numeric.
But either way will work perfectly well. In either case, i is guaranteed to alternate 0, 1, 0, 1, ...
You could also use
i = i ? 0 : 1;
or
i = (i == 0) ? 1 : 0;
Both of these will work, too, but they're basically equivalent to i = !i.
In your question you suggested
i = (i == 1) ? 0 : 1;
This would mostly work, but it looks weird to my eye. Also it would do the wrong thing if i ever ended up containing 2 (or any value other than 0 or 1).
Adding to Summit's answer, you can also do this:
#define TRUE ~0U
#define FALSE 0U
#ifndef BOOL
#define BOOL unsigned int;
#endif
int main() {
BOOL var = TRUE;
var = ~var; //Negate var and set it to false.
var = ~var; //Negate var again and set it to true.
return EXIT_SUCCESS;
}
If you are using at least C99, then you can change
#ifndef BOOL
#define BOOL unsigned int;
#endif
to:
#include <stdint.h>
#ifndef BOOL
#define BOOL uint_fast8_t;
#endif
Related
Part of my C code 1:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
[snip!!]
#define FALSE 0
#define TRUE 1
[snip!!]
typedef int Boolean;
[snip!!]
typedef struct {
int identification ;
char name[NAMESIZE] ;
char subject[SUBJECTSIZE] ;
int grade ;
} RECORD ;
typedef struct {
char type ;
RECORD student ;
} TRANSACTION ;
typedef struct {
char occupied ;
RECORD student ;
} MASTER ;
char *prog ;
Boolean get_transaction_record(FILE *fp, TRANSACTION *transaction);
[snip!!]
void main(int argc, char *argv[])
{
FILE *fpmas,*fptrans ;
int current_key ,
relative_record_number ;
Boolean allocated;
TRANSACTION transaction;
MASTER master ;
clrscr();
prog = argv[0];
[snip!!]
else
{
get_transaction_record(fptrans, &transaction) ;
current_key = choose_next_key(transaction.student.identification);
while(current_key != TRAILER)
{
relative_record_number = do_initial_status(
current_key,&allocated, fpmas,&master);
while(current_key == transaction.student.identification)
{
apply_transaction (&allocated, &transaction,&master) ;
get_transaction_record(fptrans, &transaction);
}
do_final_status (fpmas, relative_record_number, allocated, &master);
current_key = choose_next_key(transaction.student.identification);
} //end of while
fcloseall();
} //end of else
}
Part of code 2:
Boolean get_transaction_record(FILE *fp, TRANSACTION *transaction)
{
if (fscanf (fp, "%4d%c%20s%10s%2d",
&transaction -> student. Identification,
&transaction -> type,
transaction -> student.name,
transaction -> student. Subject,
&transaction -> student. Grade) == 5)
return(TRUE);
return(FALSE);
}
How these return(); work (in the screenshot I attached) ?! I see before Boolean application like this typedef int Boolean; before. But that usage was in accompany with if() . But I do not see any if() in this code!
My main question is, how it works when the return value (TRUE or FALSE), get back to main() function'?! In main(), there is no condition evaluation to take decision about that (TRUE or FALSE) returned value. So what?
Boolean - return
First, your C learning book is largely outdated. C99 (out in 1999) allows #include <stdbool.h> that contain a bool type and true/false defines, use these instead of making your own boolean.
C and many other languages are a bit weird with boolean, if and what is true of false. In C what is 0 is false, everything else is true, hence why TRUE is defined as 1 and FALSE defined as 0 in your book. Note that comparison operators such as ==, &&, ||, ! (not to be confused with binary operators &, |, ~) returns either 1 or 0 depending of the condition.
See this example:
#include <stdio.h>
#include <stdbool.h>
bool return_the_truth(void)
{
return true; // A trivial function that returns true.
}
int main(void) {
if (2)
printf("As you see just \"2\" is true since it's different of zero\n");
if (0)
printf("That line won't be printed\n");
if (4 - 4)
printf("Neither this one since 4-4 is zero\n");
if (true == 1)
printf("true is in fact a one.\n");
if (true == 2)
printf("But merely a integer with value 1 so this line won't print.\n");
// You can invoke a function that returns a boolean and ignore it's return value.
return_the_truth();
// It is never mandatory to use the returned value. This example is absurd but perfectly valid
fopen("delete_me.txt","a"); // <- Don't forget to delete this file afterward.
if (printf("printf() return an int that is the numbers of characters printed.\n"))
printf("Hence again, this line is printed because what in the if() is not zero.");
int boolean_check_result = 42 == 40+2;
if (boolean_check_result)
printf("You can write expressions like this, there boolean_check_result is %d.\n",boolean_check_result);
printf("You can performs math with boolean, there is %d true expressions there, it works because a comparison returns 1 if true, 0 if false and we doing a sum of 1 and zeros (it's brainfuck to understand don't do that or people reviewing your code will hate you).\n",
(4 == 5) + (4 < 5) + (4 != 5) + (4 > 5) + (4 >= 5) // <- The expressions.
);
// These examples below are valid C.
5 + 6; // This sum goes to... nothing
7 == 7; // Same for this boolean, nothing will happen
printf; // Functions are kind of constants variables so that works.
// It's a non-sense, a compiler will output warnings because making computations without using the results is likely a programming error.
printf("But remind you that in the case of a function (returning a boolean or not), there might be side-effects you want and don't care about the returned value such as with this printf().\n");
}
// Did you know that you can use a `void` value ?
// The code below is perfectly valid.
// It's useful for C++ wrappers when you want to exactly mimic the behavior a library in order to catch errors.
void a_function_that_does_nothing(void)
{
}
void you_can_return_a_void(void)
{
return a_function_that_does_nothing(); // Allowed because the function return a void
}
There is tons of valid case where a returned boolean are not used inside a if().
So to answer your original question (that I might forgot while writing this answer hehe...):
how it works when the return value (TRUE or FALSE), get back to main()
function'?!
And ! 🥁 🥁 🥁 Nothing happens. The value is just lost, just like with printf() and any other functions. In the book the boolean value was an error indicator since scanf() return the number of inputs read, not 5 mean that the input was incorrect.
Not checking it is fine for learning purposes. In real-world input parsing, first don't use scanf(), then it could introduce a security vulnerability since some variables would not be written and in incorrect state and trigger unwanted behavior later that can be exploited by a malicious hacker to leak sensitive data of thousands of customers and costs millions of USD to a company (I'm barely exaggerating).
So don't be outraged when a boolean or other returned value is not used, memcpy() is a function where it's commonly sane to ignore it's return value. What is important is to understand what you are doing.
If you're still extremely angry about the fact that this boolean wasn't used and could avoid a potential security vulnerability... (I'm joking there, yet) as an exercise you can add error checking and do something useful such as printing an expressive error message telling the user that the input is incorrect and remind they what you are expecting and quit.
How could I achieve something like this ...
int main(void)
{
if (f(x) == (a || b))
{
puts("Success");
}
return (0);
}
This would print Success if the return of f(x) is equal to a or b.
I know it is possible to store it in a variable but my question is:
"Could something like this be done by calling the f(x) function only once without using a variable?"
Edit 1: I'm not allowed to use the switch statement for this assignment
Edit 2: Could I set a range with only one expression like this?
if ( 2 < f(x) < 5)
Would this be valid (return type is int)?
how to test for multiple return values from a function called once without storing into a variable (?)
Not really, but with some restrictions let us abuse C and assume a, b and f() return a character.
1Form a character array made up of a and b and search it using memchr(). Inspired by #David C. Rankin (It does not store the result of f() in a variable, but does call a function)
int main(void) {
// v-------------v compound literal
if (memchr((char [2]){a,b}, f(x), 2)) {
puts("Success");
}
return 0;
}
I see OP added "return type is int" - Oh well.
if ( 2 < f(x) < 5) is valid code, but is does not do what OP wants.
It is like if ( (2 < f(x)) < 5) which compares f(x) with 2 and results in 0 or 1, which is always less than 5.
Tough crowd tonight, so how about the below. Needs a bit of extension math for int overflow`, but is close.
abs(2*f(x) - (a+b)) == abs(a-b)
1 Not serious code suggestions for production code - use a temporary.
This can obviously be done using a switch statement. Another way would be calling a function returning true or false with the first function value as input, another way could be a jump table or even > or bit checking using binary operators depending on a and b values (very common for testing multiple bit flags at once).
But really you shouldn't care about using or not using a variable in such cases. Current compilers are quite good putting temporary variables like that in registers.
EDIT: given the constraints, the most likely solution is using some bit fu, but it fully depends of values of a and b and c, etc. The common way is using powers of two as values to check. Then you can check a set of values in only one operation.
exemple: a = 1, b = 2, c = 4
if (f(x) & (1+2+4)) {...}
checks if we have a or b or c or a superposition of these values.
C language does not such constructs. You need do save the result of the function or/and both a & b.
Of course you can:
int compare(int a, int b, int f)
{
if(a == f || b == f) { puts("Success"); return 0;}
return -1;
}
int f(int x)
{
return x * x;;
}
int main()
{
compare(5,8,f(3));
}
but of course it saves all the values as the functions parameters.
I have to do some things based on the value of a big number like 83025 (which is >65535). For this I can't use switch-case since it uses only integral arguments of a max value of 255. (Or at least this is how I know. I still tried however and it compiled but the switch-case did not work well.)
So I thought I would make an if-else if ladder like this below but it seems not too elegant.
if ((refnum == 32120) ||
(refnum == 32075)) {
else if (refnum == 51036) {
else if ((refnum == 61024) ||
(refnum == 61060)) {
else if ((refnum == 71030) ||
(refnum == 71048)) {
else if ((refnum == 72012) ||
(refnum == 72024) ||
(refnum == 72048)) {
else if ((refnum == 81025) ||
(refnum == 81050) ||
(refnum == 81100)) {
else if ((refnum == 82012) ||
(refnum == 82024) ||
(refnum == 82048) ||
(refnum == 82096)) {
else if ((refnum == 83050) ||
(refnum == 83100)) {
Can you confirm that this is the proper way to do this? Or do you have a better idea?
Additional info:
refnum is a 32bit unsigned integer
the big number comes from the middle of a string and strtol converts it to a DWORD
the things i have to do in each case is to perform a strcpy and then return a certain value.
the code is embedded and runs on a 16 bit microcontroller
have to do some things based on the value of a big number like 83025
Then make sure that all variables involved use uint32_t.
For this I can't use switch-case since it uses only integral arguments of a max value of 255
This is a misunderstanding, not sure where you got this idea from. The switch statement works on all integer constant expressions. There's no numerical limits in the switch statement itself.
(In fact the controlling expression of a switch statement is implicitly promoted to type int, if it happens to be a smaller integer type.)
So I thought I would make an if-else if ladder like this below but it seems not too elegant. Can you confirm that this is the proper way to do this? Or do you have a better idea?
The if-else will likley yield the very same machine code as a corresponding switch. The switch might increase readability a bit and is therefore perhaps a better choice:
switch (refnum)
{
case 32120: do_this(); break;
case 61024: do_that(); break;
...
default: do_something();
}
Alternative:
I notice that these are integer values in sorted order. If there are lots of values or if fast look-up is required, you could also replace the whole thing with a binary search. This will possibly give faster code but also increase complexity. Preferably, use C standard bsearch().
However, if what you wish to achieve in the end is to return a pointer to a string, this solution might be ideal. You could then store the numbers and strings as key-value pairs:
typedef struct
{
uint32_t key;
const char* str;
} thingie_t;
static const thingie_t things [] =
{
{ 32120, "text string" },
{ 32075, "another text string" },
...
};
the big number comes from the middle of a string and strtol converts it to a DWORD
Why are you using signed numbers? The data does not seem to be signed. What is DWORD? That's some smelly type from Windows programming, which should definitely be avoided in embedded systems. Use the types from stdint.h, not some ugly, home-made types.
I have to do some things based on the value of a big number like 83025 (which is >65535). For this I can't use switch-case since it uses only integral arguments of a max value of 255. (Or at least this is how I know).
Your understanding is incorrect: here is the wording of the C Standard:
6.8.4.2 The switch statement
The controlling expression of a switch statement shall have integer type.
[...] The expression of each case label shall be an integer constant expression and no two of the case constant expressions in the same switch statement shall have the same value after conversion. [...]
The integer promotions are performed on the controlling expression. The constant expression in each case label is converted to the promoted type of the controlling expression. If a converted value matches that of the promoted controlling expression, control jumps to the statement following the matched case label. [...]
Thus there is no limit at 65535 for the case values in general, the maximum value is at least 18446744073709551615 if the switch expression has type unsigned long long. If your switch expression is an unsigned int and your target platform had 16-bit ints, then the maximum value for a case expression would be 65535 but given the values you want to test, refnum's type must be a larger than that.
I still tried however and it compiled but the switch-case did not work well.
You did not post the offending code... Unless your compiler is ancient or seriously broken, the problem is not where you suspect, more likely a bug in your code.
EDIT from the extra information provided, the target platform indeed has 16-bit int, but refnum must be larger than int or unsigned int to accommodate for values larger than 65535, either a long or an unsigned long. The compiler should then accept case values larger than 65535. Ancient compilers may not be compliant with this... in this case, you will probably have many more problems to deal with.
Switch statement can do the job for you in this case.
switch (refnum) {
case 0:
case 1:
//Do stuff when refnum is 0 or 1
break;
case 2:
//Do stuff when refnum is 2
break;
case 36371:
case 36372:
case 36373:
case 36374:
// if (refnum == 36371 || refnum == 36372 || refnum == 36373 || refnum == 36374)
break;
default: break;
}
Beauty is that you can apply multiple case statements (like case 0 and case 1 in my case) which acts like or in your if statement.
GCC extension also allows you to write your switch this way:
switch (refnum) {
case 36371 ... 36374:
//Do the job when refnum is >= 36371 && refnum <= 36374
break;
}
But remember! This is not available in all compilers.
You appear to have a very restrictive non-standard compiler.
You could create a function for each action then generate a lookup-table of refnum to function-pointer and scan that. For example:
int action1( unsigned long refnum ) ;
int action2( unsigned long refnum ) ;
int action3( unsigned long refnum ) ;
int action4( unsigned long refnum ) ;
int action5( unsigned long refnum ) ;
...
int action8( (unsigned long ) ;
int doRefnumAction( unsigned long refnum )
{
typedef void(*refnumFn)(unsigned long ) ;
static const struct
{
unsigned long refnum,
refnumFn refnum_action
} refnum_lookup[] = { {32120, action1}, {32075, action1},
{51036, action2},
...
{82012, action7}, {82024, action7}, {82048, action7}, {82096, , action7},
{83050, action8}, {83100, action8} } ;
// Find refnum in lookup and call action...
for( int i = 0 ;
i < sizeof(refnum_lookup) / sizeof(*refnum_lookup) ;
i++ )
{
if( refnum == refnum_lookup[i].refnum )
{
return refnum_lookup[i].refnum_action( refnum ) ;
}
}
}
Whether that is better in any way that the if-else if solution is perhaps a matter of opinion, probably larger in code-space terms, and slower in execution but arguably more easily maintained.
Once we know details of your compiler and your real code, we can find out why you feel you cannot use a switch statement. Until then, everyone is just guessing.
I have used a large number of C compilers over the years, and never heard of one that restricts switches in this way. It sounds like the kind of pseudo-C compilers that existed for 8-bit microcontrollers in the 1990's - not something you would see today.
If you are using a decent compiler, and have optimisation enabled, then a switch will be the fastest way. Someone mentioned binary searches as a more complex but faster solution - a good compiler will generate a jump table or a binary search automatically from a switch statement to give you the most efficient code.
You could create a global array with all your values to check. And simply loop trought this array. If you need a specific behavior for each else if you could create an array of struct and use function pointer to set a different behavior.
Here's an example :
// For int variables
#include <stdint.h>
// For printf
#include <stdio.h>
#define VALUE_TO_GUESS 3
#define NB_VALUES 4
#define MY_VALUE_1 1
#define MY_VALUE_2 2
#define MY_VALUE_3 3
#define MY_VALUE_4 4
void behavior_1(void) {
printf("Behavior 1 !\n");
}
void behavior_2(void) {
printf("Behavior 2 !\n");
}
void behavior_3(void) {
printf("Behavior 3 !\n");
}
void behavior_4(void) {
printf("Behavior 4 !\n");
}
// Definition of the struct using a function pointer
typedef struct s_compare {
uint32_t value_to_compare;
void (*ptr)(void);
}t_compare;
// Setting up my struct
t_compare g_compare[] = {
{MY_VALUE_1, behavior_1},
{MY_VALUE_2, behavior_2},
{MY_VALUE_3, behavior_3},
{MY_VALUE_4, behavior_4}
};
int main(void) {
for (int i = 0; i < NB_VALUES; i++) {
/* If your current value match the value set in the current struct
then call the function pointer associated, with these 2 lines i can
compare an infinite quantity of numbers */
if (g_compare[i].value_to_compare == VALUE_TO_GUESS) {
g_compare[i].ptr();
}
}
}
Feel free to tell me if you need some explanations about this one.
This need a bit of setup but its a powerful solution to your problem and a more elegant solution than a tree of if / else / else if.
Why am I getting the answer "odd" instead of "even"?
#include<stdio.h>
#define ODD(x) x%2?0:1
int main()
{
int a=5;
if(ODD(a+1))
printf("even");
else
printf("odd");
return 0;
}
ODD(a+1) expands to a+1%2?0:1. With a as 5, that is same as (5+(1%2))?0:1 or 0.
% beats + which beats ?:
if(0)
printf("even");
else
printf("odd"); // print `odd`
Perhaps you wanted some () to insure evaluation order.
// #define ODD(x) x%2?0:1
#define ODD(x) ((x)%2?0:1)
Yet that seems backwards. How about
#define ISODD(x) ((x)%2 != 0)
See How do I check if an integer is even or odd?
1 is treated as true and 0 as false.
if (1) is executed always, and when you get 0 as result, the branch shifts to else
so code should be :
if ODD is true (returning 1 from terneray expression), print "odd"
#define ODD(x) x % 2 ? 0 : 1
Given an even number x, x % 2 will give you zero, which is false.
Hence the result of the entire ternary expression will be the second option 1, which is true.
You would be better off with something like:
#define ODD(x) (((x) % 2) != 0)
It's both more readable in intent, and less prone to errors such as getting the true/false values mixed up, or being burnt by simple text substitution having unexpected effects.
I do not like this kind if macros for many reasons (one of it that they can be a source of silly errors - like in your case). It should be domain of functions.
int ODD(int x)
{
return x & 1;
}
if you are worried about function call overhead just make it inline (but on any level op optimisation the compiler will inline it anyway as the call is probably longer than the function itself.
A friend of mine jokingly asked me this question. It was meant to be a "goes without saying" type remark, but then I actually thought about it for a while and started coming up with some clever "almost solutions".
First attempt:
If C ever supports quantum computing there may be an answer to this. A q-bit can be in many states at once, so it could be false AND true and this conditional will return (BOOL)0.5 aka "Yes/no/maybe-so" - but once you observe the variable the whole thing will collapse and become invalid again.
Second attempt:
If X could somehow be defined as a random binary generator and you cast it to a BOOL you could get false some of the time. I'm not sure if you can do this though in C unless you use CLANG. #define x (BOOL)!!(rand()%2)
The language we were discussing this in is C but I'm also curious if anyone can find any solutions in any language.
When x is volatile (volatile int x) and is modified by an external thread / device, the expression can be false.
It's a bit of a trick, but the following solution also works:
#define x 1 ? 0 : 1
(x || !x)
The reason is in the operator precedence. After preprocessing (x || !x) resolves to the following (parentheses added to show the precedence):
(1 ? 0 : (1 || !1) ? 0 : 1)
Macros are really cheating here, but you don't need anything to do with boolean types or special compilers. The following, as far as I know, is legal standard C.
#include <stdio.h>
int f(void) {
static int y = 0;
if (y == 0) {
y = 1;
return 0;
} else {
return 1;
}
}
#define x f()
int main(void) {
if (x || !x) {
puts("It was true");
} else {
puts("It was false");
}
return 0;
}
Or even more concisely:
int y = 0;
#define x y++
(For those worried about undefined behavior, note there is a sequence point between the left and right side of ||.)
An even simpler macro:
#define x 0&0
expanding (x || !x) gives (0 & 0 || !0 & 0) which is always false.
Similarly:
#define x 0*0
#define x 1*0 // for binary buffs
#define x 4&2 // for HHGG fans.
I could not find a 2 letter macro :(
Tried in JS:
var i = 0
i++ || !(i++)
Note: this solution works only when i = 0