Anda di halaman 1dari 54

Arrays

Arrays
Introduction
• Often we need many different variables that are of the same type and play a
similar role in the program
• For example, suppose we have a temperature reading for each day of the year
and need to manipulate these values several times within a program.
• With simple variables,
– We would need to declare 365 variables.
– We would not be able to loop over these variables.
Definition
• An array is a numbered collection of variables of the same type.
• An array is a homogeneous collection of data.
• An array is a collection of similar elements i. e all are same data type.
• The variables in an array share the same name and are distinguished from one
another by their numbers or subscripts.
• We can loop through the variables of an array by using a variable for the
subscript.
• The subscripts are always 0,1,…, size-1
Array Characteristics
 An array represents a group of related data.
 An array has two distinct characteristics:
 An array is ordered: data is grouped sequentially. In other words, here
is element 0, element 1, etc.
 An array is homogenous: every value within the array must share the
same data type. In other words, an int array can only hold ints, not
doubles.
How to create an Array
 Before you create an array, you need to decide on two properties:
 Element type: what kind of data will your array hold? ints, double,
chars? Remember, you can only choose one type.
 Array size: how many elements will your array contain?
 When you initially write your program, you must pick an array size.
 Your array will stay this size throughout the execution of your program.
 In other words, you can change the size of an array at compile time, but
cannot change it at run-time.
Declaring Arrays
 To declare regular variables we just specify a data type and a unique name: int number;
syntax
 data _type array_name [array_size];

 To declare an array, we just add an array size.


 For example: int temp[5];
 creates an array of 5 integer elements.
 For example: double stockprice[31];
 creates an array of 31 doubles.

 Where:
 Data_ type: data type of each element in the array.
 Array_Name: name of the variable you are declaring.
 Array_size: number of elements allowed for this array.
 [ ] : tells the compiler that we are dealing with an array.
• How to access elements of an array?
- Index is used to access the array elements
- Index must be an integer or expression evaluated to
some integer.
- The number in the brackets following the array name.
- This number specifies the elements position in the
array.
- a[8]- shows the value at the position 9 in an array a.
Store values in an array
• When an array is declared and defined
only reserves space for the elements in
the array.
• If no values are stored by default all are
initialized to garbage value.
• To store values in the array we can read it
from key board or assign values to each
individual element.
Read values through key board
main()
{
int i;
int a[5];
printf(“enter the array elements\n”);
for (i=0;i<5;i++)
scanf (“%d”, &a [i]);
printf(“ the elements in an array\n);
for (i=0;i<5;i++)
printf (“%d”, a [i]);
}//main
Initializing Arrays
 You have three options for initializing your arrays.
 But, first, REMEMBER THIS: Just like regular variables, arrays that have
not been initialized may contain “garbage values.”
 Data_type array_name[size]= {list of values};

 Option 1: If you know all the data at compile time, you can specify all your
data within brackets:
int temp [5] = {45, 47, 44, 56, 49};
 Option 2: If you omit the size of your array, but specify an initial set of data,
the compiler will automatically determine the size of your array.
int temp [] = {45, 47, 44, 56};
 Here, the compiler creates an array of 4 elements.

 Option 3: If you do not know any data ahead of time, but you want to
initialize everything to 0, just use 0 within { }.
 For example:
int temp[5] = {0};
 This will initialize every element within the array to 0.
Referencing Array Elements
• Suppose we have an array, temperature, for the temperature readings for
the year.
• The subscripts would be 0,1,…,364.
• To refer to the reading for a given day, we use the name of the array with
the subscript in brackets: temperature[4] for the fifth day.

temperature
75 79 82 70 68 65 58 63 67 61
temperature[4]
• Assigning values:
• To assign the value 89 for the 150th day:
temperature[149] = 89;
• We can loop through the elements of an array by varying the subscript.
To set all of the values to 0, say

for (i = 0; i < 365; ++i)


temperature[i] = 0;
#include <stdio.h>
#define SIZE 12
void main()
{
int a[SIZE] = {1, 3, 5, 4, 7, 2, 99, 16, 45, 67, 89, 45};
int i, total = 0;
for (i = 0; i <= SIZE - 1; i++)
total += a[i];
printf("Total of array element values is %d\n", total);
getch();
}

 C does not provide array bounds checking


 Hence, if we have
int a[5];
printf ("%d", a[10]);
 This will compile, but you have overstepped the bounds of your array.
 You may therefore be accessing another variable in your program or
another application.
Int a[3]={0}; 0 0 0

for(i=0;i<3;i++)
scanf(“%d”,&a[i]);

35 28 45
Iteration 1:
i=0 1<3 (T)
exe scanf(&a[0])
i++; // i=1
Iteration 2:
1<3 (T)
exe scanf(&a[1])
i++; // i=2
Iteration 3:
2<3 (T)
exe scanf(&a[2])
i++; //i=3
Iteration 4:
3<3 (F)
control comes out of for loop
Character array
• Char a;- it stores only one character at a time.
• To store a string (collection of characters) we
can use arrays.
• In c , character strings are treated as array of
characters (character array)
• char name[10];
where name is a character array (string)
variable that can hold a maximum of 10
characters.
Strings
• C has no native string type, instead we use arrays of char
• A special character, called a “null”, marks the end
• This may be written as ‘\0’ (zero not capital ‘o’)
• This is the only character whose ASCII value is zero
• Depending on how arrays of characters are built, we may need to add the null
by hand, or the compiler may add it for us
Example

char
char first_name[5]
first_name[5] == {{ 'J',
'J', 'o',
'o', 'h',
'h', 'n',
'n', '\0'
'\0' };
};
char
char last_name[6]
last_name[6] == "Minor";
"Minor";
char
char other[]
other[] == "Tony
"Tony Blurt";
Blurt";
char
char characters[7]
characters[7] == "No
"No null";
null";
this special case
first_name 'J' 'o' 'h' 'n' \0 specifically excludes the
null terminator
last_name 'M' 'i' 'n' 'o' 'r' \0

other 'T' 'o' 'n' 'y' 32 'B' 'l' 'u' 'r' 't' \0

characters 'N' 'o' 32 'n' 'u' 'l' 'l'


Write a program to find the sum of
n numbers
main()
{
int n,a[n];
float total=0.0;
pf(“enter the n value\n”);
sf(“%d”, &n);
pf(“enter the array elements\n”);
for(i=0;i<n;i++)
sf(“%d”,&a[i];);
for(i=0;i<n;i++)
total= total +a[i];
printf(“%f”, total);
}//main
2D Arrays
• An array of arrays is called a two-dimensional array and can be regarded as a
table with a number of rows and columns:

'J' 'o' 'h' 'n' 'J' 'o' 'h' 'n'


is a 3 × 4 array:
'M' 'a' 'r' 'y' 3 rows, 4 columns 'M' 'a' 'r' 'y'
'I' 'v' 'a' 'n' 'I' 'v' 'a' 'n'

• This is an array of size 3 names[3]


whose elements are arrays of size 4 [4]
whose elements are characters char
• Declaration:- datatype arrayname [row][column];
ex: char names[3][4];

number
type of element of columns
name
in of number
each slot array of rows
• They are stored in memory as
col0 col1 col2
Row0 [0][0] [0][1] [0][2]
Row1 [1][0] [1][1] [1][2]
Row2 [2][0] [2][1] [2][2]
Initializing 2D arrays
• An array may be initialized at the time of declaration:
char names[3][4] = {
{ 'J', 'o', 'h', 'n'} ,
{ 'M', 'a', 'r', 'y'} ,
• An integer array may be initialized
{ 'I', 'v', 'a', 'n'}
to all zeros as follows:
};
int nums[3][4] = {0};
• This only works for zero.
nums[0][0] = 16;
• To access an element of a 2D
printf("%d", nums[1][2]);
array, you need to specify both
the row and the column: ...
'J' 4269

Address   
'J' 'o' 'h' 'n' is stored: 'o' 4270
'M' 'a' 'r' 'y' 'h' 4271
'n' 4272
'M' 4273
• Two-dimensional arrays in C are stored in "row-major format": the array is laid 'a' 4274
out contiguously, one row at a time: 'r' 4275
'y' 4276
...
• int x[2][3]={1,2,3,2,4,5};
• We can also write is as
int x[2][3]={{1,2,3},{2,4,5}};
- Each elements of row are surrounded by braces.
- Commas are required at end of the each row.
• int a[2][3]={{0,0},{1,1}};
the first two elements of the first row initialized to
zero and last element to garbage value.
the first two elements of the second row initialized
to one’s and last element to garbage value.
/* Fill 2-d array, print out values, sum the array. */
#include <stdio.h>
#define M 3 /* Number of rows */
#define N 4 /* Number of columns */
intmain(void){
int a [ M ] [ N ], i, j, sum = 0;
for ( i = 0; i < M; ++i ) /* fill the array */
for (j = 0; j < N, ++j )
a [ i ] [ j ] = i + j;
for ( i = 0; i < M; ++i ){ /* print array values */
for (j = 0; j < N, ++j )
printf(“a [ %d ] [ %d ] = %d “, i, j, a[ i ] [ j ]);
printf (“\n”);
}
for ( i = 0; i < M; ++i ) /* sum the array */
for (j = 0; j < N, ++j )
sum += a[ i ] [ j ];
printf(“\nsum = %d\n\n”);
return 0;
} Produces the output:
a[ 0 ] [ 0 ] = 0 a[ 0 ] [ 1 ] = 1 a[ 0 ] [ 2 ] = 2 a[ 0 ] [ 3 ] = 3
a[ 1 ] [ 0 ] = 1 a[ 1 ] [ 1 ] = 2 a[ 1 ] [ 2 ] = 3 a[ 1 ] [ 3 ] = 4
a[ 2 ] [ 0 ] = 0 a[ 2 ] [ 1 ] = 3 a[ 2 ] [ 2 ] = 4 a[ 2 ] [ 3 ] = 5

sum = 30
Multi Dimensional Arrays
• Array declarations read right-to-left
• int a[10][3][2];
• “an array of ten arrays of three arrays of two ints”
• In memory

3 3 3

...

2 2 2 2 2 2 2 2 2

10
Character I/O from Keyboard
To read characters from the keyboard and write to screen:
c = getchar( );
putchar(c);
• To input strings, you can use scanf() or gets().
• But it’s important to understand the difference between the two.
• scanf reads in character data until the first white space character.
– Whitespace = space, tab, or new line character.
• For example, given the following program:
scanf ("%s", name);
printf ("Hello, %s!", name);
• If I enter "Ethan Cerami", the program will print: Hello, Ethan!
• That’s because scanf reads up until the first space character.

gets()
• Gets: reads in character data until the new line character.
• For example:
gets (name);
printf ("Hello, %s!", name);
• If I enter "Ethan Cerami", the program will print: Hello, Ethan Cerami!
Functions
• Divide and conquer
– Construct a program from smaller pieces or components
– Each piece more manageable than the original program

• Programs written by combining user-defined functions with library


functions
• C standard library has a wide variety of functions
- Makes programmer's job easier - avoid reinventing the wheel
• A function receives zero or more parameters, performs a specific task, and returns zero or one
value
• A function is invoked by its name and parameters
• No two functions have the same name in a C program

• Communication between the function and its invocation is through its


parameters and its return value
• A function is independent:
– It is completely self-contained
– It can be called from any place in your code and can be ported to
another program
• Functions make programs reusable and readable
Function Syntax
Parameter names can be omitted
from the function prototype
Function Prototype:

return_type function_name (type1 name1, type2 name2,


..., typen namen) ;

Return type and parameter Semi-colon indicates


types must be provided in the that this is only the
prototype function prototype,
and that its definition
- Function_name: any valid identifier will be found
- Return_type: data type of the result (default int)elsewhere
- void - function returns nothing
- Returning control
If nothing returned
return;
or, until reaches right brace
If something returned
return expression;
No semi-colon
Function Definition:

return_type function_name (type1 name1, type2 name2,


...,typen namen)
{
....statements...
}

Body of the function Parameter names are


appears in its definition required here – they’ll
be used in the function
body

– Declarations and statements: function body (block)


• Variables can be declared inside blocks (can be nested)
• Function can not be defined inside another function
Passing Arguments
• Arguments in the function call (actual parameters) match up with
arguments in the function header (formal parameters) by position
• Function call: func1 (a, b, c);

• Function header: int func1 (int x, int y, int z)


• Each argument in the call can be any valid C expression that has a value of
the appropriate type

Local Variables

• Variables declared within the function are int func1 (int y)


considered local variables {
int a, b = 10;
• Can only be used inside the function they float rate;
were declared in, and not elsewhere double cost = 12.55;
.......
}
2 /* Finding the maximum of three integers */ 1. Function prototype (3
3 #include <stdio.h> parameters)
4
5 int maximum( int, int, int ); /* function prototype */
6 2. Input values
7 int main()
8 { 2.1 Call function
9 int a, b, c;
10
11 printf( "Enter three integers: " ); 3. Function definition
12 scanf( "%d%d%d", &a, &b, &c );
13 printf( "Maximum is: %d\n", maximum( a, b, c ) );
14
15 return 0;
16 }
17
18 /* Function maximum definition */
19 int maximum( int x, int y, int z )
20 {
21 int max = x;
22
23 if ( y > max )
24 max = y;
25 Program Output
26 if ( z > max )
27 max = z;
28
29 return max;
30 }

Enter three integers: 22 85 17


Maximum is: 85
String Functions
#include <string.h>

• int strlen( char str[] );


– Returns length of string str
• int strcpy( char to[], char from[] );
– Copies from into to
• int strcat( char existing[], char added[] );
– adds added to end of existing
• int strcmp( char str1[], char str2[] );
– Returns relationship between strings
• value less than 0 means ''str1'' is less than ''str2'‘
• 0 means ''str1'' is equal to ''str2'‘
• value greater than 0 means ''str1'' is greater than ''str2''
Strlen()
• C provides a strlen() function.
• located in <string.h>
• strlen returns the length of a string (does not include the \0 in its
calculation.)
• For example: Output: 4
char name[100]="Gore"; Note, however, that the size of the array is
printf ("%d", strlen (name));100
Comparing Strings
C provides a built-in function to compare two strings.
• strcmp (str1, str2) fucntion
• If str1 and str2 are identical, the function returns 0.

Other String Functions

• String.h includes lots of other string manipulation functions:


– strcat(): appends one string onto the end of the other.
– strcpy(): copies one string to another.
Example: Password Protection
#include <stdio.h>
#include <string.h>
#include <conio.h>

main () {
char password[255];
printf ("Enter password: ");
scanf ("%s", password);
while (strcmp (password, "bluemoon") != 0) {
printf ("Access Denied. Enter Password: ");
scanf ("%s", password);
}
printf ("Welcome!");
getch();
}
Using strcat()

#include <stdio.h>
#include <string.h>
main ()
{
char opening[255] = "And, the Oscar goes to... ";
char winner[255] = "American Beauty";
strcat (opening, winner);
printf ("%s", opening);
getchar();
}

Output:
And, the Oscar goes to... American
When using strcat, be
Beauty
careful that you do not
overrun the array size. For
example, do not append a
255 char word to opening.
Using strcpy()
#include <stdio.h>
#include <string.h>

main ()
{
char word1[] = "And, the winner is....";
char word2[255];
strcpy (word2, word1);
printf ("%s", word2);
getchar();
} This copies the contents of word1 into
word2.

Output:
And, the winner is....
User-Defined Functions
Allows programmers to define special purpose functions with the same
advantages of C’s library functions. Some of the advantages of using
functions are:
• Changing the program into separate pieces
• Code reusing
• Easier modification and maintenance of the program
• More understandable program

• A function is a grouping of program statements into a single program unit.


• It must be declared before it can be referenced.
• One way of declaration is to insert a function prototype before the main
function
• Function prototype defines the data type of that function (type of the return
value), function name and information about the arguments that the function
expects.
Calling Functions : Call by Value and Call by Reference
• Used when invoking functions
• Call by value
– Copy of argument passed to function
– Changes in function do not effect original
– Use when function does not need to modify argument
• Avoids accidental changes
• Call by reference
– Passes original argument
– Changes in function effect original
– Only used with trusted functions
• For now, we focus on call by value
1 /*
2 Randomizing die-rolling program */
3 #include <stdlib.h>
4 #include <stdio.h>
5 1. Initialize seed
6 int main()
7 { 2. Input value for
8 int i; seed
9 unsigned seed;
10 2.1 Use srand to
11 printf( "Enter seed: " ); change random
12 scanf( "%u", &seed ); sequence
13 srand( seed );
14 2.2 Define Loop
15 for ( i = 1; i <= 10; i++ ) {
16 printf( "%10d", 1 + ( rand() % 6 ) ); 3. Generate and
17 output random
18 if ( i % 5 == 0 ) numbers
19 printf( "\n" );
20 }
21
22 return 0;
23}
Placement of Functions

• For large programs • mymath.h


– Put related functions in a .c file int min(int x,int y);
– Write a .h (header) file that contains int max(int x,int y);
the function prototypes
– #include the header file in the files that • mymath.c
uses the functions int min(int x,int y)
• For small programs in a single .c file, use {
this order: return x>y?y:x;
– All prototypes }
– main() function int max(int x,int y)
{
– Other functions
return x>y?x:y;
}
Transfer of Control in function call
• When the computer executes a function call statement, it transfers control to the
function definition. In the function definition after execution of the last statement in the
function body, computer returns the control to the main program and executes the next
statement after the function call.

Common programming errors with functions


• Not using #include preprocessor directive for the predefined functions
• Not defining a prototype before the main and definition after the main for the
user defined functions
• Not using the correct order and type for the arguments of the functions
• Dividing by zero in the function body
Simple Recursion
• Recursion is where a function calls itself.
• Concept of recursive function:
– A recursive function is called to solve a problem
– The function only knows how to solve the simplest case of the problem.
When the simplest case is given as an input, the function will
immediately return with an answer.
– However, if a more complex input is given, a recursive function will
divide the problem into 2 pieces: a part that it knows how to solve and
another part that it does not know how to solve.
– The part that it does not know how to solve resembles the original problem, but
of a slightly simpler version.
– Therefore, the function calls itself to solve this simpler piece of problem that it
does now know how to solve. This is what called the recursion step.
– The recursion step is done until the problem converges to become the simplest
case.
– This simplest case will be solved by the function which will then return the
answer to the previous copy of the function.
– The sequence of returns will then go all the way up until the original call of the
function finally return the result.
Recursive factorial function • Output: 1! = 1
#include <stdio.h> 2! = 2
long factorial(long); 3! = 6
void main(void) { 4! = 24
int i; 5! = 120
for (i = 1; i <= 10; i++) 6! = 720
printf(“%2d! = %1d\n”, i, factorial(i)); 7! = 5040
} 8! = 40320
long factorial(long number) { 9! = 362880
if (number <= 1) Calls itself with a simpler version 10! = 3628800
return 1; of the problem.
else
return (number * factorial(number-1));
}
• Any problem that can be solved recursively can also be solved iteratively
(using loop).
• Recursive functions are slow and takes a lot of memory space compared to
iterative functions.
So why bother with recursion? There are 2 reasons:
Recursion approach more naturally resembles the problem and therefore
the program is easier to understand and debug.
Storage Classes
Every variable and function in C has two attributes:
type (int, float, ...)
auto
storage class
Storage class is related to the scope of the variable
There are four storage classes: • auto
• extern
• register
• static

auto (the default and the most common)


Memory for automatic variables is allocated when a block or function is
entered. They are defined and are “local” to the block. When the block is
exited, the system releases the memory that was allocated to the auto
variables, and their values are lost.
Declaration: auto type variable_name;

There’s no point in using auto, as it’s implicitly there anyway


Storage class static

static variables are local variables that keep their previous value when
the block is reentered. A declaration
static int cnt = 0;

will set cnt to zero the first time the function is used; thereafter, it will
retain its value from previous iterations.

•This can be useful, e.g., for debugging: you can insert code like this
anywhere without interfering with the rest of the program

{ /* debugging starts here */
static int cnt = 0;
printf(“*** debug: cnt = %d, v = %d\n”, ++cnt, v);
}

•The variable cnt is local to the block and won’t interfere with another
variable of the same name elsewhere in an outer block; it just increases
by one every time this block is encountered.
Storage class register

register tells the compiler that the variables should be stored in


high-speed memory registers if possible. Only a few such registers
are available, and can be assigned to frequently-accessed variables
if execution time is a problem. If no register space is free, variables
become auto instead. Keep registers in small local blocks which are
deallocated quickly.

Example: {
register int i;
for (i=0; i < 100; i++)
{
.....
}
}
register is freed on block exit

now obsolete since done automatically by most compilers


Storage class extern

global variables (defined outside functions) and all functions are of the
storage class extern and storage is permanently assigned to them
extern type variable_name;

Within a file variables outside functions have external storage class,


even without the keyword extern .

Files can be compiled separately, even for one program.


extern is used for global variables that are shared across code
in several files.
file1.c
extern in multi-file projects
#include <stdio.h>
int a =1, b = 2, c = 3; /* external variables */
int f(void);
int main (void)
{
printf(“%3d\n”, f( ));
printf(“%3d%3d%3d\n”, a, b, c); print 4, 2, 3
return 0;
} a is global and changed by f
file2.c
int f(void)
{
extern int a; /* look for it elsewhere */
int b, c;
a = b = c = 4; b and c are local and don‘t survive
return (a + b + c);
} return 12
Scope rules for blocks

Identifiers (i.e. variables etc.) are accessible only within the block in
which they are declared.
{
int a = 2; /* outer block a */
printf(“%d\n”, a); /* 2 is printed */
{
int a = 5; /* inner block a */
printf(“%d\n”, a); /* 5 is printed */
}
printf(“%d\n”, a); /* 2 is printed */
}
/* a no longer defined */
outer a masked

A variable that is declared in an outer block is available in the


inner block unless it is redeclared. In this case the outer block
declaration is temporarily “masked”.

Avoid masking!
Use different identifiers instead to keep your code debuggable!
Scope rules for functions
int func (int n) int main (void)
{ {
int a = 2, b = 1, c;
printf(“%d\n”,b);
c = func(a);
return n; return 0;
} }
b not defined locally!

variables defined within a function (including main)


are local to this function and no other function has
direct access to them!

• the only way to pass variables to a function is as parameters


• the only way to pass (a single) variable back to the calling
function is via the return statement
Exceptions: 1. Global Variables 2. Pointers
Global variables

variables defined outside blocks and functions are global ,


i.e. available to all blocks and functions that follow

#include <stdio.h>

int a = 1, b = 2; /* global variables */

int main (void)


{
int b = 5; /* local redefinition */
printf(“%d”, a+b); /* 6 is printed */
return 0;
}

Avoid using global variables to pass parameters to functions!

• Only when all variables in a function are local, it can be used in


different programs
• Global variables are confusing in long code
Structure and scope of variables
int a, b, c;of a c-file file.c

func1 () { main () {
int a, b, int x, y;
c; variables
in scope
{ {
int d,e,f; int c,d,e; down
nested
{ blocks
int g;
}
(except
} block1 } block2
for
} masking)
}

nested block use it for


efficient use
variables out of scope between parallel blocks of memory
The C Preprocessor
• Obeys special commands called preprocessor directives
• Indicate certain things to be done to the program code prior to compilation.
– Include certain other files when compiling
– Replace some code by other code
• Statements beginning with # are considered preprocessor directives

• Preprocessing
– Occurs before a program is compiled
– Inclusion of other files
– Definition of symbolic constants and macros
– Conditional compilation of program code
– Conditional execution of preprocessor directives

• Format of preprocessor directives


– Lines begin with #
– Only whitespace characters before directives on a line
The #include Preprocessor Directive
• #include
– Copy of a specified file included in place of the directive
– #include <filename>
• Searches standard library for file
• Use for standard library files
– #include "filename"
• Searches current directory, then standard library
• Use for user-defined files
– Used for:
• Programs with multiple source files to be compiled
together
• Header file – has common declarations and definitions
(classes, structures, function prototypes)
– #include statement in each file
The #define Preprocessor Directive: Symbolic Constants
• #define
– Preprocessor directive used to create symbolic constants
and macros
– Symbolic constants
• When program compiled, all occurrences of symbolic
constant replaced with replacement text
– Format
#define identifier replacement-text
– Example:
#define PI 3.14159
– Everything to right of identifier replaces text
#define PI = 3.14159
• Replaces “PI” with "= 3.14159"
– Cannot redefine symbolic constants once they have been
created
The #define Preprocessor Directive: Macros
• Macro
– Operation defined in #define
– A macro without arguments is treated like a symbolic constant
– A macro with arguments has its arguments substituted for replacement
text, when the macro is expanded
– Performs a text substitution – no data type checking
– The macro
#define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) )
would cause
area = CIRCLE_AREA( 4 );
to become
area = ( 3.14159 * ( 4 ) * ( 4 ) );
The #define Preprocessor Directive: Macros

• Use parenthesis
– Without them the macro
#define CIRCLE_AREA( x ) PI * ( x ) * ( x )
would cause
area = CIRCLE_AREA( c + 2 );
to become
area = 3.14159 * c + 2 * c + 2;
• Multiple arguments
#define RECTANGLE_AREA( x, y ) ( ( x ) * ( y ) )
would cause
rectArea = RECTANGLE_AREA( a + 4, b + 7 );
to become
rectArea = ( ( a + 4 ) * ( b + 7 ) );
Conditional Compilation
• Conditional compilation
– Control preprocessor directives and compilation
– Cast expressions, sizeof, enumeration constants cannot
be evaluated in preprocessor directives
– Structure similar to if
#if !defined( NULL )
#define NULL 0
#endif
• Determines if symbolic constant NULL has been defined
– If NULL is defined, defined( NULL ) evaluates to
1
– If NULL is not defined, this function defines NULL to
be 0
– Every #if must end with #endif
– #ifdef short for #if defined( name )
– #ifndef short for #if !defined( name )
• #
– Causes a replacement text token to be converted to a string
surrounded by quotes
– The statement
#define HELLO( x ) printf( “Hello, ” #x “\n” );
would cause
HELLO( John )
to become
printf( “Hello, ” “John” “\n” );
– Strings separated by whitespace are concatenated when using
printf

Anda mungkin juga menyukai