Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fadookie/c_fundamentals

Demonstration of some fundamental concepts of the C programming model
https://github.com/fadookie/c_fundamentals

Last synced: about 1 month ago
JSON representation

Demonstration of some fundamental concepts of the C programming model

Awesome Lists containing this project

README

        

# C Fundamentals

This project is made to demonstrate some fundamental concepts of the C programming model. My goal is try to explain things that have a bearing on other languages such as JavaScript but may be difficult to grasp at a higher level of abstraction.

This is mostly intended as a supplement to a talk I'm planning.

## Interactive illustrated examples
Using the excellent [C Tutor from pythontutor.com](http://www.pythontutor.com/c.html).

* [Stack vs. Heap][stackVsHeap] showing the difference between pass-by-reference and pass-by-value and types of memory allocation
* [Poor Man's OOP In C][poorMansOOP] demonstrating how OOP is mostly syntactic sugar, and the pitfalls of mutating shallow copies

## Building
This project is set up to build via Xcode, but it should be trivial to do so directly via your compiler of choice.

Right now the program is split up into a few different modules that can be toggled by editing `main.c`.

## Other Resources
* [Von Neumann machine simulator](http://vnsimulator.altervista.org/) - runs in the web browser.

[stackVsHeap]: http://www.pythontutor.com/c.html#code=%23include%20%3Cstdlib.h%3E%0A%0Avoid%20passByValueFunc%28int%20intPassedByValue,%20char%20charPassedByValue%29%20%7B%0A%20%20%20%20%2B%2BintPassedByValue%3B%0A%20%20%20%20charPassedByValue%20%3D%20'b'%3B%0A%20%20%20%20printf%28%22passByValueFunc%20finished,%20intPassedByValue%3A%25i,%20charPassedByValue%3A%25c%5Cn%22,%20intPassedByValue,%20charPassedByValue%29%3B%0A%7D%0A%0Avoid%20passByReferenceFunc%28int*%20intPassedByRef,%20char*%20charPassedByRef%29%20%7B%0A%20%20%20%20%2B%2B%28*intPassedByRef%29%3B%0A%20%20%20%20*charPassedByRef%20%3D%20'b'%3B%0A%20%20%20%20printf%28%22passByReferenceFunc%20finished,%20intPassedByRef%3A%25i,%20charPassedByRef%3A%25c%5Cn%22,%20*intPassedByRef,%20*charPassedByRef%29%3B%0A%7D%0A%0A%0Aint*%20stackVsHeap%28%29%20%7B%0A%20%20%20%20int%20stackInt%3B%0A%20%20%20%20stackInt%20%3D%201%3B%0A%20%20%20%20char%20stackChar%3B%0A%20%20%20%20stackChar%20%3D%20'a'%3B%0A%20%20%20%20%0A%20%20%20%20passByValueFunc%28stackInt,%20stackChar%29%3B%0A%20%20%20%20%0A%20%20%20%20printf%28%22passByValueFunc%20called,%20stackInt%3A%25i,%20stackChar%3A%25c%5Cn%22,%20stackInt,%20stackChar%29%3B%0A%20%20%20%20%0A%20%20%20%20passByReferenceFunc%28%26stackInt,%20%26stackChar%29%3B%0A%20%20%20%20%0A%20%20%20%20printf%28%22passByReferenceFunc%20called,%20stackInt%3A%25i,%20stackChar%3A%25c%5Cn%22,%20stackInt,%20stackChar%29%3B%0A%20%20%20%20%0A%20%20%20%20int*%20heapInt%20%3D%20malloc%28sizeof%28int%29%29%3B%0A%20%20%20%20char*%20heapChar%20%3D%20malloc%28sizeof%28char%29%29%3B%0A%20%20%20%20*heapInt%20%3D%2010%3B%0A%20%20%20%20*heapChar%20%3D%20'z'%3B%0A%20%20%20%20%0A%20%20%20%20passByReferenceFunc%28heapInt,%20heapChar%29%3B%0A%20%20%20%20printf%28%22passByReferenceFunc%20called,%20heapInt%3A%25i,%20heapChar%3A%25c%5Cn%22,%20*heapInt,%20*heapChar%29%3B%0A%20%20%20%20%0A//%20%20%20%20free%28heapInt%29%3B%0A//%20%20%20%20heapInt%20%3D%200%3B%0A//%20%20%20%20free%28heapChar%29%3B%0A//%20%20%20%20heapChar%20%3D%200%3B%0A%20%20%20%20%0A%20%20%20%20return%20heapInt%3B%0A%7D%0A%0A%0Aint%20main%28%29%20%7B%0A%20%20int*%20heapInt%20%3D%20stackVsHeap%28%29%3B%0A%20%20printf%28%22main%20got%20heapInt%3A%20%25i%5Cn%22,%20*heapInt%29%3B%0A%20%20return%200%3B%0A%7D&curInstr=33&mode=display&origin=opt-frontend.js&py=c&rawInputLstJSON=%5B%5D

[poorMansOOP]: http://www.pythontutor.com/c.html#code=%0A%23include%20%3Cstdarg.h%3E%0A%23include%20%3Cstdlib.h%3E%0A%23include%20%3Cstring.h%3E%0A%0Astruct%20inventoryItem%20%7B%0A%20%20%20%20const%20char*%20id%3B%0A%20%20%20%20int%20count%3B%0A%20%20%20%20struct%20inventoryItem*%20next%3B%0A%7D%3B%0A%0Atypedef%20struct%20inventoryItem%20inventoryItem%3B%0A%0Atypedef%20struct%20%7B%0A%20%20%20%20const%20char*%20id%3B%0A%20%20%20%20inventoryItem*%20inventory%3B%0A%7D%20inventoryGroup%3B%0A%0A//%20Creates%20a%20linked%20list%20from%20variadic%20struct%20arguments%0AinventoryItem*%20makeItemList%28const%20int%20count,%20...%29%20%7B%0A%20%20%20%20va_list%20args%3B%0A%20%20%20%20va_start%28args,%20count%29%3B%0A%20%20%20%20inventoryItem%20*firstItem%20%3D%200%3B%20//%20First%20item%20in%20list%0A%20%20%20%20inventoryItem%20*prevItem%20%3D%200%3B%20//%20Scratch%20variable%20for%20previous%20item%20in%20list%0A%20%20%20%20%0A%20%20%20%20//%20Loop%20over%20arguments%0A%20%20%20%20for%20%28int%20i%20%3D%200%3B%20i%20%3C%20count%3B%20%2B%2Bi%29%20%7B%0A%20%20%20%20%20%20%20%20inventoryItem%20inputItem%20%3D%20va_arg%28args,%20inventoryItem%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20//%20Allocate%20memory%20on%20the%20heap%20to%20store%20the%20input%20item%0A%20%20%20%20%20%20%20%20inventoryItem%20*item%20%3D%20malloc%28sizeof%28inventoryItem%29%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20//%20Copy%20the%20input%20item%20from%20the%20stack%20to%20the%20heap%0A%20%20%20%20%20%20%20%20memcpy%28item,%20%26inputItem,%20sizeof%28*item%29%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20//%20Save%20pointer%20to%20first%20item%20if%20needed%0A%20%20%20%20%20%20%20%20if%20%28!firstItem%29%20firstItem%20%3D%20item%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20//%20Set%20up%20linkage%20with%20previous%20item%20if%20needed%0A%20%20%20%20%20%20%20%20if%20%28prevItem%29%20prevItem-%3Enext%20%3D%20item%3B%0A%20%20%20%20%20%20%20%20prevItem%20%3D%20item%3B%0A%20%20%20%20%7D%0A%20%20%20%20va_end%28args%29%3B%0A%20%20%20%20%0A%20%20%20%20//%20Return%20pointer%20to%20first%20item%20in%20list%0A%20%20%20%20return%20firstItem%3B%0A%7D%0A%0Avoid%20printItem%20%28const%20inventoryItem*%20this%29%20%7B%0A%20%20%20%20printf%28%22inventoryItem%20%7B%20id%3A'%25s'%20count%3A'%25i'%20%7D%22,%20this-%3Eid,%20this-%3Ecount%29%3B%0A%7D%0A%0Avoid%20printGroup%20%28const%20inventoryGroup*%20this%29%20%7B%0A%20%20%20%20printf%28%22inventoryGroup%20%7B%20id%3A'%25s'%20inventory%3A%20%5B%5Cn%22,%20this-%3Eid%29%3B%0A%20%20%20%20for%20%28inventoryItem*%20item%20%3D%20this-%3Einventory%3B%20item%20!%3D%200%3B%20item%20%3D%20item-%3Enext%29%20%7B%0A%20%20%20%20%20%20%20%20printf%28%22%20%20%22%29%3B%0A%20%20%20%20%20%20%20%20printItem%28item%29%3B%0A%20%20%20%20%20%20%20%20printf%28%22,%5Cn%22%29%3B%0A%20%20%20%20%7D%0A%20%20%20%20printf%28%22%5D%7D%5Cn%22%29%3B%0A%7D%0A%0Avoid%20printGroups%28const%20inventoryGroup*%20groups,%20const%20int%20numGroups%29%20%7B%0A%20%20%20%20for%20%28int%20groupIdx%20%3D%200%3B%20groupIdx%20%3C%20numGroups%3B%20%2B%2BgroupIdx%29%20%7B%0A%20%20%20%20%20%20%20%20const%20inventoryGroup*%20group%20%3D%20%26groups%5BgroupIdx%5D%3B%0A%20%20%20%20%20%20%20%20printGroup%28group%29%3B%0A%20%20%20%20%7D%0A%7D%0A%0Avoid%20doOopTest%28%29%20%7B%0A%20%20%20%20puts%28%22do%20OOP%20test%22%29%3B%0A%20%20%20%20%0A%20%20%20%20//%20Allocate%20%26%20initialize%20some%20inventory%20groups%20on%20the%20stack%0A%20%20%20%20inventoryGroup%20groups%5B%5D%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20.id%20%3D%20%22fruits%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Groups%20can%20have%20different%20numbers%20of%20items%20in%20them%20so%20we%20can't%20allocate%20memory%20for%20them%20statically.%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Allocate%20them%20on%20the%20heap%20instead%20using%20a%20linked%20list%20%28a%20dynamic%20array%20would%20also%20work.%29%0A%20%20%20%20%20%20%20%20%20%20%20%20.inventory%20%3D%20makeItemList%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%202,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28inventoryItem%29%7B%20.id%20%3D%20%22apples%22,%20.count%20%3D%205%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28inventoryItem%29%7B%20.id%20%3D%20%22bananas%22,%20.count%20%3D%200%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20.id%20%3D%20%22vegetables%22,%0A%20%20%20%20%20%20%20%20%20%20%20%20.inventory%20%3D%20%20makeItemList%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%203,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28inventoryItem%29%7B%20.id%20%3D%20%22potatoes%22,%20.count%20%3D%204%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28inventoryItem%29%7B%20.id%20%3D%20%22carrots%22,%20.count%20%3D%202%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28inventoryItem%29%7B%20.id%20%3D%20%22kohlrabi%22,%20.count%20%3D%209%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%7D%3B%0A%20%20%20%20const%20int%20numGroups%20%3D%20sizeof%28groups%29%20/%20sizeof%28inventoryGroup%29%3B%20//%20groups.length%20would%20be%20too%20fancy%20for%20good%20old%20fashioned%20C!%0A%20%20%20%20%0A%20%20%20%20puts%28%22Initial%20values%3A%22%29%3B%0A%20%20%20%20printGroups%28groups,%20numGroups%29%3B%0A%20%20%20%20%0A%20%20%20%20puts%28%22%5CnCopy%20of%20fruit%3A%22%29%3B%0A%20%20%20%20//%20Copy%20fruit%20group%20to%20a%20new%20location%20on%20the%20stack.%0A%20%20%20%20inventoryGroup%20groupCopy%20%3D%20groups%5B0%5D%3B%0A%20%20%20%20//%20Mutate%20an%20item%20in%20our%20copy%20so%20we%20have%20a%20banana%0A%20%20%20%20%2B%2BgroupCopy.inventory-%3Enext-%3Ecount%3B%0A%20%20%20%20printGroup%28%26groupCopy%29%3B%0A%20%20%20%20%0A%20%20%20%20puts%28%22%5CnNew%20values%3A%22%29%3B%0A%20%20%20%20printGroups%28groups,%20numGroups%29%3B%0A%20%20%20%20%0A%20%20%20%20//%20Whoops!%20We%20caused%20a%20mutation%20in%20the%20original%20since%20our%20copy%20was%20still%20pointing%20to%20the%20same%20item's%20memory%20address.%20To%20fix%20this%20we%20would%20need%20to%20implement%20a%20%22deep%20copy%22%20of%20all%20children.%0A%20%20%20%20%0A%20%20%20%20//%20In%20a%20real%20application%20you'd%20need%20to%20free%20the%20heap%20memory%20when%20you're%20done%20with%20these%20objects,%20or%20you%20will%20get%20a%20memory%20leak!%0A%20%20%20%20//%20Also%20in%20a%20real%20application%20you%20should%20probably%20be%20using%20Rust%20or%20something.%0A%7D%0A%0A%0Aint%20main%28%29%20%7B%0AdoOopTest%28%29%3B%0A%20%20return%200%3B%0A%7D&curInstr=199&mode=display&origin=opt-frontend.js&py=c&rawInputLstJSON=%5B%5D