What is the proper equivalent of "while(true)" in plain C? - c

Since C doesn't have bools, what is the proper variable to put in place of true in an algorithm that uses
do
{
// ...
} while(true);
???
Should a proper C programmer do
do
{
// ...
} while(1);
or is there a specific variable reserved to mean "something that is not zero/NULL" ?

Usually nowadays I see
while(1) {
...
}
It used to be common to see
for(;;) {
...
}
It all gets the point across.

Your question isn't really about bool (which modern C does have if you #include <stdbool.h>), it's about the best way to write an infinite loop.
Common idioms are:
while (1) {
/* ... */
}
and
for (;;) {
/* ... */
}
The latter looks a little obscure, but it's well-defined. Any of the three expressions in a for loop header can be omitted; if the second expression, which controls when the loop continues to execute, is omitted, it defaults to true.
while (1) is probably the most straightforward method -- but some some compilers might warn about a condition that's always true. for (;;) likely avoids that, since there is no (explicit) expression to warn about.
I personally wouldn't use a do/while loop, because the condition is at the bottom.
There are trickier ways to write an infinite loop (while (1 + 1 == 2) et al, but none of them are really worth the effort.
Either while (1) or for (;;) will be perfectly clear to anyone with a good understanding of C.

If you're using c89:
Create a boolean definition:
typedef int bool;
#define true 1
#define false 0
Or constants:
/* Boolean constants. */
#define TRUE 1
#define FALSE 0
This gives the int a meaning for you.
Or (as mentioned elsewhere here) if using c99:
#include <stdbool.h>
My experience of universities lately, is they require you to use c89.
http://en.wikipedia.org/wiki/C_data_types#stdbool.h

C has stbool.h header file to use bool variables.
So this works
#include <stdio.h>
#include<stdbool.h>
int main(void) {
int i=1;
while(true)
{
if(i==3){
break;
}
printf("%d\n",i);
i++;
}
return 0;
}
Output
1
2
note:Modern C99 has support for bool variables but C89/90 does not have.
If you are using C89/90 then you can use typedef or constants as mentioned in one of the answers here or you can use enums as well like this
typedef enum {false, true } bool;
bool b=true;
int i=1;
while(b)
{
if(i==3){
break;
}
printf("%d\n",i);
i++;
}
output
1
2
You can check this bool in C
Hope it helps you.

Related

Ambiguity about Boolean functions in C

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.

C macros using enum

I am trying to use #if macros by defining the type of operation to invoke the right code, So i made a very simple example similar to what I am trying to do:
#include <stdio.h>
enum{ADD,SUB,MUL};
#define operation ADD
int main()
{
int a = 4;
int b = 2;
int c;
#if (operation == ADD)
c = a+b;
#endif
#if (operation == SUB)
c = a-b;
#endif
#if (operation == MUL)
c = a*b;
#endif
printf("result = %i",c);
return 0;
}
But unfortunately that does not work I get the following result = 8... if I replace The operation with numbers it works fine .... But i want it to work as it is described above.
Any help
The preprocessor is a step that is (in a way) done before the actual compiler sees the code. Therefore it has no idea about enumerations or their values, as they are set during compilation which happens after preprocessing.
You simply can't use preprocessor conditional compilation using enumerations.
The preprocessor will always consider that as false:
#if IDENT == IDENT
It can only test for numeric values.
Simplify your code and feed it to the preprocessor:
enum {ADD,SUB,MUL};
#define operation ADD
int main()
{
(operation == ADD);
}
The result of the preprocessor output is:
enum {ADD,SUB,MUL};
int main()
{
(ADD == ADD);
}
As you see, the enumerate value hasn't been evaluated. In the #if statement, that expression is just seen as false.
So a workaround would be to replace your enumerate by a series of #define:
#define ADD 1
#define SUB 2
#define MUL 3
like this it works. Output of preprocessor output is now:
int main()
{
int a = 4;
int b = 2;
int c;
c = a+b;
# 28 "test.c"
printf("result = %i",c);
return 0;
}
the solution is:
either rely at 100% on the preprocessor (as the solution above suggests)
or rely at 100% on the compiler (use enums and real if statements)
As others have said, the preprocessor performs its transformations at a very early phase in compilation, before enum values are known. So you can't do this test in #if.
However, you can just use an ordinary if statement. Any decent compiler with optimization enabled will detect that you're comparing constants, perform the tests at compile time, and throw out the code that will never be executed. So you'll get the same result that you were trying to achieve with #if.
But i want it to work as it is described above.
You seem to mean that you want the preprocessor to recognize the enum constants as such, and to evaluate the == expressions in that light. I'm afraid you're out of luck.
The preprocessor knows nothing about enums. It operates on a mostly-raw stream of tokens and whitespace. When it evaluates a directive such as
#if (operation == SUB)
it first performs macro expansion to produce
#if (ADD == SUB)
. Then it must somehow convert the tokens ADD and SUB to numbers, but, again, it knows nothing about enums or the C significance of the preceding code. Its rule for interpreting such symbols as numbers is simple: it replaces each with 0. The result is that all three preprocessor conditionals in your code will always evaluate to true.
If you want the preprocessor to do this then you need to define the symbols to the preprocessor. Since you're not otherwise using the enum, you might as well just replace it altogether with
#define ADD 1
#define SUB 2
#define MUL 3
If you want the enum, too, then just use different symbols with the preprocessor than you use for the enum constants. You can use the same or different values, as you like, because never the twain shall meet.
Another solution would be to have the enum in an included header file.

C preprocessor conditional statement output

I have this code but not able to understand the output. Can someone help out to know the behaviour
#include<stdio.h>
int main(){
int a =1;
#if(a==0)
printf("equal");
#else if
printf("unequal");
#endif
return -1;
}
Output comes out to be equal. Strange for me.
Also if i change the if condition to a==2, the output comes unequal
If i try to print value of 'a' inside 'if' block something like
#if(a==0)
printf("value of a: %d",a);
output comes out to be value of a: 1
Please some one explain the output.
The a in the preprocessor directive refers to preprocessor definitions, not variables in your program. Since a is not #defined, its value is effectively 0 for the purposes of #if.
The preprocessor directives (the lines starting with #) are dealt with at compile time, not at runtime. The a in that #if is not the same as the a variable you declared. The preprocessor just replaces it with 0, since there is no #define a statement anywhere. The variable a is unused in your program. If you do use it, like in the printf statement you show, it will get printed as expected - a value of 1 that you assigned to it.
#include<stdio.h>
int main(){
int a =1;
#if(a==0)
printf("equal");
#else if
printf("unequal");
#endif
return -1;
}
which you pass to the compiler will first go through the preprocessor whose output is then sent as an input to the compiler; the preprocessor will send
#include<stdio.h>
int main(){
int a =1;
printf("equal");
return -1;
}
to the compiler, which is the reason you see equal always. The reason is since a as a macro is undefined, the first condition is true, there by leading to only passing that statement on to the compiler. If you try adding #define a 1 next to the include directive, then you'll always see unequal as an output; but these changes affect only the compile time macro a and not the runtime variable a (both are entirely different).
All this because preprocessor is concerned only with compile-time constructs. What you really need may be
#include<stdio.h>
int main(){
int a =1;
if(a == 0)
printf("equal");
else
printf("unequal");
return 0;
}
Aside: Return 0 when you're program is successful, returning negative values from main usually means some error state termination of your program.

Cannot return bool from function

This is the piece of code in base C:
static bool is_ascii_value_of_digit(char ascii_value){
if((ascii_value<40)&&(ascii_value >= 30)){
return true;
}
return false;
}
The avr studio gcc compiler is giving me error :
../calculator.h:4: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'is_ascii_value_of_digit'
Similar errors are also evident in other functions. I do not know why this is happening. Spent an hour figuring out why and finally gave up. As far as I have seen online, my syntax is not the problem. Probably something that I am overlooking.
Question RESOLVED !
Thank you very much for your quick help as it saved me a lot of time. I was under the assumption that bool is a keyword in c.
You probably have just forgotten to #include <stdbool.h>.
However, you have a mismatch between name and behaviour of your function,
if((ascii_value<40)&&(ascii_value >= 30))
the decimal digits, 0-9, occupy the places 48-57 in the ASCII table, that's hexadecimal 0x30-0x39, so to match the name, you should test
if (ascii_value < 0x3A && ascii_value >= 0x30)
C does not have bool type, neither true or false. Use int and 0/1 values instead.
If your compiler supports, at least partially, the C99 standard (or C11, but that's not yet likely), add
#include <stdbool.h>
to the top of your source file to make bool, false, and true visible.
If it doesn't (Microsoft's support for C99 is not good), a workaround is:
typedef enum { false, true } bool;
This doesn't quite match the semantics of C99's bool (actually _Bool) type, but it's probably close enough.
Incidentally, you don't need an if/else statement in your function:
static bool is_ascii_value_of_digit(char ascii_value) {
return ascii_value >= '0' && ascii_value <= '9';
}
bool values are values, and they can be stored and returned from functions just like any other values.
Another guideline: Don't compare boolean values to true or false, just test them directly. In a condition (such as in an if statement), any non-zero value is considered true, so this:
if (cond == true) ...
can fail if cond has non-zero value other than 1. Just write:
if (cond) ...
or, to test whether it's false:
if (!cond) ...
Recommended reading: section 9 of the comp.lang.c FAQ. (Further recommended reading: all the rest of the sections.)
According to http://computer.howstuffworks.com/c11.htm
i used it many years ago
#define True 1
#define False 0
typedef int boolean;
void main(void)
{
boolean b;
b=False;
if(!b) printf("false");
}
In codepad output is false
http://codepad.org/iWKiFHFA

Is there any standard way to use boolean? because my code is giving an error

#include<stdio.h>
boolean ch(char x)
{
if(x>=48&&x<=57)
return 1;
else
return 0;
}
main()
{
if(!ch('t'))
printf("it's a character");
}
error:
cha.c:3: error: boolean' does not name a type
cha.c: In functionint main()':
cha.c:15: error: `ch' was not declared in this scope
Yes, the C99 standard has introduced the _Bool type
Update
Apparently <stdbool.h> also includes the prettier bool type in addition to the true and false macros. Updated code to reflect this.
#include <stdio.h>
#include <stdbool.h>
bool ch(int);
int main(void)
{
if(!ch('t'))
printf("it's a character\n");
return 0;
}
bool ch(int x)
{
if (x >= 48 && x <= 57)
return true;
else
return false;
}
Click this link to see the compiled code's output
And googling wins again
Boolean Expressions and Variables : What is the right type to use for Boolean values in C? Is there a standard type? Should I use #defines or enums for the true and false values?
Unless I'm crazy, C doesn't have a boolean type. Change the return type of ch to int
Also, post your error message.
C does not have a built-in boolean type. A bool type is available in the stdbool.h header in the standard library in C99.
http://en.wikipedia.org/wiki/Stdbool.h
You've got more problems than just the type, however. if(x>=48&&x<=57) doesn't mean what you think it does, and your printf is going to give you unexpected results too.
You're going to need these characters: "(())\n" and a bunch of whitespace.
Sorry to be a little cryptic but this looks like a homework problem.
The conditional statement if (boolean_expression) return true; else return false; can always be replaced by return boolean_expression; which I find a lot more readable.
Also, your naming is terrible, what does ch stand for? Since 48 is 0 and 47 is 9, a better name would probably be is_digit or something. (And, as others have noted, C89 does not have a boolean type.)
int is_digit(char c)
{
return (c >= '0') && (c <= '9');
}
The parenthesis are optional, but I think they make the code more readable.
And what do you mean by the output "It's a character" in main? Every char is a character, duh :)

Resources