- Just Enough C for PHP
- Just Enough C for PHP: Running C Programs
- Just Enough C for PHP: Variables and Types
- Just Enough C for PHP: C Macros
- There’s no Such Thing as PHP
- Just Enough C for PHP: Make Basics
In our last article, we promised to show you how to run a simple hello world program written in C
//File: main.c
#include<stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
If you’re lucky, and your computer already has the tools you’ll need to work with C, all you’ll need to do is create the above main.c
text file, and then run the following terminal commands
$ cd /path/to/c/programs
$ cc main.c
$ ./a.out
Hello World
If you’re not lucky, you’ll need to install a few tools to work with C programs. Also, even if you are lucky, you’re probably wondering what the heck cc
and a.out
are. That’s what we’re going to talk about today.
You can’t Run a C Program
If you’re used to higher level languages, you may take “running” programs for granted. Google Chrome, the world’s most popular web browser, comes equipped with a javascript console that lets you run a javascript program line-by-line. Many modern languages also have some form of command line program runner
$ node program.js
$ python program.py
$ ruby program.rb
$ php program.php
$ go run program.go
You can’t, however, run a C program like this. At least not directly.
Instead, you compile a C program. Compiling a C program turns it into something called machine code. Machine code is binary code that’s directly executable by your computer’s CPU. (this is a bit of an over simplification — just roll with us if you already know this)
Before C, computer programs were often written in a language called assembly. Assembly allows you to invoke specific instructions on your computer’s CPU — things as low level as “flip this one particular memory bit”. Aside from being a tedious way to program, assembly programs usually target one particular CPU architecture. This means if you write your program to target an Intel chip there is no easy way to run your program on a Motorola chip.
This was one of C’s big innovations. With C, programmers can write a program for one sort of computer, and (with some caveats) compile it to run on many other types of computer.
If you didn’t completely follow that, don’t worry. In 2017 you can get started with C without understanding things like chip architecture and assembly instructions. For now, all you need to know is this: Running a program in C is a two step, rather than one step, process.
The C Compiler
If we jump back to those optimistic commands we had you run
$ cc main.c
$ ./a.out
The cc
command is a c
c
ompiler. In its simplest invocation, you pass cc
a single C file (main.c
above) and cc
produces an executable program. That program is, by default (and for historical purposes), named a.out
, but you can name it anything you like. When we say
$ ./a.out
we’re running the executable of our program that the c compiler created for us.
The cc
command is a long standing c programming convention. While it may have once referred to a specific program named cc
, these days it’s almost always a symlink that points to whatever C compiler you’re using.
For example, on my OS X 10.11 Macintosh computer, cc
is a symlink that points to a program named clang
$ ls -lh /usr/bin/cc
lrwxr-xr-x 1 root wheel 5B Mar 10 2016 /usr/bin/cc -> clang
Clang is — well, clang is hard to describe unless you’re immersed in the culture of C based languages. One way to think of clang is a general purpose front end for compilers, and supports all sorts of C languages. For our purposes just think of it as our compiler.
On linux systems cc
may point to a program called GCC. GCC is the GNU project’s open source set of compiler tools and a popular choice for people writing C programs (and the de facto choice before clang
came around).
Developing compilers is a topic unto itself that we’re not going to cover, and that you’re probably not quite ready for. It’s important for you to know that compilation is happening, and that different compilers might behave slightly differently, but beyond that you don’t need to sweat the details before you’re ready to.
Installing A Compiler
Before we can explain our hello world program, we’ll need to get everyone up and running with a C compiler.
If you’re running OS X or MacOS, you’ll need to install the Apple provided developer tools, or do a full install of Apple’s Xcode IDE. This used to be software bundles on an extra CD that shipped with your Mac or a downloadable installer package. These days it seems like any attempt to use a developer tools command line program will resulting in an installation prompt.
If you’re on a linux machine and don’t already have access to a cc
command, you’ll want to use your standard package manager (apt-get
, yum
, etc.) to install clang or gcc.
$ sudo apt-get install clang
$ sudo yum install clang
$ sudo apt-get install gcc
$ sudo yum install gcc
Once you have a working cc
command (or a clang
command, or a gcc
command), give our steps another try and you should get a working hello world program.
$ cd /path/to/c/programs
$ cc main.c
$ ./a.out
Hello World
Congratulations! You’re now a C programmer!
Explaining the Program
Compiler discussion out of the way, we’re ready to talk about our program. If you’ve written a hello world program in another language, it probably looked something like this
print "Hello World";
Our C program, while not super complicated, isn’t quite as terse as a modern language
//#File: main.c
#include<stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
We’re going to run through each part of this program and explain what it does. First is this line
//#File: main.c
#include<stdio.h>
This is a C include statement. An include statement imports functions from another C library for us to use. This particular include statement lets us call functions from the stdio
library. This library contains st
and
ard i
nput and o
utput functions in our program, and will let us use the printf
function later on.
The starting #
, <
, and >
characters — as well as the .h
— are all part of a standard C include. We’ll explain why they’re here in a future article, but for now just accept them as part of the standard boilerplate, the same way you accept the word include
.
Next, we have a function definition.
//#File: main.c
int main()
{
/* ... */
return 0;
}
Every C program has a single function named main
. This function is the program’s main entry point. That is, you can’t just write a C program like this
#include<stdio.h>
printf("Hello World\n");
If you tried compiling the above program, you’d end up with a confusing error — something like this.
$ cc main.c
main.c:3:8: error: expected parameter declarator
printf("Hello World\n");
^
main.c:3:8: error: expected ')'
main.c:3:7: note: to match this '('
printf("Hello World\n");
^
main.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
printf("Hello World\n");
^
main.c:3:1: error: conflicting types for 'printf'
/usr/include/stdio.h:259:6: note: previous declaration is here
int printf(const char * __restrict, ...) __printflike(1, 2);
Don’t worry too much about the specifics of these errors (although we hope you’ll understand them by the end of this series). For now, your main take away should be that C forces you to start your program inside a function named main
.
If we take another look at that function definition
//#File: main.c
int main()
{
/*...*/
return 0
}
In C, every function definition starts with a type. Above, that’s int
(i.e. an integer type). Other types include (but are not limited to) char
(for a single character), or void
(indicating no return types). It’s also possible for program writers and library authors to create their own types.
A function’s type indicates what sort of value the function will return. Traditionally, main
‘s return value is used as the unix exit code for a program (0
meaning “everything is normal and went well”).
Finally, we have the single line that prints our hello world for us
//#File: main.c
int main()
{
printf("Hello World\n");
return 0
}
This is a call to a function named printf
, (defined in in the stdio
library), with us passing a single string constant ("Hello World\n"
). This is the code that prints Hello World to our terminal screens. Make sure that you use double quotes for your string values. Single quotes ('
) have a different meaning that we’ll cover in a future article.
Wrap Up
That’s it for today! We’ve created a simple Hello World C program, compiled that program, and ran its executable file. We’ve also briefly discussed what a compiler is, what it does, and how it’s a little different from the enviornment you may be used to. We also briefly discussed defining functions in C, as well as calling functions from a standard C library.
Next time we’ll be covering the basics of C variables, as well as defining a few functions of our own.