See: Using Eclipse / CDT
Functions are used in C are they are in any other high-level programming language: code reuse, modularized design, organization, and libraries.
#include <stdio.h> // library header int w; // global variable, visible from anywhere // prototypes - must appear before their call void function1(); // function prototype: no parameter, without return value int function2(int); // function prototype: int parameter, int return value int main(int argc, char *argv[]) { setbuf(stdout, NULL); int x = 2; // local variable w = 1; function1(); // function call int y = function2(x); // function call with argument and assign return value printf("%d, %d\n", w, y); return (0); } void function1() { // function definition: no parameter, without return value int y = 2; // local variable w += y; return; } int function2(int x) { // function definition: int parameter, int return value int z = x + 2; function1(); // call another function return (z); // return value }
You cannot change the contents of a parameter permanently in a function. Any changes made to the value of the parameter are lost when the function ends. You can, however, pass the address of a value to a function, and change the value at that address. (You cannot change the address - you can think of it as the value being passed to the function, and you cannot permanently change the value passed to a function.)
To specify pass-by-reference, use:
&
reference
*
dereference
// prototypes void add(int *, int); int main(int argc, char *argv[]) { setbuf(stdout, NULL); int n = 2, j = 2; add(&n, j); // pass reference to n, value of j printf("n = %d\n", n); //output: 3 printf("j = %d\n", j); //output: 2 return (0); } void add(int *x, int y) { *x = *x + 1; // dereference x - value at address changed y = y + 1; // y will be unchanged return; }
Example: swap values of two variables.
// prototypes void swap(int*, int*); int main(int argc, char *argv[]) { setbuf(stdout, NULL); int i = 5, j = 10; printf("before swap i = %d, j=%d\n", i, j); swap(&i, &j); printf("after swap i = %d, j=%d\n", i, j); return (0); } void swap(int *first, int *second) { int temp = *first; *first = *second; *second = temp; return; }
C supports recursion. C supports fruitful recursion, in-place recursion, tail recursion, and tree recursion. A given algorithm may require auxiliary recursive functions. Example:
// prototypes int factorial(int n); int main(int argc, char *argv[]) { setbuf(stdout, NULL); int n = 1, y = 1; printf("Input an integer: "); scanf("%d", &n); y = factorial(n); printf("%d! = %d\n", n, y); return (0); } int factorial(int n) { int result = 1; if (n > 1) { result = (n * factorial(n - 1)); } return (result); }
stdio
Input/Output Library
Supports the printf
(print formatted) function.
void printf("format control string"[, value][, value]… )
Format Control
%[flag][size][.precision]conversion char
From right to left:
0
for left 0 fill - numbers only -
for left justification
If a print width is defined, all values are printed right justified within
that width unless the -
(left justification) flag is set.
conversion char | description |
---|---|
%c |
character |
%d |
decimal (integer) number (base 10) |
%e |
exponential floating-point number |
%f |
floating-point number |
%i |
integer (base 10) |
%o |
octal number (base 8) |
%s |
a string |
%u |
unsigned decimal (integer) number |
%x |
number in hexadecimal (base 16) |
%% |
print a percent sign |
\% |
print a percent sign |
Example code (the vertical bars '|
' are there only to make the
print width clear:
float v = 99.9; printf("|%f|\n", v); printf("|%12f|\n", v); printf("|%12.2f|\n", v); printf("|%012.2f|\n", v); printf("|%-12.2f|\n", v); char *name = "David"; printf("|%s|\n", name); printf("|%12s|\n", name); printf("|%-12s|\n", name);
Example result:
|99.900002| | 99.900002| | 99.90| |000000099.90| |99.90 | |David| | David| |David |
(Where did the 00002
come from?)
Supports the scanf
(scan formatted) function.
int scanf("format control string"[, reference][, reference]… )
scanf
uses the same codes as printf
to tell the
program how to treat the values being read. The code and the data type must
match. The following example reads an integer, a float, and a character from
the keyboard - the values are space delimited:
int a; float b; char c; int count; count = scanf("%d %f %c", &a, &b, &c);
The count
returned by the function is the number of values
correctly read. The previous example should return a 3 if all three values
are properly read. If some values don't fit the formats, then scanf
returns a value less than 3. Unfortunately, this doesn't tell us which of
the values was not read properly. However, it is still helpful. Example:
setbuf(stdout, NULL); printf("Enter int, float, char: "); count = scanf("%d %f %c", &a, &b, &c); while (count < 3) { while (getchar() != '\n') // get rid of non-end-of-line characters ; printf("Invalid input\n"); printf("Enter int, float, char: "); count = scanf("%d %f %c", &a, &b, &c); }
Preprocessor directives start with #
. The preprocessor
resolves all preprocessor directives during pre-processing Four commonly
used cases:
#include <file> // predefined directory - on project path #include "file" // user-defined file, relative to current directory
Examples
#include <stdio.h> #include "myheader.h"
#define
, #undef
)
A macro is an identifier followed by text. Generally, an identifier must start with a letter and may contain only letters, numbers, and the underscore. It is followed by replacement text, i.e. the text that is to be written into the code in place of the identifier text. Macros can have parameters, which are comma-separated inside parentheses (and no spaces). Parameters are replaced by the matching values and variables when replaced by the preprocessor. Example:
#define GETMAX(a,b) a > b ? a : b int x = 10, y = 12; int c = GETMAX(x, y); // macro replaced by x > y ? x : y printf("%d\n", c);
Macros are powerful, but dangerous. In this example:
#define DOUBLE(a) a * 2 int x = 10; int c = DOUBLE(x); // macro replaced by x * 2
Imagine now that the call was:
#define DOUBLE(a) a * 2 int x = 10; int c = DOUBLE(5 + x); // macro replaced by 5 + x * 2
The replacement is a text replacement - the values are not calculated
until runtime. Clearly, 5 + x * 2
is not the same
as (5 + x) * 2
. One fix is to use parentheses to
enforce priority:
#define DOUBLE((a)) a * 2 int x = 10; int c = DOUBLE(5 + x); // macro replaced by (5 + x) * 2
which gives us the answer we want. The second is not to use a macro when it is possible such problems may occur.
#if #ifdef // if defined #ifndef // if not defined #endif #else #elif // else if
Example
int a; #ifdef MAX a = MAX; #else a = 0; #endif
Example
#ifndef MAX #define MAX 100 #endif int a = MAX;
Use #define
for constant values in the source code. This
helps with repetition and readability. Examples:
#define Pi 3.1415926 #define FALSE 0 #define TRUE 1 #define MAXSIZE 10 #define RESPONSE 'C' #define PROMPT "Enter C to continue:"