Review of C Programming

[Note: this webpage last modified Thursday, 25-Apr-2013 13:40:42 EDT]

Table of Contents

  1. C Language
  2. Standard functions
  3. Not on the exam

The first section here are all the different parts of the C language we have learned so far.

Statements

variable declaration

int x;
char y;
int z = 3;
Create a new variable. You specify the type and the name. You can also give an initial value for the variable.

assignment

int x=2; 
x = 22*x;
Variable goes on the left, some expression on the right. First, figure out what the expression on the right evaluates to, then save that into the variable.

expression

int x=0;
x+2;
Technically, you can do this. It computes x+2 but then doesn't do anything with it.

increment/decrement

int x=0;
x++; x--; x+=2; x*=3; x/=4; x-=5;
These all change the value of x. ++ adds one, -- subtracts one. The others are short-hand. For example, x+=2 is the same as x=x+2.

function call

printf("Cheers.\n");
Look up the function of that name and run it.

compound statement

{
  int x=3;
  printf("%d\n", x);
}
Technically, the {} and everything in between them is viewed as a single "compound" statement. So with an if, the rule is that it does the next statement. If there are {} right after the if test, then the next statement is a compound statment that includes everything in the {}.

if/else

int x = 5 / 2;
if (x == 2) printf("Integer division.\n");
else  printf("Float division.\n");
Test if the expression in () is true or false. If it is true, then do the next statement. If there is an else, then otherwise do the statement after the else keyword. If there is no else, then if the condition is false then nothing happens.

while

int x=1;
while (x<100) {
  x = x * 2;
  printf("%d\n", x);
}
Test the expression in the (). If it is true then do the next statement. Then check the expression again. Keep doing the statement after the expression as long as the expression is true.

for

int i; char s[100];
for(i=0;i<5;i++) {
  printf("Why? ");
  scanf("%99s", s);
}
The i=0 is the initializer. The i<5 is the condition. And the i++ is the increment. The initializer and increment can be any simple statement - assignment, function call, increment/decrement... Normally the initializer is an assignment of the index or counter variable, and the increment is an increment or decrement of the index or counter variable.

First the initializer is run. Second, the condition is checked. If it is true then the body of the for loop is run. After the body is run, the increment is executed. Then the condition is checked, and the whole process keeps repeating as long as the condition is true.

Includes, defines

#include

#include <stdio.h>
#include <stdlib.h>
These are needed because they load up functions like printf and scanf for us to be able to use. If you're using string functions, also include string.h. If you're doing curses, include curses.h. If you're using the time with the random number stuff, include time.h. If you want to use cos, sin, etc. then include math.h

#define

#define ROWS 10
This tells the program to search through your code and everywhere it sees the word ROWS, it replaces it with 10. Note that it would not replace ROWS in ROWSblah.

Data types

integers

int x;
char y;
short z;
long long int w;
int is normally a 32-bit integer (that's 4 bytes). char is a character but can also be viewed as an 8-bit integer. short is 16 bits. long long int is 64 bits. These depend on the compiler you're using, but that's what they normally are on most of today's computers.

These all have maximum and minimum possible values. About half of the values are negative and half are positive. A char can be between -128 and 127. An int can be between -231 and 231-1. If you have a char that has the value 127 and you add 1 to it, you may get -128.

floats

float x=3.14;
Numbers with decimal points. float uses 32 bits of storage. Some part of that is for the "mantissa" and some part is for the exponent. For example, the number 6.02 x 1023 needs to store 602 for the mantissa, and store 23 for the exponent. The point is there are limits for floats too - normally the exponent can be between -38 and 38, and the mantissa is about 6 digits. You can use the type
double
for a 64-bit floating point variable that can be larger/smaller and has more digits of precision.

characters

char x='3'; char y='\n';
Characters are thought of as the characters that get printed, or as integers. '3' is equivalent to the integer from the ASCII table for '3'. '\n' is a single character, not two. It is called an escape character, and represents enter being pressed. '\t' stands for tab.

strings

char s[100]="hi there.";
A string is an array of characters. There will be a '\0' character at the end to mark the end of the string.

true/false

int x=1;
There is not data type for true/false. If you want a true/false variable then you need to declare an integer. 0 means false and anything else means true. So if you do
x = (1 < 2);
then x would have the value 0.

Arrays

int x[10];
You have one variable name for 10 different integers. You get the i-th by doing x[i]. You can use that to get the value or to update it. To change the first number in that array, you'd do
x[0] = 42;
You can also do arrays of arrays. An array of strings is like
char s[3][100]= {
"hello.\0",
"good bye.\0",
"Oh sadness.\0"};

Punctuation

, comma

void myFunction(int x, char y) 
...
myFunction(3, 2);
printf("Hi %s\n", name);
char z, w;
Used to separate parameters when declaring functions, arguments to functions when calling them, and variables when declaring them.

; semicolon

int x;
Every statement ends in a ;

() parentheses

void myFunction(int x, char y)
...
myFunction(3, 2);
int x = (3+2)/2;
Used when declaring a function, when calling a function, and for grouping in expressions.

{} curly braces

int main(int argc, char *argv[]) {
while (0 == 0) {printf("Forever...\n");}
return 0;
}
Used to group all the statments in a function, and to make a compound 
statement for the body of a for, if, else, or while loop.

[] square braces

int x[10];
x[0] = 3;
Used to declare an array and the access individual items in the array.

< and >

#include 
...
if (3 <= 3) printf("blah...");
Used in comparison of things and also in the #include.

*

int y = 3 * 3;
int *x = &y;
printf("y = %d", *x)
Used for multiplication and also with pointers. For pointers, used to declare a pointer variable, and also used to take the value of where a pointer value points to.

&

int y; scanf("%d", &y);
Used to take the memory address of a variable. Used with pointers and scanf.

*, +, /, -, %

int x = 3 * 4 / 2 - 10 % 3;
Arithmetic. % is called mod or modulus and is the remainder after division. So 10 % 3 is 1. / with integers is integer division, so 10 / 3 would be 3.

The order of operations is: (1) *, /, and %, then (2) + and -. And from left-to-right within each category. Any of that can be overriden by using ().

// and /* */

//bla blah
/*bla 
blah*/
// is a comment from there to the end of the line. Anything inside of /* and */, even on multiple lines, is a comment. The compiler ignores comments.

' ' single quotes

char ch = 'x';
Used for specifying a single character.

" " double quotes

char s[100] = "hello";
printf("%s is the word of the day.\n", s);
Used for specifying a string of characters.

Boolean operators

&& and

if (x > 10 && x < 20) ...
Expression is true only when both of the sides are true.

|| or

if (x < 10 || x > 20) ...
Expression is true if either of the sides are true (or both).

! not

if (! x < 10) ... 
Expression is true if the expression right of ! is false, and is false otherwise.

Comparison operators

<, <=, >, >=, ==, != Used to compare values. Note that == is used to compare, while = is used for assignment. Don't mix them up! Also, don't use == with floating point values. The reason is that there are often found-off errors so even if two floating point values should be the same, they might be different by .000000001.

Functions

// see examples from class...
There are two parts to using functions. First, you need to define a function. For that, you give the return type, the name of the function, declaration of parameters inside (), then function body inside {}. Second, you call the function.

When you call the function, there are three main things that happen. First, values are copied from where you're calling the function into the parameters of the function. Second, the body of the function is run. Third, if there is a return statement, then whatever is returned is sent back to whoever called the function.

Pointers

int y; int *x; 
x = &y; *x = 12; printf("%d\n", y);
A pointer is a memory address. You declare a pointer variable by using * as above. If you then just say x in your program, the program uses the memory address (which is an integer). If you want to take the value of that memory address, you use *x. If you want to get the address of another variable to put into the pointer, you use &

Arrays are also pointers. Doing

int x[100];
, then if you just say x in your program it is a pointer - the memory address of the start of the array.
The rest are all different functions we have used that you should be familiar with.

User input/output

printf

printf("Hi %s, my number is %d.  What's yours? ", "Bob", 432);
Used print formatted strings. In the first string, you specify % things for values that you will give as extra parameters. %s for string, %d or %i for integer, %f for float, %c for character, %x for hexadecimal integer.

scanf

int x; char s[100];
scanf("%d", &x); scanf("%99s", s);
Used to get formatted input from the keyboard. In the string you use the same % codes as with printf. After that, you need to give the address of the variable where the value should be stored.

Strings and characters

strlen

int i; char s[100]; scanf("%99s", s);
for(i=0;i
returns length of the string.

strcmp, strncmp

char s[100]; scanf("%99s", s);
if (strncmp(s, "blah", 100)==0) printf("Password correct.");
returns 0 if the strings are exactly the same (including case), and something not 0 otherwise.

strstr

char s[100] = "My favorite is the table.";
char *found = strstr(s, "the");
if (found == NULL) printf("the not found.\n");
else printf("String after the: %s\n", found);
Looks for "the" in s. Returns a pointer to the spot it is first found. If not found, returns NULL.

isalpha, isalnum, isdigit, islower, isupper, isprint, isxdigit, isblank, iscntrl

char ch='j';
if (isalpha(ch)) printf("%c, %d\n", ch, ch);
All of these are functions to check whether a single character is a certain type - alphabetic, alphabetic or number, number, lower-case, upper-case, printable, hex digit (includes 'x'), ...

tolower, toupper

int i; char s[100]; scanf("%99s", s);
for(i=0;i
returns the same character but either converted to lower or upper case.

atoi, atof

char s[100]; scanf("%s",s);
printf("%s * %s = %d\n", s, s, atoi(s) * atoi(s));
Returns the integer (or float) that is in the string, so then that value can be used in calculations or saved into an int or float variable.

sprintf

char s[100]; sprintf(s, "%d * %d = %d\n", 3, 6, 3*6);
Like printf, but puts the result into a string rather than displaying on the screen.

sscanf Same as scanf, but reads from the string rather than from the keyboard.

File input/output

fopen, fclose

FILE *myFile = fopen("something.txt", "r");
int x; fscanf(myFile, "%d", &x); printf("number is %d\n", x);
fclose(myFile);
fopen opens the file and returns a pointer to the file. The OS keeps track of the file for us. You need to save what fopen returns, then specify that in any other file functions. fclose closes the file.

fprintf

fprintf(myFile, "blah blah...%d\n", 234);
Same as printf but puts the result into the file rather than on the screen.

fscanf

float x; fscanf(myFile, "%f", &x);
Same as scanf, but reads from the file rather than from the keyboard.

fgetc

FILE *myFile = fopen("something.txt", "r");
char ch = fgetc(myFile); 
while ( ch != EOF) {
  printf("%c", ch);
  ch = fgetc(myFile);
}
Gets one character at a time from the file.

Random numbers

srand, rand

#include<time.h>
...
int i;
for(i=0;i<10;i++) printf("random number = %d\n", rand() % 100);
Do srand(time(NULL)) once in the program to get the random number generator started. Then call rand() each time you want a random integer.

GNU Debugger

compiling

gcc myProgram.c -g
Include a -g at the end to compile the program with debugger support.

run

gdb a.out
   (inside of gdb) run
Once gdb is started, type run to start running your program.

print

(inside of gdb) print x
If the program stopped (because you put in a breakpoint) or crashed, you might be able to print variables.

backtrace If the program crashes, type backtrace to see which functions were getting called and which line in your program is the problem.


The following will not be on the test.

Math functions

If you include math.h then you have access to: cos, sin, abs, tan, log, exp, pow.

Curses

Make sure to include curses.h and include -lncurses when you compile.

Structures

See notes.txt

Dynamic memory

We didn't cover this, but it is something important. For an example, see linkedList.c

Switch statement

We didn't cover this, but it is shorthand for choosing something to do based on the value of an integer, character, or float. In some cases, you can use this instead of a bunch of if statements.

Ternery operator

x = x > 0 ? x : -x;
Shorthand for
if (x > 0) x = x; else x = -x;

Bit operations

You can do things to the bits of a variable. The operators that do this are: ^, <<, >>, &, and |. Just be careful you don't use those accidentally if you don't know what they do.