These topics are in no particular order whatsoever.
C source code files generally use the extension .c, rather than C++ extensions such as .cpp, .cc, .cxx, .C, etc.
There are a wide variety of C compilers for various platforms (just as there are a wide variety of C++ compilers). While we use g++ as our C++ compiler, we use gcc as our C compiler.
While most things with respect to compilation will be the same as with C++, you may encounter some differences in the options/flags used. Examples may include things like explicitly adding the -lm flag to compile programs that use the math library (e.g. gcc myprog.c -o myprog -lm).
This means that instead of having a method acting on a variable (e.g. mystr.length()) you have to pass the variable as a parameter to a standalone function (e.g. length(mystr)).
It also means that if you want encapsulation of code, nice modularity, etc then you'll need to come up with appropriate interfaces via .h files and make sure you adhere to those interfaces to manipulate any data.
You need to be more careful with your style and programming habits, especially in team projects, since it is easier to shoot yourself in the foot if you get sloppy.
This also means that the nice classes supplied in the C++ standard template library cannot be used in C. This includes (but isn't limited to) the following
algorithm iomanip list queue strstream bitset ios locale set typeinfo complex iosfwd map sstream utility deque iostream memory stack valarray exception istream new stdexcept vector fstream iterator numeric streambuf functional limits ostream string
C, on the other hand, uses the exact filename of the header file to be included, e.g. <stdlib.h>.
The list below identifies a handful of the libraries shared between the two languages, and the different headers for each
C++ C cassert assert.h cctype ctype.h cerrno cerrno.h cfloat float.h climits limits.h clocale locale.h cmath math.h csignal signal.h cstdarg stdarg.h cstddef stddef.h cstdio stdio.h cstdlib stdlib.h cstring string.h ctime time.h cwchar, cwctype wchar.h, wctype.h
const char c = 'c'; #define c 'c' const int i = 33; #define i 33
bool, true, and false are not a part of the C language, but it can be simulated with typedefs, enumerated types, or #defines. There is also a library, stdbool.h, which can be included and which defines bool, true, and false.
Operator overloading is not supported in C (that comes as a part of C++ classes), so don't bother trying ;-)
Namespaces are also not supported in C.
In terms of basic I/O this means using printf and scanf instead of cout and cin, respectively, and performing file I/O with fprintf and fscanf.
Output
printf is a function whose first parameter is the text
we want to print, and whose remaining parameters (if any)
are values we want to embed within the text.
We put markers, or placeholders, within the text to indicate exactly where we want the values to go, and use different types of markers to indicate what kind of data value is expected.
For example, the marker for an integer is %d, and the marker for a float is %f. The snippet below shows us embedding two floats and an int within a string of text.
int x = 1; float f = 1.1; float g = 2.5; printf("one int: %d, a float %f, another %f", x, f, g);The commonly used placeholders are
%d decimal (integers) %f real numbers (in fixed point format) %e real numbers (in scientific notation) %c character %s a text string, e.g "blah blah blah"
There are also a variety of formatting options that can be specified in the placeholder, between the % and the key letter.
For example %4.2f specifies the float is to be padded to 4 characters total with, with 2 digits shown after the decimal point.
Input
Keyboard input is performed with scanf, which takes parameters
much like printf: the first one is a text string with a placeholder
for the type of data to be read, the second parameter is the
address of the variable to hold the value read in.
For example, to read a single integer:
int i; scanf("%d", &i); /* remember the & before the variable! */scanf returns an int, specifying how many items it succeeded in reading (0 if it can't read anything that fits the specified format). Thus if we wanted to read an unknown number of ints and print them as we go, we could use
while (scanf("%d", &i) > 0) { printf("%d\n", i); }Other input options are %s for string, %x for hexadecimal, %f for fixed-point float, %e for exponential notation, %g will accept either fixed or exp notation, %c for char, %d for decimal, %o for octal, %p for pointer, etc.
If you add a * between the % and the input type specifier
it means the item read is discarded instead of stored to
a variable. For example, the following reads three ints
but discards the middle one:
scanf("%d %*d %d", &i, &j);
You can (and probably should) specify the maximum number of characters to be read into the target variable, e.g. "%10s" indicates a maximum of 10 characters.
You can also extract data from patterns of input.
For example, to read and extract three ints from input of the form
(ddd) ddd-dddd you put the non-whitespace characters
that are part of the pattern to discard (i.e. the brackets and dash)
into the format string:
int i1, i2, i3;
scanf("(%3d) %3d-%4d", &i1, &i2, &i3);
Single-character input, capturing whitespace
You can also use getc() to read a single character,
e.g.
char c = getc();
Reading data to/from text strings (char[])
You can use sscanf and sprintf to read data to/from
character arrays. The approach is the same as scanf/printf,
but you specify the character array as a first parameter, e.g.
int i; // int to translate into text
char text[80];
sscanf(text, "%d", &i);
While the basic concepts (open the file in a specific mode, read from/write to it, close the file) are the same, the specific functions used are different.
Opening the file is done with
FILE *fp = fopen("filename", "r"); /* for read mode*/
The modes are r, w, a for read, write, append.
The reading and writing are handled through fprintf and fscanf.
These correspond to printf and scanf except that they include
a file specifier before the text string, e.g.
fprintf(fp, "blah blah %d", someInt);
There is also a routine, fgets, that allows you to read
a line of text into a character array.
fgets(textArr, MaxLen, fp);
Finally, you can use fgetc(fp) to read a single character or fputc(c, fp) to write a single character.
Closing the file is done with fclose(fp)
The practical alternative is to pass a pointer to the item you want the function to modify, then dereference the pointer within the function.
For example, suppose I want to write a function to swap two ints:
/* function to swap the value of the variable * that xPtr references with the value of * the variable that yPtr references */ void swap(int* xPtr, int *yPtr) { int temp = *xPtr; *xPtr = *yPtr; *yPtr = temp; } /* example calling the function with the addresses of x and y */ int main() { int x = 3; int y = 4; swap(&x, &y); } |
Malloc needs one parameter - the number of bytes of memory which need to be allocated.
The sizeof function tells us how much space is used by a single data TYPE, e.g. sizeof(int) tells us how much space is used by an int.
If we are allocating one item of a data type we can just use the sizeof value, whereas if we are allocating an array then we need to multiply the size by how many items we need, e.g. for an array of 40 ints we would call malloc(40*sizeof(int)).
Unfortunately, malloc's return value is 'void*', which basically means a pointer of no particular type.
When we assign this to our actual pointer variable, we need to identify what kind of pointer we should treat malloc's returned value as. (There has GOT to be a better way to phrase that.)
free(ptr) releases the space when we're done with it.
The example below shows us dynamically allocating, initializing, and then deleting an array of 40 ints
int *myArray; myArray = (int*)malloc(40*sizeof(int)); int i; for (i = 0; i < 40; i++) { myArray[i] = 0; } free(myArray); |
If we populate a char array with text, we can include the null character ('\0') to mark the end of the part of the array we are using.
E.g. if I have an array of 40 characters to hold a name, and choose to store the name "Fred" in the array, I should put something after the 'd' to indicate the rest of the array isn't currently in use.
char name[40]; name[0] = 'F'; name[1] = 'r'; name[2] = 'e'; name[3] = 'd'; name[4] = '\0'; |
For example, the function below could be used to copy one 'string' into another
/* assumes destination has space for maxSize+1 chars */ int copyAstring(char source[], char destination[], int maxSize) { int i = 0; /* copy from the source to the destination, one char at * a time, until you've copied the max number of chars * or you've hit the null terminator in the source */ while ((i < maxSize) && (source[i] != '\0')) { destination[i] = source[i]; i++; } /* put the null terminator in the destination and * return the number of characters written (prior * to the null terminator) */ destination[i] = '\0'; return(i); } |
Many routines are available in the
strlen
strcpy, strncpy
strcat, strncat
strcmp, strncmp
strchr, strstr, strtok, etc