P1R0
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # KandR-game :::info #### Table of Contents [TOC] ::: ###### tags: `tutorials` `c` `game` `k&r` ___ ## Introduction A K&R Solving Exercises Game/Contest for the best solutions with some friends. The gist of this game is not only to have fun but to also learn about best practices in the C language. Every week (approximately), each member of the group will upload their version of the appointed exercise for that week. The fastest and most eficient code will be moved to the master branch. The criteria for the best code are explain [below](#Criteria-for-the-Best-Code). For newcomers in C programming -- and programming in general -- we recommend using the following programming environments (also text-editors): * [Vim](https://www.vim.org/download.php) (included in Linux platforms) * [VScode](https://code.visualstudio.com/download) (recommended) * [Atom](https://atom.io/) * [Emacs](https://www.gnu.org/software/emacs/download.html) (easy to install in Linux platforms) * Nano (included in Linux platforms; basic text-editor) The simplest way to compile C code is by running the following command on the terminal (Linux, Mac or Windows): ```shell $ gcc -o name program.c ``` This will create an executable (```.o```) object from the code ```program.c```. Coding software like VScode or Atom have external extensions to compile several programming languages, including C. --- ## Schematic Organization of Remote and Local Branches To keep things clean and tidy, we will structure the main (*master*) branch as follows: :::success ```bash . (kandr-game) ├── Chapter1 │ ├── exercise_1-1.c │ ├── exercise_1-10.c │ ├── exercise_1-12.c │ ... ├── Chapter2 │ ├── exercise_2-1.c │ ├── exercise_2-10.c │ ├── exercise_2-2.c │ ├── exercise_2-3.c │ ... ├── Chapter3 │ ├── exercise_3-1.c │ ├── exercise_3-2.c │ ├── exercise_3-3.c │ ... ├── Chapter4 │ ├── exercise_4-1.c │ ├── exercise_4-10.c │ ├── exercise_4-11.c │ ... ├── Chapter5 │ ├── exercise_5-1.c │ ├── exercise_5-2.c │ ├── exercise_5-3.c │ ... ├── Chapter6 │ ├── exercise_6-1.c │ ├── exercise_6-2.c │ ├── exercise_6-3.c │ ... ├── Chapter7 │ ├── exercise_7-1.c │ ├── exercise_7-2.c │ ├── exercise_7-3.c │ ... ├── Chapter8 │ ├── exercise_8-1.c │ ├── exercise_8-2.c │ ├── exercise_8-3.c │ ... ├── README.md ``` ::: The folder names of are ```ChapterX```, where ```X``` is the number of the current Chapter and the names of each concurrent exercise is ```exercise_X-Y.c```, where ```X``` is the Chapter and ```Y``` is the exercise number. Since the master branch and your branch are independent from one another, you can structure your branch any way you prefer, but **the names of folders and exercises should be the same as the code block above**; this is important because it makes the merging process faster. You can opt to encapsule your declarations in header libraries (```.h```), just use the same name nomenclature as the one for exercises, e.g. ```exercise_X-Y.h```, this way we can avoid copying reusable code. Now, we strongly recommend that your local repository should only have the master branch and your branch downloaded while the others remain remote[^second], i.e. [^second]: You should always be aware that your local and remote branches are separate entities, so remember to keep both of them up-to-date :smile:. ```bash $ git branch -a * kaicudon master remotes/origin/HEAD -> origin/master remotes/origin/chef remotes/origin/kaicudon remotes/origin/master remotes/origin/oliver remotes/origin/p1r0 remotes/origin/president ``` where the ```* kaicudon``` means that the branch ```kaicudon``` is the one *checked-out* (with local access) while ```master``` remains in the background. To achieve this, we just need to *track* the desired brach right after we have cloned the *KandR* repository (do this as soon as you can): ```bash $ git checkout --track origin/yourbranch ``` where 'yourbranch' is the name of the branch to check-out. The command above will download, check-out and track 'yourbranch' to your local repository. We also suggest that you add the following header to each and every exercise you append to your remote branch: :::spoiler **Click here to show details** ```c /***************************************************************************** ############################################################################# ########## ######### ############################### ########### ######### ######## ############ ################# ########## ######## ######## ####### ########## #### ############# ############ ####### ####### ###### ########### #### ############## ########## ########## ###### ################ ####### ###### ############## ##### ####### ############ ### ### ######## ########## ############# #### ######### ######### ##### # ######### ############ ############ ### ########### ####### ####### ########## ############## ########### ## ############# ######## ### # ######## ################ ########## # ############### ########## ###### #### ################## ######### ############################################################################# ############################################################################# ######## ######## ####### # ## # ### #### ####### ###### ############# #### ### #### ## ## # ## ## #### ####### ##### ####### ### ## ## ###### ## ##### ### ## ############## ###### ################# #### ### ## ########### #### ############## ######## ##### #### ######### ## ########### ###### ########## ################### ################################################### ############################################################################# ============================================================================= | This code is part of the K&R group game, where the goal is to solve every | | exercise of the book in the most elegant and eficient way. The K&R C book | | can be consulted on the Telegram group. More information about the game | | is provided in the README.md file located at the master branch. | |---------------------------------------------------------------------------- | | | Coded by ____________ | | Date: ____________ | | | |---------------------------------------------------------------------------- | | | Exercise 1-1. Run the ``hello, world'' program on your system. Experiment | | with leaving out parts of the program, to see what error messages you | | get. | | | |---------------------------------------------------------------------------- | | | Explanation (in cases needed): | | | ============================================================================= *****************************************************************************/ #include <stdio.h> ... /* other declarations */ ... int main() { ... } ... /* more code */ ... ``` ::: &nbsp; Some of the exercises ask you to explain how a certain process works, which only happens occasionally. Adding this header to your code will also help speed up the merging and organizing process for the main branch. ___ ## Best Coding Practices The [K&R book](http://mef-lab.com/osnove-2016/C-Programming-Ebook.pdf) -- *the book* -- was the first of its kind (fresh after the creation of the C language) and, as expected, the standard applied to it (*C89* and then *C99*) is now dated -- being *C11* the current one. Nevertheless, most (if not all) coding examples and exercises in the book work with little to no modifications. For this reason, we will code with the *C99* standard, in order to avoid any confusions and to be able to keep up with the book. All of the 'rules' aforementioned are described and justified throughout the book and, with discipline, they can provide clean, readable and scalable code. ### Structure We should structure code in the following manner: 1. A header (in comment form) that contains relevant information about the program -- see a suggestion [here](#Schematic-Organization-of-Remote-and-Local-Branches). 2. Header libraries used in `main()`and other functions. For example: ```c #include <stdio.h> // pre-compiled library #include <string.h> // pre-compiled library #include <"allvars.h"> // external library ``` 3. Macro definitions. ```c #define PI 3.14159 #define EULER 2.71828 ``` Macros should always be set in **CAPS**, except when the macro is in the form of an embedded function (see Section 4.11.2 of the book). 4. Function declarations or *preamble*. The names of functions cannot be the same as other pre-existing functions or reserved words. ```c void function_1(int, char*); // the names of the parameters // can be omitted void strcpy(char *s, char *t); // invalid name 'strcpy' // if string.h has been included void while(int); // invalid, 'while' is reserved ``` 5. Function definitions, this includes, of course, the ```main()```definition, which should be the first function declared. We recommend to always define a ```main()``` function, even if it is not required in the exercise. ```c int main(int argc, char *argv) { ... return 0; } void function_1(int a, char *s) { ... return; } char function_2(int a, char *s) { ... return '\0'; } ``` In the book, it is recommended that, if a static variable should be defined or there should be a macro defined for an specific function, this static variable or macro should go right before the function definition, e.g. ```c int main(int argc, char *argv) { ... return 0; } #define MAC 0 static int var = 30; void function_1(int a, char *s) { a += var; if (s[0] != MAC) { ... } ... return; } ``` Although this is not at all necessary, we do recommend to follow this 'rule'. Another thing to point out is that, despite ```main()``` not being obliged to explicitly return a value, we recommend to always return an integer (```int```) value and to specify the return type as in: ```int main(...) {...}```, similar to the code above. The arguments ```argc``` and ```argv``` are not explicitly mentioned up until Chapter 5 of the book and may be omitted for the preceding Chapters' exercises. ### Variable Declaration and Assignment Variables can be declared practically anywhere in a C program. They can be declared (and assigned) outside any function, inside a function or -- in some special cases -- inside a block-structure like ```if``` or ```for``` (this also depends on the C standard). ```c #include <stdio.h> void function_1(int, char*); int a, b; // global variable (full scope) int main(int argc, char *argv) { int a, b = 10; // main() variable (main-limited scope) // variables can be assigned when declared a = 2 // assigned when used if (a < b) { int c; // internal if variable (scope inside if) ... } ... return 0; } void function_1(int a, char *s) { int a, b; // function_1 variable (scope limited by function_1) ... return; } ``` Notice that every variable has been declared at the beginning of a block (excluding global variables). This is because the *C89* and *C99* standards would not permit to declare variables elsewhere. Although *C11* already does allow this, we should stick to the *C99* standard for this project. Exotic, but valid, statements like: ```c for (int i = 0; i < 10; i++) { ... } ``` are useful due to their compactness but they should be avoided in favor of clarity (it also depends on the desired scope). ```c int i; for (i = 0; i < 10; i++) { ... } ``` We recommend to assign variables when they are going to be used and not at declaration. We also encourage you to make declarations as compact as possible by grouping per type, e.g. ```c int a, b, c; size_t d, f; char *s, t, *p; ``` Lastly, try to avoid working with *ghost* numbers and to instead use macros for them. ```c #define ITER 10 ... int i; for (i = 0; i < ITER; i++) { // using macro ITER ... } ``` ### Wrapping with Braces Throughout the book you will see block-structured code similar to this: ```c int i, j; for (i = 0, j = 0; i < ITER; i++, j++) if (i < j) printf("%d\n", i); ``` This is because, if an instruction like ```for``` or ```if``` has only one statement inside its body, it is not necessary to wrap it between braces; otherwise, it would look like this: ```c int i, j; for (i = 0, j = 0; i < ITER; i++, j++) { if (i < j) { printf("%d\n", i); } } ``` which is a bit messier and unnecessary. We recommend not to use braces when the body of a block has one statement, but braces are mandatory when the block has more than one statement. ### Indentation Braces in C programming delimit the scope of a group of statements, so it is not necessary to indent the code to know to what block they belong (unlike languages like **Python**). However, all of the code uploaded to this project/game should be indented to make it easier to read. Indentation is measured with *tabspaces* and each tabspace a has number of single white spaces. The norm used to be that **1 tabspace = 4 whitespaces** (all the examples above use this rule). We instead recommend to use **1 tabspace = 2 whitespaces**, so each block should be indented **1 tabspace**. ```c |int i, j; | |for (i = 0, j = 0; i < ITER; i++, j++) |__if (i < j) |____printf("%d\n", i); ``` This amount of indentation is specially useful if the line-width of your screen is 80 characters per line. ___ ## Criteria for the Best Code We will focus on the following pointers (:wink:) to evaluate the best codes uploaded. Criteria *zero* is, obviously, to ==***push the current exercise to your remote branch on time***==, that is, before the deadline expires. We are aware sometimes there is simply no time to invest on the project, that is why we will schedule each deadline once the previous one is completed, i.e. once we have chosen the best code available. If you did not push your local branch to the remote one on time, your code **will not be considered for selection**. More information on how to push your code, and how to work with Git in general, may be found [below](#Git-References) or [here](https://docs.gitlab.com/ee/gitlab-basics/). The remaining criteria are: - Structure and adherence to best practices - Economical use of language - Inventiveness and originality - Error-checking - Documentation (helpful remarks with comments) - Execution time Let us explain all of this criteria with one simple example. Consider the code right below. The function ```strend``` returns 1 (True) if the string ```s``` ends with the string ```t```, otherwise it returns 0 (False). ```c= /* strend: return 1 if 's' ends with 't', 0 if else */ int strend(char *s, char *t) { int n, lt, ls; lt = strlena(t); // length of t ls = strlena(s); // length of s if ((ls-lt) < 0) { printf("strend: first argument string is shorter than second argument string.\n"); return 0; } s += ls-lt; // moves s to the start of t for (n = 0; (*t != '\0') && (*s == *t); s++, t++, n++) ; if (n == lt) // n = length of t return 1; return 0; } ``` From the start we can notice an adherence to basic coding principles. The variables used in ```strend``` are declared at the beginning, and they were grouped by type (line **3**). All of the variables -- ```n```, ```ls``` and ```lt``` -- were defined when used (lines **5**, **6** and **13**). Every block with more than one statement was wrapped in braces (lines **2** and **7**), while the others were not (lines **13** and **15**). Additionally, all of the blocks and statements inside ```strend``` were indented with two whitespaces. While sticking to these principles already translates to good language economics, it is much more noticeable by looking at the ```for``` statement of line **13**. It manages to initialize ```n```, perform two comparison tests and add to three different variables -- two of them using pointer arithmetics -- in just one line! Statements like this are common in the book, but it might take you some time to get used to them. Although the ```strend``` algorithm (and code) may not be very inventive, it certainly is original[^first]. The same goal could be accomplished with ease using ```char``` arrays instead of pointers, but it would make the code less economical and less scalable, among other disadvantages. [^first]: See Sections 4.10 and 5.6 of the book to check-out a truly inventive sorting algorithm. Since ```strend``` is such a simple function, it requires little error-checking processes. In this case, the ```if``` block at line **7** verifies that ```s``` is longer than ```t```, ```else```, the function cannot be applied. A short function like ```strend``` needs little to no information to be understood, still, the code provides some help when deems it suitable. Stating the function's purpose is always welcome. Finally, problems usually have more than one solution and some solutions are faster than others. For example, the array version of ```strend``` is a tad faster than the pointer version. Of course, this tiny difference could be of true relevance when we are dealing with a program with a dozen processes similar to ```strend```. Measuring the execution time of a chunk of code is as simple as: ```c #include <time.h> #include <stdio.h> ... int main() { ... clock_t start, end; double cpu_time_used; start = clock(); ... //process to be measured ... end = clock(); ... // printing measurement cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("Time taken: %lf in seconds.\n", cpu_time_used); ... return 0; } ``` ___ ## Git References We end this document with some references regarding information about Git management, which include pulling, pushing, commiting, branching, merging, and other basic git administrative tasks. * Git fundamentals: * [Basic concepts (cloning, adding, commiting, etc.)](https://docs.gitlab.com/ee/gitlab-basics/) * [Branching](https://docs.gitlab.com/ee/user/project/repository/branches/) * Git merging: * [Getting started](https://docs.gitlab.com/ee/user/project/merge_requests/getting_started.html) * [How to create a merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) #### Happy coding! And have lots of fun! (Ritchie fun, not P1R0 fun :joy:) ![DRthug](https://n0pe.org/images/dennis-ritchie-tuac.jpg)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully