summaryrefslogtreecommitdiffhomepage
path: root/c.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'c.html.markdown')
-rw-r--r--c.html.markdown47
1 files changed, 30 insertions, 17 deletions
diff --git a/c.html.markdown b/c.html.markdown
index 8e170300..d3f20eda 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -4,6 +4,8 @@ filename: learnc.c
contributors:
- ["Adam Bard", "http://adambard.com/"]
- ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
+ - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"]
+ - ["Marco Scannadinari", "https://marcoms.github.io"]
---
@@ -20,13 +22,19 @@ memory management and C will take you as far as you need to go.
Multi-line comments look like this. They work in C89 as well.
*/
- // Constants: #define <keyword>
+/*
+Multi-line comments don't nest /* Be careful */ // comment ends on this line...
+*/ // ...not this one!
+
+// Constants: #define <keyword>
#define DAYS_IN_YEAR 365
- // Enumeration constants are also ways to declare constants.
- enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
+// Enumeration constants are also ways to declare constants.
+// All statements must end with a semicolon
+enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// MON gets 2 automatically, TUE gets 3, etc.
+
// Import headers with #include
#include <stdlib.h>
#include <stdio.h>
@@ -51,7 +59,6 @@ int main() {
// print output using printf, for "print formatted"
// %d is an integer, \n is a newline
printf("%d\n", 0); // => Prints 0
- // All statements must end with a semicolon
///////////////////////////////////////
// Types
@@ -73,12 +80,12 @@ int main() {
long long x_long_long = 0;
// floats are usually 32-bit floating point numbers
- float x_float = 0.0;
+ float x_float = 0.0f; // 'f' suffix here denotes floating point literal
// doubles are usually 64-bit floating-point numbers
- double x_double = 0.0;
+ double x_double = 0.0; // real numbers without any suffix are doubles
- // Integral types may be unsigned.
+ // integer types may be unsigned (greater than or equal to zero)
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;
@@ -175,6 +182,9 @@ int main() {
i2 * i1; // => 2
i1 / i2; // => 0 (0.5, but truncated towards 0)
+ // You need to cast at least one integer to float to get a floating-point result
+ (float)i1 / i2 // => 0.5f
+ i1 / (double)i2 // => 0.5 // Same with double
f1 / f2; // => 0.5, plus or minus epsilon
// Floating-point numbers and calculations are not exact
@@ -194,9 +204,11 @@ int main() {
2 >= 2; // => 1
// C is not Python - comparisons don't chain.
- // WRONG:
- //int between_0_and_2 = 0 < a < 2;
- // Correct:
+ // Warning: The line below will compile, but it means `(0 < a) < 2`.
+ // This expression is always true, because (0 < a) could be either 1 or 0.
+ // In this case it's 1, because (0 < 1).
+ int between_0_and_2 = 0 < a < 2;
+ // Instead use:
int between_0_and_2 = 0 < a && a < 2;
// Logic works on ints
@@ -211,7 +223,7 @@ int main() {
int e = 5;
int f = 10;
int z;
- z = (a > b) ? a : b; // => 10 "if a > b return a, else return b."
+ z = (e > f) ? e : f; // => 10 "if e > f return e, else return f."
//Increment and decrement operators:
char *s = "iLoveC";
@@ -222,7 +234,7 @@ int main() {
// same with j-- and --j
// Bitwise operators!
- ~0x0F; // => 0xF0 (bitwise negation, "1's complement")
+ ~0x0F; // => 0xFFFFFFF0 (bitwise negation, "1's complement", example result for 32-bit int)
0x0F & 0xF0; // => 0x00 (bitwise AND)
0x0F | 0xF0; // => 0xFF (bitwise OR)
0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
@@ -230,7 +242,7 @@ int main() {
0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
// Be careful when shifting signed integers - the following are undefined:
- // - shifting into the sign bit of a signed integer (int a = 1 << 32)
+ // - shifting into the sign bit of a signed integer (int a = 1 << 31)
// - left-shifting a negative number (int a = -1 << 2)
// - shifting by an offset which is >= the width of the type of the LHS:
// int a = 1 << 32; // UB if int is 32 bits wide
@@ -374,7 +386,8 @@ int main() {
// or when it's the argument of the `sizeof` or `alignof` operator:
int arraythethird[10];
int *ptr = arraythethird; // equivalent with int *ptr = &arr[0];
- printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr); // probably prints "40, 4" or "40, 8"
+ printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr);
+ // probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
@@ -465,7 +478,7 @@ void testFunc() {
}
//make external variables private to source file with static:
-static int j = 0; //other files using testFunc() cannot access variable i
+static int j = 0; //other files using testFunc2() cannot access variable j
void testFunc2() {
extern int j;
}
@@ -573,7 +586,7 @@ typedef void (*my_fnp_type)(char *);
'\''; // single quote
'\"'; // double quote
'\xhh'; // hexadecimal number. Example: '\xb' = vertical tab character
-'\ooo'; // octal number. Example: '\013' = vertical tab character
+'\0oo'; // octal number. Example: '\013' = vertical tab character
//print formatting:
"%d"; // integer
@@ -618,7 +631,7 @@ typedef void (*my_fnp_type)(char *);
## Further Reading
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
-It is *the* book about C, written by the creators of C. Be careful, though - it's ancient and it contains some
+It is *the* book about C, written by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it's ancient and it contains some
inaccuracies (well, ideas that are not considered good anymore) or now-changed practices.
Another good resource is [Learn C the hard way](http://c.learncodethehardway.org/book/).