c language concepts - cbranton/computer-system-concepts GitHub Wiki
C is like most languages you know:
- procedural and imperative
- every program is a series of statements
- code is organized into functions
- every program contains a
main
function, the entry point for the program
C is different from most languages you know:
- compiled directly to machine code; compiled units are machine-dependent
- no support for object-orientation
- less abstracted from the hardware; will deal often with addresses of variables
- small; no built-in strings or collection types
- memory management is the responsiblity of the programmer (along with much else)
The overall syntax of C is similar to Java:
- statements end with a semicolon
- blocks are delimited with
{ }
- comments are indicated by
//
for single lines and/* */
for multiline comments - libraries are included with
#include
There are plenty of differences:
- no classes or objects
- C
main
function is of typeint
. Successful programs should return 0. - the C
printf
function is primary means of output. (printf
does not automatically place a newline at the end of the string. This is the responsibility of the progammer.)
The first C program ever written printed "Hello World" to the console. It has become a traditional first program when learning a new language. Type the following into a text editor and save it as hello.c
// A first program in C
#include <stdio.h>
int main ()
{
printf("Hello World!\n");
return 0;
}
Before we can run the program we need to compile it. On a Unix or Linux operating system this is most often accomplished using the GNU C Compiler gcc. Open a terminal window and type:
gcc -o hello hello.c
The -o hello
parameter tells gcc to write the output to a file named "hello". If you omit it, the program will be written to a file called "a.out". Execute your progam by typing ./hello
at the command line.
The gcc compiler supports a host of command line options. We have already seen -o
in action. We can also tell the compiler to generate the assembly code for our program using the -S
option (note the capital letter):
gcc -S -masm=intel hello.c
The masm=intel
parameter tells gcc that we want Intel assembly dialect. The compiler supports Intel and AT&T (the default) on x86-based systems. We could use the -o
parameter, but it is not necessary. With -S
the output will be written to "hello.s" by default.
tl;dr Most things in C are integers.
For the most part, C types are similar to Java primitive types, and are declared in the same way. One difference to be aware of is that the size of C types are hardware-dependent. For example a Java int
is 32 bits (or 4 bytes) long. This is a typical size for ints in C, but is not universal. C includes a sizeof
operator that allows programs to determine the number of bytes used to store a types.
C handles characters and Boolean expressions differently than many languages. The char
type in C is an integer value that (typically) holds the ASCII value for a single character. Character literals are denoted by single quotes (e.g. 'a'
). C does not have a string type, but string literals are denoted with double quotes as we saw in our Hello World program.
Some of the implications and possibilities can be seen in the following code snippet:
ch = 'A';
printf("ch value is %d which is the ASCII value of %c\n", ch, ch);
ch = 99;
printf("ch value is %d which is the ASCII value of %c\n", ch, ch);
The output looks like:
ch value is 65 which is the ASCII value of A
ch value is 99 which is the ASCII value of c
C also lacks a Boolean type. Boolean values are also integers. Zero is interpreted as false, and all other values evaluate to true. This, and the character handling lead to the satrical (but true) assertion that a C program can add a character to an integer and ask if the result is true or false.
C also includes unsigned integer types. The unsigned versions provide an extra bit for storage, allowing larger positive numbers to be stored. Unsigned versions are denoted by prefixing the version with "unsigned", for example:
unsigned int
unsigned short
unsigned long
For the most part you can treat C conditionals and loops like their Java counterparts. One important consideration is that relational operations will evaluate to 0 or something other than zero. The nonzero value is not specified in the language specification, so you should not count on it being any particular value.
The for
loop in C is less structured than Java, though the appearance is the same. The C for loop syntax is:
for (<initialization>; <boolean expression>; <step> ) {
<body>
}
- The initialization is executed once before the loops executes.
- The boolean expression is evaluated before the loop executes each time. If it ever evaluates to zero, the loop terminates.
- The step expression is executed after each loop evaluation
- The initialization and step can include (legal) lists of comma separated expressions
- Any or all three of the parts can be empty. In other words:
for (; ; ;)
is a legal for loop declaration.
null-terminated. Must leave space for the '\0'
Which means memory should probably move up here.
struct <struct_name> {
<field 1 type> <field 1 name>;
<field 2 type> <field 2 name>;
<field 3 type> <field 3 name>;
...
};
Declaring struct variables
Declaring struct types
All parameters are passed by value.
File pointers and file descriptors
FILE object. <cstdio>
File pointer -- example file struct
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
Configure SSH if you wish to use CLion Setting up VS Code for WSL (https://code.visualstudio.com/docs/cpp/config-wsl)
https://www.jetbrains.com/help/clion/quick-tutorial-on-configuring-clion-on-windows.html