diff options
author | Divay Prakash <divayprakash@users.noreply.github.com> | 2019-12-23 23:14:50 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-23 23:14:50 +0530 |
commit | 16dc074e39f5f996639f23f4d6812c211ae5d22d (patch) | |
tree | 63be0d1a3885201f3d13f1dc00266fb719f304a7 /c.html.markdown | |
parent | ffd1fed725668b48ec8c11cbe419bd1e8d136ae3 (diff) | |
parent | 1d5f3671ea4bc6d7a70c3026c1ae6857741c50a6 (diff) |
Merge branch 'master' into master
Diffstat (limited to 'c.html.markdown')
-rw-r--r-- | c.html.markdown | 53 |
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 % |