Skip to content

Commit f25caad

Browse files
committed
[c/en] Fixed mistakes & added clarifications regarding the C standard
* Reference to C23 `constexpr` constants * Note on `long long` only being supported since C99 * Clarification about the `_Bool`/`bool` type in section on comparisons * Fixed incorrect explanation about null statements * Replaced boolean typedef, which in it's original form would not compile when using the C23 standard (which is due to become the default for gcc) * Updated outdated information on binary literals * Added `%b` binary conversion specifier
1 parent ca117e4 commit f25caad

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

c.md

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ contributors:
1111
- ["Joshua Li", "https://github.com/JoshuaRLi"]
1212
- ["Dragos B. Chirila", "https://github.com/dchirila"]
1313
- ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"]
14+
- ["Mykolas Bamberg", "https://github.com/MykBamberg"]
1415
---
1516

1617
Ah, C. Still **the** language of modern high-performance computing.
@@ -33,6 +34,9 @@ Multi-line comments don't nest /* Be careful */ // comment ends on this line...
3334
// Constants: #define <keyword>
3435
// Constants are written in all-caps out of convention, not requirement
3536
#define DAYS_IN_YEAR 365
37+
// Since C23 it is also possible to define constants using the constexpr keyword
38+
// which gives you the ability to easily specify the type of the constant
39+
constexpr int DAYS_IN_YEAR = 365;
3640

3741
// Enumeration constants are also ways to declare constants.
3842
// All statements must end with a semicolon
@@ -119,8 +123,8 @@ int main (int argc, char** argv)
119123
char x_char = 0;
120124
char y_char = 'y'; // Char literals are quoted with ''
121125

122-
// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
123-
// 8 bytes
126+
// longs are often 4 to 8 bytes; long longs (added in C99) are guaranteed to
127+
// be at least 8 bytes
124128
long x_long = 0;
125129
long long x_long_long = 0;
126130

@@ -191,7 +195,7 @@ int main (int argc, char** argv)
191195
// time constant:
192196
printf("Enter the array size: "); // ask the user for an array size
193197
int array_size;
194-
fscanf(stdin, "%d", &array_size);
198+
scanf("%d", &array_size);
195199
int var_length_array[array_size]; // declare the VLA
196200
printf("sizeof array = %zu\n", sizeof var_length_array);
197201

@@ -265,11 +269,10 @@ int main (int argc, char** argv)
265269
(-11) % 3; // => -2, as one would expect
266270
11 % (-3); // => 2 and not -2, and it's quite counter intuitive
267271

268-
// Comparison operators are probably familiar, but
269-
// there is no Boolean type in C. We use ints instead.
270-
// (C99 introduced the _Bool type provided in stdbool.h)
271-
// 0 is false, anything else is true. (The comparison
272-
// operators always yield 0 or 1.)
272+
// Comparison operators are probably familiar. However, instead of the
273+
// result being of a Boolean type (introduced as _Bool in the C99 standard
274+
// and called bool since C23) it is represented by an int, 0 is the value
275+
// of a false statement and 1 is the value of a true statement.
273276
3 == 2; // => 0 (false)
274277
3 != 2; // => 1 (true)
275278
3 > 2; // => 1
@@ -358,11 +361,9 @@ int main (int argc, char** argv)
358361
// *****NOTES*****:
359362
// Loops and Functions MUST have a body. If no body is needed:
360363
int i;
361-
for (i = 0; i <= 5; i++) {
362-
; // use semicolon to act as the body (null statement)
363-
}
364+
for (i = 0; i <= 5; i++) {} // use an empty compound statement
364365
// Or
365-
for (i = 0; i <= 5; i++);
366+
for (i = 0; i <= 5; i++); // use semicolon to act as the body (null statement)
366367

367368
// branching with multiple choices: switch()
368369
switch (a) {
@@ -387,15 +388,15 @@ int main (int argc, char** argv)
387388
/*
388389
Using "goto" in C
389390
*/
390-
typedef enum { false, true } bool;
391+
typedef enum { FALSE, TRUE } boolean;
391392
// for C don't have bool as data type before C99 :(
392-
bool disaster = false;
393+
boolean disaster = FALSE;
393394
int i, j;
394395
for(i=0; i<100; ++i)
395396
for(j=0; j<100; ++j)
396397
{
397398
if((i + j) >= 150)
398-
disaster = true;
399+
disaster = TRUE;
399400
if(disaster)
400401
goto error; // exit both for loops
401402
}
@@ -418,9 +419,11 @@ int main (int argc, char** argv)
418419
// Every value in C has a type, but you can cast one value into another type
419420
// if you want (with some constraints).
420421

421-
int x_hex = 0x01; // You can assign vars with hex literals
422-
// binary is not in the standard, but allowed by some
423-
// compilers (x_bin = 0b0010010110)
422+
// You can assign variables with hex literals.
423+
int x_hex = 0x01;
424+
// Binary literals were introduced in the C23 standard, however most
425+
// compilers already supported them beforehand
426+
int x_bin = 0b0010010110;
424427

425428
// Casting between types will attempt to preserve their numeric values
426429
printf("%d\n", x_hex); // => Prints 1
@@ -813,6 +816,7 @@ typedef void (*my_fnp_type)(char *);
813816
// it as an argument to `printf`.
814817
"%x"; // hexadecimal
815818
"%o"; // octal
819+
"%b"; // binary (only supported since C23)
816820
"%%"; // prints %
817821
*/
818822

0 commit comments

Comments
 (0)