Sample solutions for low-level problems written in C [closed] - c

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
Does anyone know where I might find sample solutions written in C for low level / systems level applications? A really good website or book recommendation would be cool too.
I've learned some of the basics, but would like to see some code within the context of a real solution written in C, and specifically for a lower-level problem. Id' be interested in how C is used within the context of OS programming, for example. What are some areas where C is used for lower-level programming?
Thanks.

I would suggest you to study MINIX3 from Tanenbaum: http://www.minix3.org/
Its a microkernel architecture, and with his book ( http://vig.prenhall.com/catalog/academic/product/0,1144,0131429388,00.html ) it is really enlightning.
As of my opinion, studying the linux kernel is a bit hardcore for a start ;), and out of a academical point of view the microkernel architecture is superior to the monolithic kernel.
Furthermore, with only a few thousands lines of code, unlike the Linux Kernel, its consumable in a realistic timetable.
And its a real serious project, the European Union sponsored some Millions towards it as far as i am aware of. I think i remind him saying that in one of his talks.
And you have a X-Server running there, a gcc-toolchain etcpp.
Have fun :)
EDIT: As i read the comments, someone mentions the Ruby interpreter. Its written in a mixture of C and Ruby, and as far as it was mentioned in one episode of se-radio.net, it is really nice sourcecode. Though i have to admit, i havent looked into it myself. Might be worth the dig into it if you have some interest in Ruby too.

I'd suggest looking at some (for you) interesting open source projects written in C. For example, there's busybox, a piece of software that runs on embedded devices and has lots of smaller programs to study. You could, for example, take the source for the telnet client on one side and the corresponding RFC on the other. Or, for a steeper learning curve, you could also try studying the open source OSes, like the Linux kernel (here's the tree for browsing) or the BSDs. It's a lot more involved than busybox, but you can still find some parts that are fairly easy to understand if you're familiar with the context.

Studying the Linux kernel, maybe in conjunction with one of the several books on the kernel or device drivers would provide a wealth of material. Much of this is available free.
any or all of the books by W. Richard Stevens that walk though the implementation (TCP/IP Illustrated) or use (UNIX Network Programming) of the networking stack or his Advanced Programming in the UNIX Environment book.
If you have a leaning toward Windows there are several good books, even if they're quite old, including:
Programming Server-Side Applications for Microsoft Windows 2000 by Richter and Clark
Programming Applications for Microsoft Windows by Richter

I would suggest the following sources might be interesting r.e. Operating Systems from a learning perspective. Be aware there have been many advancements actually present in modern kernels:
The original linux code.
xv6. This is a simple unix OS that goes along with MIT's excellent OpenCourseWare course on Operating Systems.
Other ideas:
The current grub stage 1 bootloader isn't that complicated - it's pretty hard to be complicated with 512 bytes to play with.
The Linux kernel module guide gives you an introduction to building kernel modules. You could experiment with building custom, yet pointless, drivers that add say character devices to /dev/ or proc devices to /proc and work towards implementing something interesting. People have implemented web servers in kernel space...
If you want to experiment with Windows kernels, have a go with Native NT applications. I'd start with printing a pointless boot message, then move up to drivers.
Beyond that, it's hard to suggest where you might want to go. Systems level is a wide space.
In the context of low level programming, C and C++ are portable assembler. In many of the above spaces the standard library is either partially or totally missing and extra functionality may be implemented by existing parts of the system-level code you're modifying, so you have to be aware of the API functions available to you in any given space and what you need to implement yourself, as well as what your memory and processing requirements must be. For example, a bootloader written to the MBR has to use bios interrupts and starts in real (16-bit) mode. Those are the constraints of the hardware design. Likewise, functions like fopen() aren't available in kernel space since they wrap system calls - you'd need to use kernel specific constructs to achieve this if it really made sense to write a file from kernel space.

Related

Can you help improve one of my college's class on low level software and peripheral interfaces?

I am a 2nd year student at the Portuguese Engineering Faculty at the University of Oporto. I am currently studying for a Joint Degree (5 yr undergrad + masters) in Informatics and Computer engineering (which is basically software engineering :P).
I think the course is great, and well structured, but I was in for a nasty surprise.
For a class called Computer Labs (link to the syllabus, english), we have to use obsolete software - Windows 98/MS-DOS (because of protected mode limitations in XP+). I think this has no room in 2010 - even if we don't take into account the fact we should be learning multiplatform programming! All of my lecturers have made sure the software/technologies they selected was 1. updated, 2. compatible with AT LEAST the big three OSs (Mac/Win/Lin), and now this.
My knowledge of this sort of programming is insuficcient to effectively think of alternatives, but we want to change this situation for coming students.
Can I get your opinion and some suggestions for alternatives we can discuss with our lecturers? Please take the syllabus into account.
Thank you for your time!
PS: Extra info on the class here (english)
I looked at the syllabus and I think that this setup is appropriate for the goals of the class. The problem with more modern computers for a class on interfacing is that the operating system has become detached from the hardware. The HAL (hardware abstraction layer), Direct-X (graphics abstraction), and the modern toolkits for device driver development mean that interfacing to a modern Windows machine is (in my experience) more a task of understanding the security and framework requirements than it is learning what is involved in making code interact with electronic circuits. This is a course that sets the foundation for what you will learn when you get a job. It shouldn't be a course that teaches you what you will use on the job - in ten years no one will care if you had a school course interfacing to Windows Server 2010. But to add a robot control interface to the latest brain interfaced cell phone will still require an understanding of how code interacts with circuitry.
Low level programming of this sort cannot be compatible with multiple platforms. By definition, this is platform specific.
From a "working at home" point of view, it gets worse: this is hardware specific.
In my undergraduate course, we did this work on an embedded system (specifically, a Freescale HCS12 microcontroller) rather than using a general purpose PC. It still generally means that you can't work from home - we were provided with out-of-hours access to the lab - but emulators for microcontrollers tend to be about emulating the hardware rather than just getting the majority of software to work.
In terms of the syllabus you linked, we covered almost exactly the same material, with the only differences being that we used CPU12/Motorola assembly language rather than IA32 and a different set of tools. You could suggest using a simpler processor (such as the HC11 or HCS12), but the main advantage is that people expect it to be simple and understand that they can't use it at home: your situation doesn't change, but it is easier to accept.
dos is still alive and well, actively used in ATM (bank teller machines) cash registers, gas pumps, and the like. Basically is one of the most widely used embedded operating systems. The tools and (used) books, web information, etc are still available, inexpensive, etc. A balance of just the right amount of system calls with the freedom to get at the hardware without the OS getting in the way. The windows 3.x based kernels (windows 3.x up to windows 98 or maybe me) also easily allow for direct access with minimal operating system interference. Linux, Windows nt based kernels (windows nt, 2000, xp, etc) do not have those features, are too high level in their drivers, too much operating system in the way. The connection from dos/win3x to the present windows is still there and the student can then understand and use the more advanced/complicated modern operating system.
Encouraging DOS, AmigaOS, pdp-11 assembler, 6502 assembler, and the like in the curriculum is a good thing for future generations not a bad thing. Perhaps call it hands on computer history if you like but it is important to get a well rounded education in software engineering. Students will get a better understanding of the C language for example when they see the platform it was developed on/from (pdp-11/lsi-11). pdp11 is probably one of the best first assembly languages to teach (or msp430) and x86 is clearly the last you would ever teach if ever. (well briefly touching on I/O mapped memory vs memory mapped memory is important, also segmented architectures and how they were used instead of mmus is important, perhaps taught along side some harvard and other now less popular architectures).
Behind the curtain knowledge is dropping off at an alarming rate in the software industry. To the point of being a crisis. Fixing that starts at the schools. You cannot learn it with linux or windows 7 or anything like that.
If you want to replace this class with something else then non-operating system (non-rtos) microcontroller work. msp430 or ARM are good platforms for teaching C interrupts, have good tools, are good instruction sets for teaching for the some assembly that is required. ARM being the most widely used processor today means the student would be immediately marketable for the devices using that platform (mp3 players, mobile phones, pretty much everything handheld). avr and arduino is not bad, covers the same c and interrupt thing, but is not a great instruction set for teaching.

What language to learn for microcontroller programming? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I'm getting into microcontroller programming and have been hearing contrasting views. What language is most used in the industry for microcontroller programming? Is this what you use in your own work? If not, why not?
P.S.: I'm hoping the answer is not assembly language.
In my experience, you absolutely must know C, and assembly language helps too.
Unless you are dealing with very bare-bones microcontrollers (like the RS08 series), C is by far the language of choice. Get to know C, understand functionality like volatile and const. Also understand the architecture - what is efficient, what isn't, what can the CPU do. These will differ wildly from a "desktop" environment. Learn to love stdint.h.
You will encounter C++ (or a restricted subset) as projects scale up.
However, you need to understand the CPU and how to read basic assembly as a debugging tool. You can't become an excellent embedded developer without this skillset.
What 'contrasting' views have you heard? To some extent it will depend on the microcontroller and the application. However C is available for almost all architectures (I hesitate to say all, but probably all that you will ever encounter); so on that point alone, learning C would give you the greatest coverage.
For all architectures, the availability of an assembler and a C compiler are pretty much a given. For 32-bit and most 16-bit architectures C++ will also be available. Notable exceptions I have encountered are Microchip's PIC24/dsPIC parts for which C++ is not supported by Microchip's own GNU based compiler (although 3rd party compilers may do so).
While there are C++ compilers for 8 bit microcontroller's C++ is not ubiquitous on such platforms, and often the compilers are subsets of the full language. For the types (or more specifically the size) of application for which 8-bit is usually employed, C++ may be useful but not to the extent that it is on much larger applications, so C is generally adequate.
There are lot of myths about C++ in embedded systems; while the language is larger than C and has constructs that may compromise the performance or capacity of your system, you only pay for what you use with C++. But of course if what you use is just the C subset, the C would be adequate in any case.
The point about C (and C++) is that it is a systems level language; it will run on your microprocessor with no additional support save a very simple runtime start-up to initialise the processor (and possibly external SDRAM), initialise static data, establish a stack, and in the case of C++ invoke static constructors. This is why along with target specific assembler, it is used to build operating systems and kernels - it needs no operating system or kernel itself to run.
One of the reasons I suggested that it may depend on the microcontroller is that if for example it is an ARM9 with a few Mb of external SDRAM, and at least say 4Mb Flash (also usually external - memory takes up a lot of die space), then you could run a 'heavyweight' OS on it such as Linux, WinCE, or Symbian, or even a large RTOS such as QNX or VxWorks. Then your choice of language (once you got the OS working), would be influenced by the OS, though for real-time applications C and C++ would still dominate, (or often Ada in military, avionics, and some transport applications).
For mid-size applications - a few hundred KBytes of code and data space - C# running on the .NET-Micro platform is possible; However I sat in a presentation of this at the Embedded Systems Show in the UK a few years ago, just after it was when it was launched; when I asked the question "but is it real-time", and was told, "no you need WinCE for that", there was a gasp and a groan from much of the audience, and some stopped wasting their time an left the presentation there and then (including me).
So I am still interested in the 'contrasting' opinions you have heard; because although it is possible to use other languages; the answer to your question:
What language is most used in the
industry for microcontoller
programming?
then the definitive answer is C; for the reasons I have given. For anyone who might choose to contest this assertion here are the statistics (note the different survey method after 2004 explained in the text). However just to add to the collection of alternatives, I once spent two years programming in Forth on embedded systems, and I know of people still using it, but it is a bit of a niche.
I've successfully used both C and C++ but in almost any microcontroller project you will need to be familiar with the assembly language of the target micro. If only for debugging low level hardware issues assembly will be indispensable, even if it is a cursory familiarity.
I think the hardest thing for me when moving from a desktop environment to a micro was that almost everything needs to be allocated statically. You won't often use malloc/new in a micro unless maybe it has external RAM.
I notice that you also tagged your question with FPGA and Verilog, take a look at Altium, they have a C to Hardware compiler that works really well with their integrated environment.
Regarding assembler:
Prefer C/C++ over assembler as much as possible. You'll get better productivity by writing as much as possible in C or C++. That includes being able to run some of your code on a PC, which can help developing the higher-level code (application-layer functions).
On many embedded platforms, it's good to have someone on the project who is comfortable with a little assembler. Mostly to get start-up code and interrupts going nicely, and perhaps functions for interrupt enable/disable. That's not the same as knowing it really thoroughly--just a basic working knowledge will be sufficient.
If you're porting an RTOS (e.g. µC/OS-II) to a new platform, then you'll have to know your assembler more. But hopefully your RTOS supports your platform well already.
If you're pushing up against CPU performance limits, you probably need to know assembler more thoroughly. But hopefully you're not pushing performance limits much, because that can be a drag on a project's viability.
If you're writing for a DSP, you probably need to know the DSP's assembler fairly thoroughly.
Microcontrollers were originally programmed only in assembly language, but various high-level programming languages are now also in common use to target microcontrollers. These languages are either designed specially for the purpose, or versions of general purpose languages such as the C programming language. Compilers for general purpose languages will typically have some restrictions as well as enhancements to better support the unique characteristics of microcontrollers. Some microcontrollers have environments to aid developing certain types of applications. Microcontroller vendors often make tools freely available to make it easier to adopt their hardware.
Many microcontrollers are so quirky that they effectively require their own non-standard dialects of C, such as SDCC for the 8051, which prevent using standard tools (such as code libraries or static analysis tools) even for code unrelated to hardware features. Interpreters are often used to hide such low level quirks.
Interpreter firmware is also available for some microcontrollers. For example, BASIC on the early microcontrollers Intel 8052[4]; BASIC and FORTH on the Zilog Z8[5] as well as some modern devices. Typically these interpreters support interactive programming.
Simulators are available for some microcontrollers, such as in Microchip's MPLAB environment. These allow a developer to analyze what the behavior of the microcontroller and their program should be if they were using the actual part. A simulator will show the internal processor state and also that of the outputs, as well as allowing input signals to be generated. While on the one hand most simulators will be limited from being unable to simulate much other hardware in a system, they can exercise conditions that may otherwise be hard to reproduce at will in the physical implementation, and can be the quickest way to debug and analyze problems.
You need to know assembly language programming.You need to have good knowledge in C and also C++ too.so work hard on thse things to get better expertize on micro controller programming.
And don't forget about VHDL.
For microcontrollers assembler comes before C. Before the ARMs started pushing into this market the compilers were horrible and the memory and ROM really tiny. There are not enough resources or commonality to port your code so writing in C for portability makes no sense.
Some microcontroller's assembler is less than desirable, and ARM is taking over that market. For less money, less power, and less footprint you can have a 32-bit processor with more resources. It just makes sense. Much if your code will still not port, but you can probably get by with C.
Bottom line, assembler and C. If they advertise BASIC or Java or something like that, mark that company on your blacklist and move on. Been there, done that, have the scars to prove it.
First Assembly. After C.
I think that who knows Assembly and C are better than who knows only C.

Developing a non-x86 Operating system [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I have to choose a thesis topic soon and I was considering implementing an operating system for an architecture that is not x86 (I'm leaning towards ARM or AVR). The reason I am avoiding x86 is because I would like to gain some experience with embedded platforms and I (possibly incorrectly) believe that the task may be easier when carried out on a smaller scale. Does anyone have any pointers to websites or resources where there are some examples of this. I have read through most if not all of the OSDev questions on stack overflow, and I am also aware of AvrFreaks and OSDev. Additionally if anyone has had experience in this area and wanted to offer some advice in regards to approach or platform it would be much appreciated.
Thanks
Developing an (RT)OS is not a trivial task. It is very educational though. My advice to you is to start hardware independent. PC is a good starting point as it comes with plenty of I/O possibilities and good debugging. If you create a kind-of-virtual machine application, you can create something with simple platform capabilities (console output, some buttons/indicators are a good start). Also, you can use files for instance, to output timing (schedules) If you start on 'bare metal' you'll have to start from scratch. Debugging on a LED (on/off/blinking) is very hard and time consuming. My second advice is to define your scope early: is it the scheduler, the communication mechanisms or the file systems you're interested at... ? Doing all can easily end up in a life long project.
Samek, Miro, Practical UML Statecharts in C/C++ contains some interesting sections on a microkernel. It's one of my favorite books.
Advanced PIC Microcontroller Projects in C: From USB to RTOS with the PIC 18F Series
seems to cover some of your interests; I haven't read it yet though. Operating Systems: Internals and Design Principles may also bring good insights. It covers all aspects from scheduler to network stack. Good luck!
Seems like you should get a copy of Jean Labrosse's book MicroC/OS.
It looks like he may have just updated it too.
http://micrium.com/page/press_room/news/id:40
http://micrium.com/page/home
This is a well documented book describing the inner workings of an RTOS written in C and ported to many embedded processors. You could also run it on a x86, and then cross compile to another processor.
Contiki might be a good thing to research. It's very small, runs on microcontrollers, and is open source. It has a heavy bias towards networking and communications, but perhaps you can skip those parts and focus on the kernel.
If you choose ARM, pick up a copy of the ARM System Developer's Guide (Sloss, Symes, Wright). Link to Amazon
Chapter 11 discusses the implementation of a simple embedded operating system, with great explanations and sample code.
ARM and AVR are chalk and cheese - you've scoped this very wide!
You could produce a very different and more sophisticated OS for ARM than AVR (unless you are talking about AVR32 perhaps - which is a completely different architecture?).
AVR would be far more constraining to the point that the task may be just to trivial for the scope of your thesis. Even specifying ARM does not narrow it down much; low-end ARM parts have small on-chip memories, no MMU and simple peripherals; higher end parts have an MMU, data/instruction caches, often a GPU, sometimes an FPU, hardware Java bytecode execution, and many other complex peripherals. The term 'ARM' covers ARM7, ARM9, ARM11, Cortex M3, Cortex M8, plus a number of architectures intended for use on ASICs and FPGAs - so you need to narrow it down a bit perhaps?
If you choose ARM, take a look at these resources. Especially the Insider's Guides from Hitex, and the "Building bare-metal ARM with GNU", they will help you get your board 'up' and form starting point for your OS.
Silly as it may sound, I was recently interested in the Arduino platform to learn some hacking tricks with the help of more experienced friends. There was also this thread for a guy interested in writing an OS for it (although not his primary intention).
I think the Arduino is very basic and straightforward as an educational tool for such endeavors. It may worth the try checking it out if it fits the bill.
The first thing I recommend is to narrow your thesis topic considerably. OSs are ubiquitous, well researched and developed. What novel idea do you hope to pursue?
That said, the AvrX is a very small microkernel that I've used professionally on AVR microcontrollers. It is written in assembly. One person started to port it to C, but hasn't finished the port. Either finalizing the port to C and/or making a C port to the AVR32 architecture would be valuable.
An OS shall not be tightly coupled to any processor so ARM or x86 doesn't matter.
It will be a bigger topic, if we start discussing if ARM is embedded and x86 is not. Anyway, there are many many places in which x86 processors are used for embedded software development.
I guess most of the kernel code will be just plain C lanugage. There are many free OS that are already available, like for example, embedded linux, Free version of Itron, minix, etc ... It will be a daunting task.
But on the other hand, what you can try is, port embedded linux to platforms in which it is not yet working. This will be really useful to the world.
An RTOS is almost never architecture specific. Refer to any RTOS architecture available on the net and you will notice that a CPU/Hardware abstraction layer abstracts out the CPU. The board specific portions (that deal with peripherals such as com ports, timers etc.) are abstracted by a board support package.
To begin with, get an understanding of how multi-threading works in a RTOS try implementing a simple context switch code for the CPU of your choice; this will involve code for creating a thread context, saving a context and restoring a saved context. This code will form the basis of your hardware abstraction layer. The initial development can easily be accomplished using a software simulator for the selected CPU.
I agree with the poster who suggested reading the book, uCOS-II by Jean Labrosse. Samples of context switch code, especially for x86, should be just a google search away!
http://www.amazon.com/Operating-Systems-Design-Implementation-3rd/dp/0131429388
Pretty solid stuff.

What sort of businesses still hire C programmers? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm starting a job search, ideally ending up at a C shop. So far, I'm coming up empty in my local ads, and am starting to think I need to broaden my search, targeting specific types of businesses.
So, what type of places typically use this language?
C is typically used for fairly low-level development. You'll see it used in embedded systems, frequently, which is often listed as a computer engineering position (rather than computer science, or software engineering.) C is also used frequently for device drivers and 'generic' low-level code like math utility code for larger projects.
Generally the sorts of jobs that -need- C are taken by developers who've been using it forever, and have likely been in that position a long time.
Just keep looking! C is a rarity in terms of seeing a job just listed as "C Developer" as you've seen - so obviously they'll just be hard to find.
But I'd just wonder why you're exclusively looking for a C job as opposed to a language like C++ or Objective C :)
Edit:
Just a little note also, not to mislead you with the answer; C is still used for a lot of different stuff. Browsers, instant messengers, server daemons, the network code for even some code written on other languages even. The problem is this is just inefficient in terms the amount of time spent doing the work when you easily write it in Python, on .NET, or any number of other technologies. As such, it just isn't common, but the work can exist.
I work primarily as a C (and Perl) developer, because the application is mature, with a fairly long history (i.e. originally developed in the early 90s). The application suite originally was developed for Unix based graphical workstations. My previous job was a similar situation, a mature distributed application that was developed on multiple Unix platforms, originally in the early 1990s, and due to the source code size and maturity, it would be difficult to justify simply throwing that code base away to move to a new development language or even migrating to C++.
I would imagine there are still a number of larger in-house (used for internal purposes, not sold as a product) applications written in C that are still being maintained. Not entirely unlike the massive COBOL applications that large companies (insurance, finance, banking) that are also still being maintained.
For new development in C, others have already mentioned the embedded systems market, where the development is often for software put into ROM or EEPROM / flash memory where it is referred to as firmware, for microcontrollers (Microchip PIC, Atmel AVR, 80C51, 68HC11, etc.), where object code size, RAM usage, and performance matters so the usage of a programming language with fewer high-level or generic abstractions or assumptions is desirable.
One critical thing about good to great C programmers, is that they are expected if not required to know more about data structures and algorithms. Priority Queues, Binary Trees, MergeSort, QuickSort, Knuth-Morris-Pratt, and Karp-Rabin should be at least vaguely familiar. This is because the C language lacks the STL, Boost, CPAN, and other standard libraries available in other languages. This is at least partly because most implementations are type-specific (due to lack of templates or dynamic typing or similar mechanism) to have generic enough routines to be useful in practise.
Knowing more than one programming language is not a bad thing, even if you don't feel comfortable enough to claim to be comptent enough to program in the additional langages professional. A "modern" scripting or "trendy" web development language might be a good match. Perl, Python, and Ruby are good potential candidates.
For programming experience, functional languages like LISP, Scheme, Prolog*, ML, Objective Caml, Haskell, and Scala are good candidates for making you "think different." Admittedly Prolog is actually a declarative logic programming language, but it is still programming experience expanding.
To add on to Anthony's excellent answer, C is still used extensively in the development of operating systems and firmware, so you may want to try looking in that direction as well.
Good luck in your search for a job.
Things that must run close to the metal, and be fast.
So in addition to what Anthony wrote -- networking protocols, storage device drivers, file systems, the core of operating systems, are still big on C.
Because the focus of interest has commonly moved to applied and web development where you can't do much with C.
Either extend your search geography to other cities/countries or follow the industry trend and learn something new.
Most C programming jobs are in "embedded systems" ... things like televisions, cars, phones, alarms, clocks, toys. Such applications are often memory-constrained by cost reasons, so higher-level languages (eg, Python) are not an option there.
At a time when C and C++ were the predominant coding environments, it was said that 90% of the C programming jobs were for embedded work. Stuff that isn't advertised as software, and for which there are rarely any famous names or faces associated. This is even more the case today.
Linux is completely in C. So any company that contributes to Linux is likely to employ C coders. I worked for an industrial automation company that developed in C. Though most automation shops run PLCs and ladder logic.
iPhone development shops online. Try craigslist as well.
Objective-C is a slim superset of C, so your C skills translate nicely.
Good luck!

What type of programs are best written in C [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Joel and company expound on the virtues of learning C and how the best way to learn a language is to actually write programs using that use it. To that effect, which types of applications are most suitable to the C programming language?
Edit:
I am looking for what C is good at. This likely does not coincide with the best way of learning C.
Code where you need absolute control over memory management. Code where you need to be utterly in control of speed versus memory trade-offs. Very low-level file manipulation (such as access to the raw devices).
Examples include OS kernel, and embedded apps.
In the late 1980s, I was head of the maintenance team on a C system that was more than a million lines of code. It did database access (Oracle), X Windows graphics, interprocess communications, all sorts of good stuff. It ran on VMS and several varieties of Unix. But if I were to recreate that system today, I sure wouldn't use C, I'd use Java. Others would probably use C#.
Low level functions such as OS kernel and drivers. For those, C is unbeatable.
You can use C to write anything. It is a very general purpose language. After doing so for a little while you will understand why there are other "higher level" languages available.
"Learn C", by all means, but don't don't stick with it for too long. Other languages are far more productive.
I think the gist of the people who say you need to learn C is so that you understand the relationship between high level code and the machine internals and what exaclty happens with bits, bytes, program execution, etc.
Learn that, and then move on.
Those 100 lines of python code that were accounting for 80% of your execution time.
Small apps that don't have a UI, especially when you're trying to learn.
Edit: After thinking a little more on this, I'd add the following: if you already know a higher-level language and you're trying to learn more about C, a good route may be to not create a whole new C app, but instead create a C DLL and add functions to it that you can call from the higher language. In this way you can replace simple functions that your high language already has to ensure that you C function does what it should (gives you pre-built testing), lets you code mostly in what you're familiar with, uses the language in a problem you're already familiar with, and teaches you about interop.
Anything where you think of using assembly.
Number crunching (for example, libraries to be used at a higher level from some other language like Python).
Embedded systems programming.
A lot of people are saying OS kernel and device drivers which are, of course, good applications for C. But C is also useful for writing any performance critical applications that need to use every bit of performance the hardware is capable of.
I'm thinking of applications like database management systems (mySQL, Oracle, SQL Server), web servers (apache, IIS), or even we browsers (look at the way chrome was written).
You can do so many optimizations in C that are just impossible in languages that run in virtual machines like Java or .NET. For instance, databases and servers support many simultaneous users and need to scale very well. A database may need to share data structures between multiple users (threads/processes), but do so in a way that efficiently uses CPU caches. In C, you can use an operating system call to determine the size of the cache, and then align a data structure appropriately to the cache line so that the line does not "ping pong" between caches when multiple threads access adjacent, but unrelated data (so called "false sharing). This is one example. There are many others.
A bootloader. Some assembly also required, which is actually very nice..
Where you feel the need for 100% control over your program.
This is often the case in lower layer OS stuff like device drivers,
or real embedded devices based on MCU:s etc etc (all this and other is already mentioned above)
But please note that C is a mature language that has been around for many years
and will be around for many more years,
it has many really good debugging tools and still a huge number off developers that use it.
(It probably has lost a lot to more trendy languages, but it is still huge)
All its strengths and weaknesses are well know, the language will probably not change any more.
So there are not much room for surprises...
This also means that it would probably be a good choice if you have a application with a long expected life cycle.
/Johan
Anything where you need a minimum of "magic" and need the computer to do exactly what you tell it to, no more and no less. Anything where you don't trust the "magic" of garbage collection to handle your memory because it might not be as efficient as what you can hand-code. Anything where you don't trust the "magic" of built-in arrays, strings, etc. not to waste too much space. Anything where you want to be able to reason about exactly what ASM instructions the compiler will emit for a given piece of code.
In other words, not too much in the real world. Most things would benefit more from higher level abstraction than from this kind of control. However, OS code, device drivers, and a few things that have to be near optimal in both space and speed might make sense to write in C. Higher level languages can do pretty well competing with C on speed, but not necessarily on space.
Embedded stuff, where memory-usage and cpu-speed matters.
The interrupt handler part of an OS (and maybe two or three more functions in it).
Even if some of you will now start to bash heavily on me now:
I dont think that any decent app should be written in C - it is way too error prone.
(and yes, I do know what I am talking about, having written an awful lot of code in C myself (OSes, compilers, VMs, network protocols, RT-control stuff etc.).
Using a high level language makes you so much more productive. Speed is typically gained by keeping the 10-90 rule in mind: 90% of CPU time is spent in 10% of your code (which you should optimize first).
Also, using the right algorithm might give more performance than optimizing bits in C. And doing things right in C is so much more trouble.
PS: I do really mean what I wrote in the second sentence above; you can write a complete high performance OS in a high level language like Lisp or Smalltalk, with only a few minor parts in C. Think how the 70's Lisp machines would fly on todays hardware...
Garbage collectors!
Also, simply programs whose primary job is to make operating-system calls. For example, I need to write a short C program called timeout that
Takes a command line as argument, with a number of seconds for that command to run
Forks two child processes, one to run the command and one to sleep for N seconds
When the first of the child processes exits, kills the other, then exits
The effect will be to run a command with a limit on wall-clock time.
I and others on this forum have tried several different solutions using shells and/or perl. All are convoluted and none quite do the right thing. In C the solution will be easy, because all the OS facilities are right where you can get at them.
A few kinds that I can think of:
Systems programming that directly uses Unix/Linux or Win32 system calls
Performance-critical code that doesn't have much string manipulation in it (e.g., number crunching)
Embedded programming or other applications that are severely resource-constrained
Basically, C gives you portable, efficient access to the native capabilities of the machine; everything else is your responsibility. In particular, string manipulation in C is tedious, error-prone, and generally nasty; the most effective way to do extensive string operations with C may be to use it to implement a language that handles strings better...
examples are: embedded apps, kernel code, drivers, raw sockets.
However if you find yourself more productive in C then go ahead and build whatever you wish. Use the language as a tool to get your problem solved.
c compiler
Researches in maths and physics. There are probably two alternatives: C and C++, but such features of the latter as encapsulation and inheritance are not very useful there. One could prefer to use C++ "as a better C" or just stay with C.
Well most people are suggesting system programming related things like OS Kernels , Device Drivers etc. These are difficult and Time consuming. Maybe the most fun thing to with C is console programming. Have you heard of the HAM SDK? It is a complete software development kit for the Nintendo GBA , and making games for it is fun. There is also the CC65 Compiler which supports NES Programming (Althought Not Completely). You can also make good Emulators. Trust Me , C is pretty helpful. I was originally a Python fan, and hated C because it was complex. But after yuoget used to it, you can do anything with C. Now I use CPython to embed Python in my C Programs(if needed) and code mostly in C.
C is also great for portability , There is a C Compiler for like every OS and Almost Every Console And Mobile Device. Ive even seen one that supports some calculators!
Well, if you want to learn C and have some fun at the same time, might I suggest obtaining NXC and a Lego Mindstorms set? NXC is a C compiler for the Lego Mindstorms.
Another advantage of this approach is that you can compare the effort to program the Mindstorms "brick" with C and then try LEJOS and see how it goes with Java.
All great fun.
Implicit in your question is the assumption that a 'high-level' language like Python or Perl (or Java or ...) is fast enough, small enough, ... enough for most applications. This is of course true for most apps and some choice X of language. Given that, your language of choice almost certainly has a foreign function interface (FFI). Since you're looking to learn C, create a module in the FFI built in C.
For example, let's assume that your tool of choice is Python. Reimplement a subset of Numpy in C. Since C is a pretty fast language, and has, in C99, a clear numeric library interface, you'll get the opportunity to experience the power of C in an appropriate setting.
ISAPI filters for Internet Information Server.
Before actually write C code, i would suggest first read good C code.
Choose subject you want to concentrate on, basically any application can be written in C, but i assume GUI application will be not your first choice, and find few open source projects to look into.
Not any open source project is best code to look. I assume that after you will select a subject there is a place for another question, ask for best open source project in the field.
Play with it, understand how it's working modify some functionality...
Best way to learn is learn from somebody good.
Photoshop plugin filters. Lots and lots of interesting graphical manipulation you can do with those and you'll need pure C to do it in.
For instance that's a gateway to fractal generation, fourier transforms, fuzzy algorithms etc etc. Really anything that can manipulate image/color data and give interesting results
Don't treat C as a beefed up assembler. I've done some serious app's in it when it was the natural language (e.g., the target machine was a Solaris box with X11).
Write something with some meat on it. Write a client server chess program, where the AI is on a server and the UI is displaying in X11; once you've done that you will really know C.
I wonder why nobody stated the obvious:
Web applications.
Any place where the underlying libraries are entirely in C is a good candidate for staying in C - openGL, Lua extensions, PHP extensions, old-school windows.h, etc.
I prefer C for anything like parsing, code generation - anything that doesn't need a lot of data structure (read OOP). It's library footprint is very light, because class libraries are non-existent. I realize I'm unusual in this, but just as lots of things are "considered harmful", I try to have/use as little data structure as possible.
Following on from what someone else said. C seems a good language to implement the language in which you write the rest of your software.
And (mutatis mutandis) the virtual machine which runs the rest of your software.
I'd say that with the minuscule runtime environment and it's self-contained nature, you might start by creating some CLI utilities such as grep or tail (or half the commands in Unix). Anything that uses only STDOUT, STDIN and file manipulation is a good candidate.
This isn't exactly answering your question because I wouldn't actually CHOOSE to use C in such an app, but I hope it's answering the question you meant to ask--"what would be a good type of app to use learn C on?"
C isn't actually that bad a language--it's pretty easily to understand your code at an assembly language level which is quite useful, and the language constructs are few, leaving a very sparse language.
To answer your actual question, the very best use of C is the one for which it was created--porting itself (and UNIX) to other CPU architectures. This explains the lack of language features very well; it also explains the existence of Pointers which are really just a construct to make the compiler work less--any code created with pointers could be created without it (just as well optimized), but it becomes much harder to create a compiler to do so.
digital signal processing, all Pure Data extensions are written in C, this can be done in other languages also but has had good success in C

Resources