Update
This commit is contained in:
parent
3dbb022352
commit
95e6641b63
13 changed files with 1858 additions and 1851 deletions
|
@ -224,7 +224,7 @@ X is not greater than 10.
|
|||
And it is also smaller than 5.
|
||||
```
|
||||
|
||||
About **conditions** in C: a condition is just an expression (variables/functions along with arithmetic operators). The expression is evaluated (computed) and the number that is obtained is interpreted as *true* or *false* like this: **in C 0 (zero) means false, 1 (and everything else) means true**. Even comparison operators like `<` and `>` are technically arithmetic, they compare numbers and yield either 1 or 0. Some operators commonly used in conditions are:
|
||||
About **conditions** in C: a condition is just an expression (variables/functions along with arithmetic operators). The expression is evaluated (computed) and the number that is obtained is interpreted as *true* or *false* like this: **in C 0 ([zero](zero.md)) means false, 1 (and everything else) means true**. Even comparison operators like `<` and `>` are technically arithmetic, they compare numbers and yield either 1 or 0. Some operators commonly used in conditions are:
|
||||
|
||||
- `==` (equals): yields 1 if the operands are equal, otherwise 0.
|
||||
- `!=` (not equal): yields 1 if the operands are NOT equal, otherwise 0.
|
||||
|
@ -376,7 +376,7 @@ Functions are similar to but **NOT the same as mathematical functions**. Mathema
|
|||
|
||||
**Why are function so important?** Firstly they help us divide a big problem into small subproblems and make the code better organized and readable, but mainly they help us respect the [DRY](dry.md) (*Don't Repeat Yourself*) principle -- this is extremely important in programming. Imagine you need to solve a [quadratic equation](quadratic_equation.md) in several parts of your program; you do NOT want to solve it in each place separately, you want to make a function that solves a quadratic equation and then only invoke (call) that function anywhere you need to solve your quadratic equation. This firstly saves space (source code will be shorter and compiled program will be smaller), but it also makes your program manageable and eliminates bugs -- imagine you find a better (e.g. faster) way to solving quadratic equations; without functions you'd have to go through the whole code and change the algorithm in each place separately which is impractical and increases the chance of making errors. With functions you only change the code in one place (in the function) and in any place where your code invokes (calls) this function the new better and updated version of the function will be used.
|
||||
|
||||
Besides writing programs that can be directly executed programmers write **[libraries](library.md)** -- collections of functions that can be used in other projects. We have already seen libraries such as *stdio*, *standard input/output library*, a standard (official, bundled with every C compiler) library for input/output (reading and printing values); *stdio* contains functions such as `puts` which is used to printing out text strings. Examples of other libraries are the standard *math* library containing function for e.g. computing [sine](sine.md), or [SDL](sdl.md), a 3rd party multimedia library for such things as drawing to screen, playing sounds and handling keyboard and mouse input.
|
||||
Besides writing programs that can be directly executed programmers also write so called **[libraries](library.md)** -- collections of functions (and possibly similar things like macros etc.) that can be used in other projects. We have already seen libraries such as *stdio*, *standard input/output library*, a standard (official, should be bundled with every C compiler) library for input/output (reading and printing values); *stdio* contains functions such as `puts` which is used to printing out text strings. Examples of other libraries are the standard *math* library containing function for e.g. computing [sine](sine.md), or [SDL](sdl.md), a 3rd party multimedia library for such things as drawing to screen, playing sounds and handling keyboard and mouse input.
|
||||
|
||||
Let's see a simple example of a function that writes out a temperature in degrees of Celsius as well as in Kelvin:
|
||||
|
||||
|
@ -611,7 +611,7 @@ void work(void)
|
|||
printMoney();
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
work();
|
||||
playLottery();
|
||||
|
@ -705,7 +705,7 @@ void printDecorated2(int x, int fancy)
|
|||
putchar('<');
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
printDecorated1(10,1);
|
||||
putchar('\n'); // newline
|
||||
|
@ -847,11 +847,11 @@ Some programmers simplify this whole process further so that they don't even nee
|
|||
|
||||
As a bonus, let's see a few useful compiler flags:
|
||||
|
||||
- `-O1`, `-O2`, `-O3`: Optimize for speed (higher number means better optimization). Adding `-O3` normally instantly speeds up your program. This is recommended.
|
||||
- `-Os`: Optimize for size, the same as above but the compiler will try to make as small executable as possible.
|
||||
- `-Wall -Wextra -pedantic`: The compiler will write more warnings and will be more strict. This can help spot many bugs.
|
||||
- `-O1`, `-O2`, `-O3`: Optimize for speed (higher number means better optimization). Adding `-O3` normally instantly speeds up your program (but slows down compilation, so you may want to choose higher optimization only for releases etc.). This is recommended (watch out though: your program may grow in size).
|
||||
- `-Os`: Optimize for size, the same as above but the compiler will try to make as small executable as possible (this may be on detriment of execution speed).
|
||||
- `-Wall -Wextra -pedantic`: The compiler will write more warnings and will be more strict. This can help spot many bugs. It's highly recommended to always set these!
|
||||
- `-c`: Compile only (generate object files, do not link).
|
||||
- `-g`: Include debug symbols, this will be important for [debugging](debugging.md).
|
||||
- `-g`: Include debug symbols, this will be important for [debugging](debugging.md). For non-release builds it's good to always turn this on.
|
||||
|
||||
## Advanced Data Types And Variables (Structs, Arrays, Strings)
|
||||
|
||||
|
@ -921,7 +921,7 @@ int main(void)
|
|||
putchar('\n'); // newline
|
||||
|
||||
/* compute vector length with
|
||||
pythagoren theorem: */
|
||||
pythagorean theorem: */
|
||||
|
||||
float sum = 0;
|
||||
|
||||
|
@ -1118,7 +1118,7 @@ void printArray(void)
|
|||
printf("%d ",array[i]);
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
fillArray();
|
||||
printArray();
|
||||
|
@ -1137,7 +1137,7 @@ Macros can optionally take parameters similarly to functions. There are no data
|
|||
|
||||
#define MEAN3(a,b,c) (((a) + (b) + (c)) / 3)
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
int n = MEAN3(10,20,25);
|
||||
|
||||
|
@ -1149,7 +1149,7 @@ int main()
|
|||
|
||||
`MEAN3` computes the mean of 3 values. Again, it's just text replacement, so the line `int n = MEAN3(10,20,25);` becomes `int n = (((10) + (20) + (25)) / 3);` before code compilation. Why are there so many brackets in the macro? It's always good to put brackets over a macro and all its parameters because the parameters are again a simple text replacement; consider e.g. a macro `#define HALF(x) x / 2` -- if it was invoked as `HALF(5 + 1)`, the substitution would result in the final text `5 + 1 / 2`, which gives 5 (instead of the intended value 3).
|
||||
|
||||
You may be asking why would we use a macro when we can use a function for computing the mean? Firstly macros don't just have to work with numbers, they can be used to generate parts of the source code in ways that functions can't. Secondly using a macro may sometimes be simpler, it's shorter and will be faster to execute because the is no function call (which has a slight overhead) and because the macro expansion may lead to the compiler precomputing expressions at compile time. But beware: macros are usually worse than functions and should only be used in very justified cases. For example macros don't know about data types and cannot check them, and they also result in a bigger compiled executable (function code is in the executable only once whereas the macro is expanded in each place where it is used and so the code it generates multiplies).
|
||||
You may be asking why would we use a macro when we can use a function for computing the mean? Firstly macros don't just have to work with numbers, they can be used to generate parts of the source code in ways that functions can't. Secondly using a macro may sometimes be simpler, it's shorter and will be faster to execute because there is no function call (which has a slight overhead) and because the macro expansion may lead to the compiler precomputing expressions at compile time. But beware: macros are usually worse than functions and should only be used in very justified cases. For example macros don't know about data types and cannot check them, and they also result in a bigger compiled executable (function code is in the executable only once whereas the macro is expanded in each place where it is used and so the code it generates multiplies).
|
||||
|
||||
Another very useful directive is `#if` for conditional inclusion or exclusion of parts of the source code. It is similar to the C `if` command. The following example shows its use:
|
||||
|
||||
|
@ -1171,7 +1171,7 @@ void printNumber(int x)
|
|||
printf("%d\n",x);
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
printNumber(3);
|
||||
printNumber(100);
|
||||
|
@ -1852,7 +1852,7 @@ int main(int argc, char **argv)
|
|||
if (fileOffset + COLS < fileSize)
|
||||
fileOffset += COLS;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (fileOffset >= COLS)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue