summaryrefslogtreecommitdiffhomepage
path: root/c.html.markdown
diff options
context:
space:
mode:
authorDivay Prakash <divayprakash@users.noreply.github.com>2019-12-23 23:14:50 +0530
committerGitHub <noreply@github.com>2019-12-23 23:14:50 +0530
commit16dc074e39f5f996639f23f4d6812c211ae5d22d (patch)
tree63be0d1a3885201f3d13f1dc00266fb719f304a7 /c.html.markdown
parentffd1fed725668b48ec8c11cbe419bd1e8d136ae3 (diff)
parent1d5f3671ea4bc6d7a70c3026c1ae6857741c50a6 (diff)
Merge branch 'master' into master
Diffstat (limited to 'c.html.markdown')
-rw-r--r--c.html.markdown53
1 files changed, 40 insertions, 13 deletions
diff --git a/c.html.markdown b/c.html.markdown
index 87a047be..7975a1c2 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -8,6 +8,8 @@ contributors:
- ["Marco Scannadinari", "https://marcoms.github.io"]
- ["Zachary Ferguson", "https://github.io/zfergus2"]
- ["himanshu", "https://github.com/himanshu81494"]
+ - ["Joshua Li", "https://github.com/JoshuaRLi"]
+ - ["Dragos B. Chirila", "https://github.com/dchirila"]
---
Ah, C. Still **the** language of modern high-performance computing.
@@ -17,13 +19,14 @@ it more than makes up for it with raw speed. Just be aware of its manual
memory management and C will take you as far as you need to go.
> **About compiler flags**
->
+>
> By default, gcc and clang are pretty quiet about compilation warnings and
-> errors, which can be very useful information. Using some
-> stricter compiler flags is recommended. Here is an example you can
-> tweak to your liking:
+> errors, which can be very useful information. Explicitly using stricter
+> compiler flags is recommended. Here are some recommended defaults:
+>
+> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic`
>
-> `-Wall -Wextra -Werror -O0 -ansi -pedantic -std=c11`
+> For information on what these flags do as well as other flags, consult the man page for your C compiler (e.g. `man 1 gcc`) or just search online.
```c
// Single-line comments start with // - only available in C99 and later.
@@ -87,6 +90,8 @@ int main (int argc, char** argv)
// All variables MUST be declared at the top of the current block scope
// we declare them dynamically along the code for the sake of the tutorial
+ // (however, C99-compliant compilers allow declarations near the point where
+ // the value is used)
// ints are usually 4 bytes
int x_int = 0;
@@ -99,7 +104,7 @@ int main (int argc, char** argv)
char y_char = 'y'; // Char literals are quoted with ''
// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
- // 64 bits
+ // 8 bytes
long x_long = 0;
long long x_long_long = 0;
@@ -139,6 +144,17 @@ int main (int argc, char** argv)
// You can initialize an array to 0 thusly:
char my_array[20] = {0};
+ // where the "{0}" part is called an "array initializer".
+ // NOTE that you get away without explicitly declaring the size of the array,
+ // IF you initialize the array on the same line. So, the following declaration
+ // is equivalent:
+ char my_array[] = {0};
+ // BUT, then you have to evaluate the size of the array at run-time, like this:
+ size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]);
+ // WARNING If you adopt this approach, you should evaluate the size *before*
+ // you begin passing the array to function (see later discussion), because
+ // arrays get "downgraded" to raw pointers when they are passed to functions
+ // (so the statement above will produce the wrong result inside the function).
// Indexing an array is like other languages -- or,
// rather, other languages are like C
@@ -372,8 +388,8 @@ int main (int argc, char** argv)
// respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h>
// Integral types can be cast to floating-point types, and vice-versa.
- printf("%f\n", (float)100); // %f formats a float
- printf("%lf\n", (double)100); // %lf formats a double
+ printf("%f\n", (double) 100); // %f always formats a double...
+ printf("%f\n", (float) 100); // ...even with a float.
printf("%d\n", (char)100.0);
///////////////////////////////////////
@@ -431,7 +447,7 @@ int main (int argc, char** argv)
// 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);
+ printf("%zu, %zu\n", sizeof(arraythethird), sizeof(ptr));
// probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
@@ -447,7 +463,7 @@ int main (int argc, char** argv)
for (xx = 0; xx < 20; xx++) {
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
-
+
// Be careful passing user-provided values to malloc! If you want
// to be safe, you can use calloc instead (which, unlike malloc, also zeros out the memory)
int* my_other_ptr = calloc(20, sizeof(int));
@@ -520,9 +536,11 @@ Example: in-place string reversal
void str_reverse(char *str_in)
{
char tmp;
- int ii = 0;
+ size_t ii = 0;
size_t len = strlen(str_in); // `strlen()` is part of the c standard library
- for (ii = 0; ii < len / 2; ii++) {
+ // NOTE: length returned by `strlen` DOESN'T include the
+ // terminating NULL byte ('\0')
+ for (ii = 0; ii < len / 2; ii++) { // in C99 you can directly declare type of `ii` here
tmp = str_in[ii];
str_in[ii] = str_in[len - ii - 1]; // ii-th char from end
str_in[len - ii - 1] = tmp;
@@ -587,6 +605,14 @@ static int j = 0; //other files using testFunc2() cannot access variable j
void testFunc2() {
extern int j;
}
+// The static keyword makes a variable inaccessible to code outside the
+// compilation unit. (On almost all systems, a "compilation unit" is a .c
+// file.) static can apply both to global (to the compilation unit) variables,
+// functions, and function-local variables. When using static with
+// function-local variables, the variable is effectively global and retains its
+// value across function calls, but is only accessible within the function it
+// is declared in. Additionally, static variables are initialized to 0 if not
+// declared with some other starting value.
//**You may also declare functions as static to make them private**
///////////////////////////////////////
@@ -701,7 +727,8 @@ typedef void (*my_fnp_type)(char *);
"%3.2f"; // minimum 3 digits left and 2 digits right decimal float
"%7.4s"; // (can do with strings too)
"%c"; // char
-"%p"; // pointer
+"%p"; // pointer. NOTE: need to (void *)-cast the pointer, before passing
+ // it as an argument to `printf`.
"%x"; // hexadecimal
"%o"; // octal
"%%"; // prints %