diff options
Diffstat (limited to 'c.html.markdown')
-rw-r--r-- | c.html.markdown | 158 |
1 files changed, 147 insertions, 11 deletions
diff --git a/c.html.markdown b/c.html.markdown index 8e631de4..7c2386ef 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -6,7 +6,8 @@ contributors: - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"] - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"] - ["Marco Scannadinari", "https://marcoms.github.io"] - + - ["Zachary Ferguson", "https://github.io/zfergus2"] + - ["himanshu", "https://github.com/himanshu81494"] --- Ah, C. Still **the** language of modern high-performance computing. @@ -27,6 +28,7 @@ Multi-line comments don't nest /* Be careful */ // comment ends on this line... */ // ...not this one! // Constants: #define <keyword> +// Constants are written in all-caps out of convention, not requirement #define DAYS_IN_YEAR 365 // Enumeration constants are also ways to declare constants. @@ -52,10 +54,21 @@ int function_2(void); // Must declare a 'function prototype' before main() when functions occur after // your main() function. 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), +// it is recommended to name arguments in the prototype as well for easier inspection // Your program's entry point is a function called // main with an integer return type. int main(void) { + // your program +} + +// The command line arguments used to run your program are also passed to main +// argc being the number of arguments - your program's name counts as 1 +// argv is an array of character arrays - containing the arguments themselves +// argv[0] = name of your program, argv[1] = first argument, etc. +int main (int argc, char** argv) +{ // print output using printf, for "print formatted" // %d is an integer, \n is a newline printf("%d\n", 0); // => Prints 0 @@ -63,6 +76,9 @@ int main(void) { /////////////////////////////////////// // Types /////////////////////////////////////// + + // 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 // ints are usually 4 bytes int x_int = 0; @@ -130,15 +146,12 @@ int main(void) { // can be declared as well. The size of such an array need not be a compile // time constant: printf("Enter the array size: "); // ask the user for an array size - char buf[0x100]; - fgets(buf, sizeof buf, stdin); - - // strtoul parses a string to an unsigned integer - size_t size2 = strtoul(buf, NULL, 10); - int var_length_array[size2]; // declare the VLA + int size; + fscanf(stdin, "%d", &size); + int var_length_array[size]; // declare the VLA printf("sizeof array = %zu\n", sizeof var_length_array); - // A possible outcome of this program may be: + // Example: // > Enter the array size: 10 // > sizeof array = 40 @@ -219,7 +232,7 @@ int main(void) { 0 || 1; // => 1 (Logical or) 0 || 0; // => 0 - // Conditional expression ( ? : ) + // Conditional ternary expression ( ? : ) int e = 5; int f = 10; int z; @@ -289,6 +302,8 @@ int main(void) { for (i = 0; i <= 5; i++) { ; // use semicolon to act as the body (null statement) } + // Or + for (i = 0; i <= 5; i++); // branching with multiple choices: switch() switch (a) { @@ -304,7 +319,29 @@ int main(void) { exit(-1); break; } - + /* + using "goto" in C + */ + typedef enum { false, true } bool; + // for C don't have bool as data type :( + bool disaster = false; + int i, j; + for(i=0;i<100;++i) + for(j=0;j<100;++j) + { + if((i + j) >= 150) + disaster = true; + if(disaster) + goto error; + } + error : + printf("Error occured at i = %d & j = %d.\n", i, j); + /* + https://ideone.com/GuPhd6 + this will print out "Error occured at i = 52 & j = 99." + */ + + /////////////////////////////////////// // Typecasting /////////////////////////////////////// @@ -403,6 +440,17 @@ int main(void) { 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) + + // Note that there is no standard way to get the length of a + // dynamically allocated array in C. Because of this, if your arrays are + // going to be passed around your program a lot, you need another variable + // to keep track of the number of elements (size) of an array. See the + // functions section for more info. + int size = 10; + int *my_arr = malloc(sizeof(int) * size); + // Add an element to the array + my_arr = realloc(my_arr, ++size); + my_arr[10] = 5; // Dereferencing memory that you haven't allocated gives // "unpredictable results" - the program is said to invoke "undefined behavior" @@ -470,6 +518,46 @@ char c[] = "This is a test."; str_reverse(c); printf("%s\n", c); // => ".tset a si sihT" */ +/* +as we can return only one variable +to change values of more than one variables we use call by reference +*/ +void swapTwoNumbers(int *a, int *b) +{ + int temp = *a; + *a = *b; + *b = temp; +} +/* +int first = 10; +int second = 20; +printf("first: %d\nsecond: %d\n", first, second); +swapTwoNumbers(&first, &second); +printf("first: %d\nsecond: %d\n", first, second); +// values will be swapped +*/ + +/* +With regards to arrays, they will always be passed to functions +as pointers. Even if you statically allocate an array like `arr[10]`, +it still gets passed as a pointer to the first element in any function calls. +Again, there is no standard way to get the size of a dynamically allocated +array in C. +*/ +// Size must be passed! +// Otherwise, this function has no way of knowing how big the array is. +void printIntArray(int *arr, int size) { + int i; + for (i = 0; i < size; i++) { + printf("arr[%d] is: %d\n", i, arr[i]); + } +} +/* +int my_arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; +int size = 10; +printIntArray(my_arr, size); +// will print "arr[0] is: 1" etc +*/ // if referring to external variables outside function, must use extern keyword. int i = 0; @@ -626,8 +714,56 @@ typedef void (*my_fnp_type)(char *); // , | left to right // //---------------------------------------------------// -``` +/******************************* Header Files ********************************** + +Header files are an important part of c as they allow for the connection of c +source files and can simplify code and definitions by seperating them into +seperate files. + +Header files are syntaxtically similar to c source files but reside in ".h" +files. They can be included in your c source file by using the precompiler +command #include "example.h", given that example.h exists in the same directory +as the c file. +*/ + +/* A safe guard to prevent the header from being defined too many times. This */ +/* happens in the case of circle dependency, the contents of the header is */ +/* already defined. */ +#ifndef EXAMPLE_H /* if EXAMPLE_H is not yet defined. */ +#define EXAMPLE_H /* Define the macro EXAMPLE_H. */ + +/* Other headers can be included in headers and therefore transitively */ +/* included into files that include this header. */ +#include <string.h> +/* Like c source files macros can be defined in headers and used in files */ +/* that include this header file. */ +#define EXAMPLE_NAME "Dennis Ritchie" +/* Function macros can also be defined. */ +#define ADD(a, b) (a + b) + +/* Structs and typedefs can be used for consistency between files. */ +typedef struct node +{ + int val; + struct node *next; +} Node; + +/* So can enumerations. */ +enum traffic_light_state {GREEN, YELLOW, RED}; + +/* Function prototypes can also be defined here for use in multiple files, */ +/* but it is bad practice to define the function in the header. Definitions */ +/* should instead be put in a c file. */ +Node createLinkedList(int *vals, int len); + +/* Beyond the above elements, other definitions should be left to a c source */ +/* file. Excessive includeds or definitions should, also not be contained in */ +/* a header file but instead put into separate headers or a c file. */ + +#endif /* End of the if precompiler directive. */ + +``` ## 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) |