mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-16 03:34:53 +02:00
[c/en] mostly word clarification and extra descriptions (#4222)
* Adds extra clarity to enum value assignment. The previous statement shows only 1 way to declare enums, and it happens that they specify a starting value. I clarify that a starting value is not necessary and that all enum value could contain user specified values. * Added clarity to `includes` section. specified that angle brackets are for system libraries and not just standard libs. I also added an example of relative paths in the local include statements. * Added more clarity for function prototyping and main return vals. I cleaned up some formatting; then added some clarity to how function prototyping works, as well as recommend techniques. * Fixed the mention of character sizes. they are not always 1 byte * Added clarity about floating point arithmetic. The previous comments on floating points made it feel like there was something broken with doing comparison and arithmetics with floating point types. I added clarity about how floats are stored in memory and why they seem to behave strangly when used in arithmetic expressions. * reworded boolean stuff for better clarity on _Bool type in C99 * Adds not about binary assignment * Added clarity for value roll over * Added section on multiple return values. C doesnt allow returning of multiple values, so i added a section on returning multiple values through pointers. * added section break for printing special characters * fix typo Co-authored-by: Andre Polykanine <ap@oire.me> * fix typos Co-authored-by: Andre Polykanine <ap@oire.me> * fix markdown syntax Co-authored-by: Andre Polykanine <ap@oire.me> * fix markdown syntax Co-authored-by: Andre Polykanine <ap@oire.me> * fix markdown syntax Co-authored-by: Andre Polykanine <ap@oire.me> * reword with better english Co-authored-by: Andre Polykanine <ap@oire.me> * reword with better english Co-authored-by: Andre Polykanine <ap@oire.me> Co-authored-by: Andre Polykanine <ap@oire.me>
This commit is contained in:
@@ -46,31 +46,47 @@ Multi-line comments don't nest /* Be careful */ // comment ends on this line...
|
|||||||
|
|
||||||
// Enumeration constants are also ways to declare constants.
|
// Enumeration constants are also ways to declare constants.
|
||||||
// All statements must end with a semicolon
|
// All statements must end with a semicolon
|
||||||
enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
|
enum days {SUN, MON, TUE, WED, THU, FRI, SAT};
|
||||||
|
// SUN gets 0, MON gets 1, TUE gets 2, etc.
|
||||||
|
|
||||||
|
// Enumeration values can also be specified
|
||||||
|
enum days {SUN = 1, MON, TUE, WED = 99, THU, FRI, SAT};
|
||||||
// MON gets 2 automatically, TUE gets 3, etc.
|
// MON gets 2 automatically, TUE gets 3, etc.
|
||||||
|
// WED get 99, THU gets 100, FRI gets 101, etc.
|
||||||
|
|
||||||
// Import headers with #include
|
// Import headers with #include
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// (File names between <angle brackets> are headers from the C standard library.)
|
// File names between <angle brackets> tell the compiler to look in your system
|
||||||
// For your own headers, use double quotes instead of angle brackets:
|
// libraries for the headers.
|
||||||
//#include "my_header.h"
|
// For your own headers, use double quotes instead of angle brackets, and
|
||||||
|
// provide the path:
|
||||||
|
#include "my_header.h" // local file
|
||||||
|
#include "../my_lib/my_lib_header.h" //relative path
|
||||||
|
|
||||||
// Declare function signatures in advance in a .h file, or at the top of
|
// Declare function signatures in advance in a .h file, or at the top of
|
||||||
// your .c file.
|
// your .c file.
|
||||||
void function_1();
|
void function_1();
|
||||||
int function_2(void);
|
int function_2(void);
|
||||||
|
|
||||||
// Must declare a 'function prototype' before main() when functions occur after
|
// At a minimum, you must declare a 'function prototype' before its use in any function.
|
||||||
// your main() function.
|
// Normally, prototypes are placed at the top of a file before any function definition.
|
||||||
int add_two_ints(int x1, int x2); // function prototype
|
int add_two_ints(int x1, int x2); // function prototype
|
||||||
// although `int add_two_ints(int, int);` is also valid (no need to name the args),
|
// although `int add_two_ints(int, int);` is also valid (no need to name the args),
|
||||||
// it is recommended to name arguments in the prototype as well for easier inspection
|
// it is recommended to name arguments in the prototype as well for easier inspection
|
||||||
|
|
||||||
// Your program's entry point is a function called
|
// Function prototypes are not necessary if the function definition comes before
|
||||||
// main with an integer return type.
|
// any other function that calls that function. However, it's standard practice to
|
||||||
|
// always add the function prototype to a header file (*.h) and then #include that
|
||||||
|
// file at the top. This prevents any issues where a function might be called
|
||||||
|
// before the compiler knows of its existence, while also giving the developer a
|
||||||
|
// clean header file to share with the rest of the project.
|
||||||
|
|
||||||
|
// Your program's entry point is a function called "main". The return type can
|
||||||
|
// be anything, however most operating systems expect a return type of `int` for
|
||||||
|
// error code processing.
|
||||||
int main(void) {
|
int main(void) {
|
||||||
// your program
|
// your program
|
||||||
}
|
}
|
||||||
@@ -96,13 +112,14 @@ int main (int argc, char** argv)
|
|||||||
// For the sake of the tutorial, variables are declared dynamically under
|
// For the sake of the tutorial, variables are declared dynamically under
|
||||||
// C99-compliant standards.
|
// C99-compliant standards.
|
||||||
|
|
||||||
// ints are usually 4 bytes
|
// ints are usually 4 bytes (use the `sizeof` operator to check)
|
||||||
int x_int = 0;
|
int x_int = 0;
|
||||||
|
|
||||||
// shorts are usually 2 bytes
|
// shorts are usually 2 bytes (use the `sizeof` operator to check)
|
||||||
short x_short = 0;
|
short x_short = 0;
|
||||||
|
|
||||||
// chars are guaranteed to be 1 byte
|
// chars are defined as the smallest addressable unit for a processor.
|
||||||
|
// This is usually 1 byte, but for some systems it can be more (ex. for TMS320 from TI it's 2 bytes).
|
||||||
char x_char = 0;
|
char x_char = 0;
|
||||||
char y_char = 'y'; // Char literals are quoted with ''
|
char y_char = 'y'; // Char literals are quoted with ''
|
||||||
|
|
||||||
@@ -225,13 +242,22 @@ int main (int argc, char** argv)
|
|||||||
i1 / (double)i2; // => 0.5 // Same with double
|
i1 / (double)i2; // => 0.5 // Same with double
|
||||||
f1 / f2; // => 0.5, plus or minus epsilon
|
f1 / f2; // => 0.5, plus or minus epsilon
|
||||||
|
|
||||||
// Floating-point numbers and calculations are not exact
|
// Floating-point numbers are defined by IEEE 754, thus cannot store perfectly
|
||||||
// for instance it is not giving mathematically correct results
|
// exact values. For instance, the following does not produce expected results
|
||||||
|
// because 0.1 might actually be 0.099999999999 insided the computer, and 0.3
|
||||||
|
// might be stored as 0.300000000001.
|
||||||
(0.1 + 0.1 + 0.1) != 0.3; // => 1 (true)
|
(0.1 + 0.1 + 0.1) != 0.3; // => 1 (true)
|
||||||
// and it is NOT associative
|
// and it is NOT associative due to reasons mentioned above.
|
||||||
1 + (1e123 - 1e123) != (1 + 1e123) - 1e123; // => 1 (true)
|
1 + (1e123 - 1e123) != (1 + 1e123) - 1e123; // => 1 (true)
|
||||||
// this notation is scientific notations for numbers: 1e123 = 1*10^123
|
// this notation is scientific notations for numbers: 1e123 = 1*10^123
|
||||||
|
|
||||||
|
// It is important to note that most all systems have used IEEE 754 to
|
||||||
|
// represent floating points. Even python, used for scientific computing,
|
||||||
|
// eventually calls C which uses IEEE 754. It is mentioned this way not to
|
||||||
|
// indicate that this is a poor implementation, but instead as a warning
|
||||||
|
// that when doing floating point comparisons, a little bit of error (epsilon)
|
||||||
|
// needs to be considered.
|
||||||
|
|
||||||
// Modulo is there as well, but be careful if arguments are negative
|
// Modulo is there as well, but be careful if arguments are negative
|
||||||
11 % 3; // => 2 as 11 = 2 + 3*x (x=3)
|
11 % 3; // => 2 as 11 = 2 + 3*x (x=3)
|
||||||
(-11) % 3; // => -2, as one would expect
|
(-11) % 3; // => -2, as one would expect
|
||||||
@@ -239,7 +265,7 @@ int main (int argc, char** argv)
|
|||||||
|
|
||||||
// Comparison operators are probably familiar, but
|
// Comparison operators are probably familiar, but
|
||||||
// there is no Boolean type in C. We use ints instead.
|
// there is no Boolean type in C. We use ints instead.
|
||||||
// (Or _Bool or bool in C99.)
|
// (C99 introduced the _Bool type provided in stdbool.h)
|
||||||
// 0 is false, anything else is true. (The comparison
|
// 0 is false, anything else is true. (The comparison
|
||||||
// operators always yield 0 or 1.)
|
// operators always yield 0 or 1.)
|
||||||
3 == 2; // => 0 (false)
|
3 == 2; // => 0 (false)
|
||||||
@@ -391,13 +417,16 @@ int main (int argc, char** argv)
|
|||||||
// if you want (with some constraints).
|
// if you want (with some constraints).
|
||||||
|
|
||||||
int x_hex = 0x01; // You can assign vars with hex literals
|
int x_hex = 0x01; // You can assign vars with hex literals
|
||||||
|
// binary is not in the standard, but allowed by some
|
||||||
|
// compilers (x_bin = 0b0010010110)
|
||||||
|
|
||||||
// Casting between types will attempt to preserve their numeric values
|
// Casting between types will attempt to preserve their numeric values
|
||||||
printf("%d\n", x_hex); // => Prints 1
|
printf("%d\n", x_hex); // => Prints 1
|
||||||
printf("%d\n", (short) x_hex); // => Prints 1
|
printf("%d\n", (short) x_hex); // => Prints 1
|
||||||
printf("%d\n", (char) x_hex); // => Prints 1
|
printf("%d\n", (char) x_hex); // => Prints 1
|
||||||
|
|
||||||
// Types will overflow without warning
|
// If you assign a value greater than a types max val, it will rollover
|
||||||
|
// without warning.
|
||||||
printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
|
printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
|
||||||
|
|
||||||
// For determining the max value of a `char`, a `signed char` and an `unsigned char`,
|
// For determining the max value of a `char`, a `signed char` and an `unsigned char`,
|
||||||
@@ -588,6 +617,24 @@ printf("first: %d\nsecond: %d\n", first, second);
|
|||||||
// values will be swapped
|
// values will be swapped
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Return multiple values.
|
||||||
|
// C does not allow for returning multiple values with the return statement. If
|
||||||
|
// you would like to return multiple values, then the caller must pass in the
|
||||||
|
// variables where they would like the returned values to go. These variables must
|
||||||
|
// be passed in as pointers such that the function can modify them.
|
||||||
|
int return_multiple( int *array_of_3, int *ret1, int *ret2, int *ret3)
|
||||||
|
{
|
||||||
|
if(array_of_3 == NULL)
|
||||||
|
return 0; //return error code (false)
|
||||||
|
|
||||||
|
//de-reference the pointer so we modify its value
|
||||||
|
*ret1 = array_of_3[0];
|
||||||
|
*ret2 = array_of_3[1];
|
||||||
|
*ret3 = array_of_3[2];
|
||||||
|
|
||||||
|
return 1; //return error code (true)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
With regards to arrays, they will always be passed to functions
|
With regards to arrays, they will always be passed to functions
|
||||||
as pointers. Even if you statically allocate an array like `arr[10]`,
|
as pointers. Even if you statically allocate an array like `arr[10]`,
|
||||||
@@ -716,6 +763,10 @@ typedef void (*my_fnp_type)(char *);
|
|||||||
// my_fnp_type f;
|
// my_fnp_type f;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Printing characters with printf()
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
//Special characters:
|
//Special characters:
|
||||||
/*
|
/*
|
||||||
'\a'; // alert (bell) character
|
'\a'; // alert (bell) character
|
||||||
|
Reference in New Issue
Block a user