basic features of c (review)
Post on 21-Mar-2016
27 Views
Preview:
DESCRIPTION
TRANSCRIPT
BASIC FEATURES OF C (REVIEW)
C PHILOSOPHY Low-level language
System programming
Small languageLibrary of standard “functions”
Permissive languageDoesn’t require the detailed error-
checking
C STRENGTHS Efficiency
Limited amount of memoryFast
PortabilityCompilers are small and easily writtenC: UNIX and ANSI/ISO standard
Power Flexibility Standard library
Input/output, string handling, storage allocation, etc.
Integration with UNIX
C WEAKNESS Can be error-prone
FlexibilityC compiler doesn’t detect many
programming mistakesPitfalls
Can be difficult to understandSome features are easier to be misusedFlexibility
Can be difficult to modifyNo modules
COMPILING AND LINKING
VARIABLES AND ASSIGNMENTS C is case-sensitive Compiler remembers only first 31 characters Type Should be declared
int height, length, width; Declarations must precede the statements. The value should be assigned before using the
variable in computations:height = 8;length = 12;width = 5;int volume = height * length * width;
CONSTANTS Macro definition:
#define SCALE_FACTOR (5.0/9.0)
No semicolon at the end!
FORMATTED OUTPUT: PRINTF printf(string, expr1, expr2,…)printf(string, expr1, expr2,…) Format string contains both ordinary
characters and conversion specifications
Conversion specification is a placeholder representing a value to be filled in during printing.
The information after % specifies how the value is converted form its internal form(binary) to printed form (characters)
PITFALLS
FORMATTED INPUT: SCANF scanf(string, expr1, expr2,…)scanf(string, expr1, expr2,…)Reads input according to a particular
format.Format string contains both ordinary
characters and conversion specificationsscanf(“%d%d%f%f”, &&i, &j, &x, &y); Number of conversion specification
should match number of variables.Each conversion should be appropriate for
type of the variable. while (scanf (“%d”, &i)==1) { … }
HOW SCANF WORKSFor each conversion specification, tries to locate
an item of appropriate type, skipping blank spaces if necessary.
Reads it, stopping when it encounters the symbol that can’t belong o item.
Ignores white-space characters.scanf(“%d%d%f%f”, &&i, &j, &x, &y); 1-20 .3 -4.0e3 1-20 .3 -4.0e3 1-20 .3 -4.0e3
ARITHMETIC OPERATORS Unary operators: + (unary plus), - (unary minus)
Binary operators
ASSIGNMENT OPERATORS Simple assignment(right associative): ==
int i=5, j=3;int k = 5*3;i = 72.99; float f;f = 136;i = j = k = 7;f = i = 33.3;k = 1 + (j = i);
Compound assignments(right associative): +=, -=, *=, /=, %=+=, -=, *=, /=, %=i += j += k; i += k; vs i =+ k;
INCREMENT AND DECREMENT OPERATORS Prefix operators: ++i, --i++i, --i Postfix operators: i++, i—i++, i— Side effect:Side effect:
x=1, y=2;k=1 + ++x; vs k = 1+ x++;k = ++x + y++; vs k = x++ +
y++;
PRECEDENCE AND ASSOCIATIVITY
SUB EXPRESSION EVALUATION a = 5; c = (b = a + 2) – (a = 1);
i = 2; j = i * i ++;
Any expression can be used as a statement i++; i*j -1; i + j ; /* i = j */
RELATIONAL OPERATORS 0 (false) and 1 (true) Their precedence is lower than the
precedence of the arithmetic operators. Left associative
i < j < k
EQUALITY OPERATORS 0 (false) and 1 (true) Their precedence is lower than the
precedence of the relational operators.i < j == j < k
Left associative
LOGICAL OPERATORS Logical negation: !!
!expr : 1 if expr has the value 0!expr : 1 if expr has the value 0Right associativeThe same precedence as unary plus and minus
Logical and: &&&&expr1 && expr2 : 1 if both expr1 and expr2 has non-expr1 && expr2 : 1 if both expr1 and expr2 has non-
zero valueszero values Logical or: ||||
expr1 || expr2 : 1 if either expr1 or expr2 (or both) expr1 || expr2 : 1 if either expr1 or expr2 (or both) has non-zero valueshas non-zero values
Short-circuit evaluation Left associative The precedence is lower that that of the relational and
equality operators
IF … ELSE STATEMENT if (expression) statementif (expression) statement if (expression) statement else statementif (expression) statement else statement Statement can be compound: { statements}{ statements} if (i==0) vs if (i=0) if (expression)if (expression) statementstatement else if (expression)else if (expression) statementstatement … … elseelse statementstatement
“DANGLING ELSE” PROBLEM
if (y != 0) if (x != 0) result = x / y;else printf (“Error: y is equal to ) \n”);
1.y = 5 and x = 3 2.y = 0 and x =33.y = 5 and x = 0
CONDITIONAL EXPRESSION expr1 ? expr2: expr3expr1 ? expr2: expr3 int i, j, k; i = 1; j = 2; k = i > j ? i : j ; k = (i > 0 ? i : 0) + j ; return (i > j ? i : j); printf (“%d\n”, i > j ? i : j);
SWITCH STATEMENT switch ( expression ){switch ( expression ){ case constant-expression: statementscase constant-expression: statements … … case constant-expression: statementscase constant-expression: statements default: statementsdefault: statements}} Controlling expression should be an integer
expression (characters) Constant expression can’t contain variables or
function calls. Statements do not require {}. Usually, the
last statement is breakbreak.
EXAMPLE
WHILE LOOP while (expression) statementwhile (expression) statement Statement can be compound: {} while (i>0) printf (“%d\n”, i--); while (i>0) { printf (“%d\n”, i); i--; } Infinite loops: while(1)
Break, goto, returnBreak, goto, return
EXAMPLE
scanf(“%d”, &n);
DO LOOP do statement while (expression);do statement while (expression); Statement can be compound: {} do printf (“%d\n”, i--); while (i>0) ; do { printf (“%d\n”, i); i--; } while (i>0);
FOR LOOP for (expr1; expr2; expr3) statement Statement can be compound: {} expr1; while (expr2) { statement expr3; } for (i=10; i>0; i--) printf (“%d\n”, i); Infinite loop: for (;;) Comma operator:
for (i=1, j=2; i+j<10; i++, j++) printf (“%d\n”, i+j);
EXAMPLE
EXITING FROM A LOOP: BREAK for (d=2; d<n; d++) if (n%d==0) break; if (d<n) printf (“%d is divisible by %d\n”, n,d); else printf(“%d is prime \n”,n); for (;;){ printf (“Enter a number(0 to stop): ”); scanf(“%d”,&n); if (n==0) break; printf(“%d cubed is %d\n”,n,n*n*n);} break break escapes only one level of nesting.
SKIPPING THE REST OF ITERATION: CONTINUE n = 10; sum = 0; while (n-->0){ scanf(“%d”, &i); if (i%2==0) continue; sum+=i; }
UNCONDITIONAL JUMP: GOTO goto label ;goto label ; label: statementlabel: statement for (d=2; d<n; d++) if (n%d==0) goto done; done: if (d<n) printf (“%d is divisible by %d\
n”, n,d); else printf(“%d is prime \n”,n);
EXAMPLEwhile(expr1){ switch(expr2){ case constant_expression1: statement; break; … case constant_expression1: statement; if (expr3) goto while_done; break; default: break; }}while_done: ….
NULL STATEMENT ;; for (d=2; d<n; d++) if (n%d==0) break; for (d=2; d<n && n%d !=0 ; d++);Accidentally putting a semicolon after the
parentheses in if, while or for statement ends the statement prematurely.
if (i==0); printf (“Zero\n”); while (i>0); printf (“%d\n”, i--);
BASIC TYPES: INTEGERS Signedness: signed (defaut), unsigned Size: short, long<limits.h> holds ranges for int types.
INTEGER CONSTANTSDecimal (base 10) literals
digits between 0-9, no leading zero15, 255, 32767
Octal (base 8) literalsdigits between 0-7, must start with 0
017, 0377, 077777Hexadecimal (base 16) literals
digits between 0-9 and letters between A-F (a-f), must start with 0x (0X)
0xF, 0xFF, 0x7FFFLong literals: 15L, 0377L, 0x7fffLUnsigned literals: 15U, 0377U, 0x7ffUL
BASIC TYPES: FLOATING TYPES <float.h> Assume IEEE 754 standard
Scientific notation: sign, an exponent, a fraction.57e2, 57, 5.7e+1, 570.0e-1
BASIC TYPES: CHAR Character set: Latin (7 bit), ASCII (8 bit) Treats as integers unsigned (0-255) and signed (-128-127) version Some compilers use unsigned by default, the other
compilers use signed by default. char ch=65; /* it’s ‘A’ now */ int i = ‘a’; /* it’s 97 */ ch++; /* it’s ‘B’ now */ if (‘a’< =ch && ch <=‘z’) ch = ch – ‘a’ + ‘A’; /* ch=toupper(ch);*/ for (ch=‘A’; ch<=‘Z’; ch++) … ch=‘a’ * ‘b’ / ‘c’ …
READ AND WRITE CHAR: ALTERNATIVE ch = getchar(); putchar(ch); while ( ( ch = getchar() ) != ‘\n’ ) … while ((ch=getchar())==‘ ’);
printf(“Enter an integer: ”); scanf(“%d”, &i); printf(“Enter a command: ”); command = getchar();
SIZEOF OPERATOR sizeof (type-name)sizeof (type-name) Unsigned integer representing the number
of bytes required to store a value of type-type-namename
sizeof(char) is always 1 Can be applied to constants, variables,
expressions int i, j; int k= sizeof(i); /* k is assigned 2*/ k = sizeof (i + j );
IMPLICIT TYPE CONVERSION Convert operands to the “narrowest” type that
will safely accommodate both values. If the type of either operand is a floating point: float -> double - > long double Otherwise: if there are short and char operands, convert
them to int, then int -> unsigned int -> long int -> unsigned
long int int i= -10; unsigned int u=10; if (i < u) …
CONVERSION DURING ASSIGNMENT char c = ‘A’; int ind; float f; double d; i = c; /* will get 65 */ f = i; /* will get 65.0 */ d = f; i = 824.97; /* 824 */
c= 100000000; f = 1.0e1000;
EXPLICIT TYPE CONVERSION: CAST (type-name) expression(type-name) expression Unary operatorUnary operator float f = 3.45, frac; frac = f – (int) f; int num1=5, num2 =3; float quotient = (float) num1/ num2; int i=1000; long int i = (long int) j * j; long int i = (long int) (j * j)
ONE –DIMENSIONAL ARRAYData structure containing a number of values of
the same type.Declare array: type, name and number of elements
int a[10] Subscripting: for (i=0; i<N; i++) a[i]=0; for (i=0; i<N; i++) scanf (“%d”, &a[i]); i=0; while (i<N) a[i++] = 0;const int
month[]={31,28,31,30,31,30,31,31,30,31,30,31};
ARRAY INITIALIZATION int a[10] = { 1,2,3,4,5,6,7}; int a[]= { 1,2,3,4,5,6,7};
SIZEOF OPERATOR FOR ARRAYS sizeof(varName)sizeof(varName) Determines the size of variable in
bytes.
for ( i = 0; i< sizeof(a) / sizeof(a[0]); i++)
a[i]=0;
MULTIDIMENSIONAL ARRAY int m[i][j] int m[i,j] /*treats as m[j]*/ Stores in row-major order int m[3][3]={{1,2,3}, {4,5,6}, {7,8,9}} int m[3][3]={{1,2}, {4,5,6}} int m[3][3]={1,2, 4,5,6}
FUNCTIONS return type function-name (parameters)return type function-name (parameters) {{ declarationsdeclarations statementsstatements }} Function can not return array If return-type is omitted, it is presumed to
return int value. If function doesn’t return value, use void. List of parameters: type name, type name…
(void) float average(float a, float b){ return (a+b)/2; }
FUNCTION CALLS A call of void function is a statement:
void f (int a){ printf(“%d\n”, a);} f(3+4*5);
A call of non-void function is an expression:float average(float a, float b){ return (a+b)/2; } float av = average (3+4*5, 2);
FUNCTION DECLARATION C doesn’t require to define function before its
first use. void main() { int i =4, k=5; float av = average (i,k); } float average(float a, float b){ return (a+b)/2; } To ensure error message, declare function
before its first call (function prototypefunction prototype): return-type function-name(parameters);return-type function-name(parameters);
float average (float a, float b);float average(float, float);
ARGUMENTS ParametersParameters appear in function definition Arguments Arguments are expressions in function calls. In C, arguments are passed by valuepassed by value int power (int x, int n); void main { int k=3, pow = power (2, k); } int power (int x, int n){ int result=1; while (n-- >0) result*=x; return result; }
EXAMPLE void decompose (float x, int integer, float
fract){ integer = (int) x; fract = x – integer; } void main(){ int i=5; float f= 3.4; decompose (3.14, i, f); }
ARGUMENT CONVERSION The compiler has encountered a prototype prior to
the function’s call.Implicit conversion of the value of each argument
to the expected type. Otherwise, default argument promotionsdefault argument promotions:
float -> doublechar -> int, short -> int
void main () { int i; scanf(“%d”, &i); printf(“The square is %g\n”, square(i));}double square(double x) {return x*x;}
ARRAY ARGUMENTS int f (int a[]) {…} int sum(int[], int); int sum(int a[], int n){ int i,sum=0; for(i=0; i<n; i++) sum+=a[i]; return sum; } int a[10]={1,4,6,7,3,2,4}; int total = sum (a, 10); int f(int a[][10]){…}
RETURN AND EXIT STATEMENTS return expression;return expression; double Largest (double x, double y){ return x>y? x : y; } void print_int(int i){ if (i<0) return; printf(“%d\n”,i);} The value returned by main is a status code. In <stdlib.h>: exit(expression); exit(expression); Normal success: EXIT_SUCCESS (0) Abnormal termination: EXIT_FAILURE (1)
RECURSIVE FUNCTION int power (int x, int n){ return n==0? 1: x*power(x, n-1);} int factorial(int n){ return n<=1 ? 1 : n*factorial(n-1);} int sum_digits(int n){ return n==0 ? 0: n%10+sum_digits(n/10); }
LOCAL VARIABLES (BLOCK VARIABLES) Automatic storage duration Block scopestatic: static storage duration int sum(int a[], int n){ int i; static int sum=0; for(i=0; i<n; i++) sum+=a[i]; return sum; }void main(void){int a[4] ={3,5,7,11};printf(“%d\n”, sum(a,4));printf(“%d\n”, sum(a,4)); }
EXAMPLE
EXTERNAL VARIABLES Static storage duration File scope Disadvantages:
If we change external variable (for example, its type), we need to check every function in the same file to see its affect.
In an external variable got incorrect value, it may be difficult to find which function should be corrected.
Functions that rely on external variables are hard to reuse in the other programs.
EXAMPLE
POINTERS Executable program consists of both code and data. Each variable occupies one or more bytes of memory The address of the first byte is said to be the address
of the variable. Pointer variable is a variable storing address. int i; int *p = &i; Declaration:
type *name;type *name;int i, j, *p;
…
…
i2000
2001
p
THE ADDRESS AND INDIRECTION OPERATORS && operator: returns address of a variable int i, *p; p = &i; int i, *p=&i; p is aliasalias for i. i=1; *p=2; ** operator : returns an object that a pointer
points to. printf(“%d\n”, *p); int j=*&i;
POINTER ASSIGNMENT int x ,y, *p, *q; p = &x; q= &y; q=p; *p = 1; *q= 2; int x=1, y=2, *p, *q; p = &x; q= &y; *p = *q;
POINTERS AS ARGUMENT void decompose (float x, int **integer, float
**fract){ **integer = (int) x; **fract = x – **integer; }
void main(){ int i=5; float f= 3.4; decompose (3.14, &&i, &&f); }
scanf(“%d”, &i); *p= &i; scanf(“%d”, p);
CONST TO PROTECT ARGUMENTSvoid f(const int *p){ int j; p=&j; *p=1; *p=1; }void f(int * const p){ int j; p=&j;p=&j; *p=1; }void f(const int * const p){ int j; p=&j;p=&j; *p=1; *p=1; }
POINTERS AS RETURN VALUES double *double *Largest (double **x, double **y){ return **x>**y? x : y; } int *p, x,y; p =max(&x, &y); You can return pointer to one element of
the array passed as an argument, to static local variable, to external variable.
Never return a pointer to an automatic local variable!
POINTER ARITHMETIC int a[5], *p=&a[0]; *p=a; int *q;
p=&a[2];
q=p+2;
p++;
p
a
p
a
q
p
a
q
POINTER ARITHMETIC int a[5], *q, *p=&a[4];
q=p-3;
p-=4;
p
a
p
a
q
p
a
q
POINTER ARITHMETIC int a[5]; int *q=&a[1], *p=&a[4]; int i=p-q; i=q-p;
p
a
q
Meaningful, if pointers point to the element of the same array.
p<=q int sum=0; for (p=&a[0];p<&a[N]; p++) sum+=*p;
COMBINING * AND ++ (--)
int sum=0, *p=&a[0]; while (p<&a[N]) sum+=*p++;
ARRAY NAME AS A POINTER int a[10], *p=a; *a =7; *(a+1)=12; *(a+i) is the same as a[i] p[i] is the same as *(p+i) for (p=a; p<a+N; p++) sum+=*p; Array parameter is treated as pointer, so it’s
not protected against change. The time required to pass array to a function
doesn’t depend on its size. int f(int a[]){…} is the same as int f(int *a){…} int max = f(&a[5],10);
STRINGS Double quotes C treats string literals as character arrays,
that is, a pointer of type char *. For string literal of length n, it stores n
characters of the string literal and null character (‘\0’) to mask the end of the string.
char ch = “abc”[1]; char digit_to_hex(int digit){ return “0123456789ABCDEF”[digit];} char *p=“abc”; *p=‘b’; /* not recommended*/
STRING VARIABLES char str[length+1]; char date[8]=“June 14”; char date[9]=“June 14”; /*2 null characters at the end*/ char date[]=“June 14”; char *dt=“June 14”;
Characters of array date can be modified, dt points to string literal which characters should not be modified.
date is an array name, dt is a pointer and can point to the other string literal.
char str[length+1], *p; p=str;
WRITING STRINGS printf(“%s\n”,str); printf(“%.4s\n”,”C is a fun language”); printf(“%10s\n”,”Hi”); printf(“%10.4s\n”,”C is a fun
language”);
puts(str);
READING STRINGS scanf(“%s”, str); / *never contain white
spaces*/ scanf(“%10s”, str);
gets(str);Reads until finds newline characterIt replaces newline character with null character
before storing to a variableDoesn’t skip leading white spaces
C STRING LIBRARY char str1[10],str2[10]; str1=“abc”; /*wrong*/ str2=str1; /*wrong*/ str1==str2 compares pointers! <string.h><string.h>
char * strcpy(char *s1, const char char * strcpy(char *s1, const char *s2);*s2);
strcpy(str2, “abcd”); strcpy(str1,strcpy(str2, “abcd”));
C STRING LIBRARY char * strcat(char *s1, const char *s2);char * strcat(char *s1, const char *s2); strcat(str1, “abc”); strcat(str2, “def”); strcat(str1, strcat(str2,”gi”));
int strcmp(const char *s1, const char int strcmp(const char *s1, const char *s2);*s2);
Lexicographic ordering if (strcmp(str1,str2)<0) …
size_t strlen(const char *s);size_t strlen(const char *s); int len = strlen(“abc”); len = strlen(“”);
STRING IDIOM Search for the null character at the
end of a string:while(*s) s++;while(*s++);
size_t strlen(const char *s){ const char *p=s; while (*s++); return s-p;}
COMMAND-LINE ARGUMENTS main(int argc, char *argv[]int argc, char *argv[]){…} argcargc is the number of arguments(including
the name of the program) argv[] argv[] is an array of pointers to the
command-line arguments stored in string form
argv[0]argv[0] is the name of the program argv[argc]argv[argc] is a null pointer (NULL)
DATA STRUCTURES (STRUCT) struct struct is a collection of values(membersmembers),
possibly of different types (records). Array: one type; index Structure: different types; name of the
member.
OPERATIONS ON STRUCTURES Structure members are accessed by the name: structure member operatorstructure member operator (the dot, “..”): date2..day++; printf(“%d-%s-%s\n”,date2..day,
date2..month,date2..year); Assignment (compatible structures) date1=date2; struct {int a[10];}a1,a2={0}; a1=a2; /*legal*/ There is no operators to test if two structures
are equal or not equal.
USER DEFINED DATA TYPES (TYPEDEF) typedeftypedef creates synonyms for data type names.typedef struct {
int day; char month[3]; char year[4] ;
} timestamp; timestamp date1,date2; timestamp *myptr = &date1; Structure pointer operatorStructure pointer operator (the “->->“): myptr ->-> year ;
(*myptr)..year;
#include <stdio.h> struct personalstruct personal { long id; float gpa; } ;struct identity struct identity { char name[30]; struct personal person; } ;void print_identity(struct identity ind)void print_identity(struct identity ind){ printf ("%s %ld: %f\n", ind.name, ind.person.id,
ind.person.gpa); } int main ( )int main ( ){ struct identity js = {"Joe Smith"}, *ptr = &js ; js.person.id = 123456789 ; js.person.gpa = 3.4 ; print_identity(js); print identity(*ptr); }
UNION A unionunion (like struct) consists of one or more
members that may be of different types. They share the same storage! union { int i; float f; } u; struct { int i; float f; } s; u.i=3; u.f=5.6;
i
f
unioni
f
struct
UNION OPERATORS
Can be copied by = operator, passed to functions and returned by the functions.
date1=date2;
#include <stdio.h> union statusunion status{ int rank ; char deg[4]; };struct infostruct info{ long id; float gpa; union status lvl; };struct identity struct identity { char name[30]; struct info ind; };int main( )int main( ){ struct identity jb =
{"Joe Brown"}, *ptr = &jb;
char u_g; ptr->ind.id = 1234; ptr->ind.gpa = 3.4 ; printf ("Enter u or g\n"); scanf ("%c", &u_g); if (u_g == 'u‘){ printf ("Enter rank\n"); scanf ("%d", ptr->ind.lvl.rank); } else { printf ("Enter degree sought \n"); scanf ("%s", ptr-> ind.lvl.deg);} }
#include <stdio.h>typedef struct {typedef struct { int kind;int kind; union statusunion status{ int rank ; char deg[4]; }; }statusstatus;
void print_identity (struct identity id) void print_identity (struct identity id) { printf ("%s %ld: %f\n", id.name, id.ind.id,
id.ind.gpa); if(id.ind.lvl.kind==1) printf (“Rank is %d\n",
id.ind.lvl.status.rank); else printf (“Sought degree is %4s\n",
id.ind.lvl.status.deg); }
struct infostruct info{ long id; float gpa; statusstatus lvl; };
struct identity struct identity { char name[30]; struct info ind; };
int main( )int main( ){ struct identity jb = {"Joe Brown"}, *ptr = &jb; char u_g; ptr->ind.id = 1234; ptr->ind.gpa = 3.4 ; printf ("Enter u or g\n"); scanf ("%c", &u_g); if (u_g == 'u‘){ printf ("Enter rank\n"); scanf ("%d", ptr->ind.lvl.status.status.rank); } else { printf ("Enter degree sought \n"); scanf ("%s", ptr-> ind.lvl.status.status.deg);} ptr->ind.level.kind=(u_g == 'u‘)?1:2;ptr->ind.level.kind=(u_g == 'u‘)?1:2; print_identity(*ptr);print_identity(*ptr);}
ENUMERATION: ENUM enumenum is a type whose values are listed
(enumerated) by the programmer who creates a name (enumeration constantenumeration constant) for each of the values.
enum {yellow,red, green, blue} c1,c2; enum colors {yellow,red, green, blue}; enum colors c1,c2; typedef enum {yellow,red, green, blue} Colors; Colors c1,c2; typedef enum {FALSE, TRUE} Bool; C treats enumeration variables and constants as
integers.
#include <stdio.h>int main( ){
int apr[5][7]={{0,0,0,0,1,2,3},{4,5,6,7,8,9,10},{11,12,1314,15,16,17},{18,19,20,21,22,23,24},{25,26,27,28,29,30}};enum days enum days {Sunday, Monday, Tuesday,
Wednesday, Thursday, Friday, Saturday}; enum week enum week {week_1, week_2, week_3,
week_4, week_5};printf ("Monday at the third week of April isApril %d\n“, apr [week_3] [Monday] ); }
ENUM enum dept {CS=20, MATH=10, STAT=25}; enum colors {BLACK, GRAY=7, DK_GRAY,
WHITE=15} c; int i=GRAY; /*it’s 7 now*/ c=0; /*it’s BLACK now*/ c+=8; /*it’s DK_GRAY now*/ i= c+4 *2; /* it’s 16 now */ typedef struct {typedef struct { enum {RANK, DEG} kind;enum {RANK, DEG} kind; union statusunion status{ int rank ; char deg[4]; }; }statusstatus;
DYNAMIC STORAGE ALLOCATION It’s ability to allocate storage during program
execution Available for all types of data Mostly used for strings, arrays and structures. Dynamically allocated structures can form
lists, trees and other data structures. <stdlib.h><stdlib.h> mallocmalloc : allocates a block of memory, but
doesn’t initialize it calloccalloc: allocates a block of memory and clears
it freefree: releases the specified block of memory
NULL POINTER If memory allocation function can’t allocate a
block of the requested size, it returns a null null pointer (NULL)pointer (NULL).
<locale.h>,<stddef.h>,<stdio.h>,<stdlib.h<locale.h>,<stddef.h>,<stdio.h>,<stdlib.h>, <string.h>, <time.h>>, <string.h>, <time.h>
It is responsibility of a programmer to test It is responsibility of a programmer to test if received pointer is a null pointerif received pointer is a null pointer.
p=malloc(1000); if (p==NULL) { /* appropriate actions*/ } if ((p=malloc(1000))==NULL) { /*actions*/ } if (p) …. is the same as if (p!=NULL) if (!p) …. is the same as if (p==NULL)
USING MALLOC: STRINGS void *malloc(size_t size);void *malloc(size_t size); Allocates a block of sizesize bytes and returns a
pointer to it; if fails, returns NULLNULL. Since sizeof(char)sizeof(char) is1, to allocate space for a
string of nn characters: char *p=malloc(n+1); Memory allocated using mallocmalloc isn’t cleared or
initialized: strcpy(p, “abc”);strcpy(p, “abc”); There are no checks no checks to detect usage of
memory outside the bounds of the block Dynamical allocation makes possible to write
functions that return a pointer to a “new” string: char *p= concat(“abc”,”def”);char *p= concat(“abc”,”def”);
#include<string.h>#include<stdlib.h>#include<stdio.h>char *concat(const char *s1, const char *s2 ){char *concat(const char *s1, const char *s2 ){ char *result=malloc(strlen(s1)+strlen(s2)+1); if (result==NULL){ printf(“malloc failed\n”); exit(EXIT_FAILURE); } strcpy(result,s1); strcpy(result,s2); return result;}}
DYNAMICALLY ALLOCATED ARRAYS Elements of an array can be longer than Elements of an array can be longer than
one byte => sizeof should be used.one byte => sizeof should be used. int *a=malloc(n * sizeof (int)); for(i=0;i<n;i++) a[i]=0; void *calloc(size_t nmemb, size_t size);void *calloc(size_t nmemb, size_t size); Allocates space for an array with nmembnmemb
elements, each of which is sizesize bytes; sets all bits to 0 and returns a pointer to it.
If space is not available, returns NULL. int *a=calloc(n, sizeof(int)); struct point {int x,y;} *p; p=calloc(1, sizeof(struct point));
DEALLOCATING STORAGE Memory block are obtained from a storage
pool (heapheap). GarbageGarbage is a block of memory that’s no
longer accessible to a program. A program that leaves garbage behind has a
memory leakmemory leak. int *p=malloc(100), *q=malloc(100); p=q; void free (void *ptr);void free (void *ptr); int *p=malloc(100), *q=malloc(100); free(p); p=q;
MEMORY LEAK: EXAMPLES int *int_ptr; for (;;) { int_ptr = malloc(100 * sizeof(int) ); if ( int_ptr == NULL ) { fprintf(stderr, "..."); exit(1); } } for ( i = 1; i <= 5; i++) printf("%s\n", concat(“abc”,
“012345”[digit]));
MEMORY LEAK for ( i = 1; i <= 5; i++) { char *str=concat(“abc”, “012345”[digit]); printf("%s\n", str); free(str); } for ( i = 1; i <= 5; i++) { char *str=concat(“abc”, “012345”[digit]); free(str); printf("%s\n", str); free(str); }
DANGLING POINTERS char *p=malloc(4); … free(p); … strcpy(p,”abc”); /*wrong*/ Several pointers may point to the same block
of memory. When the block is freed, all these pointers are left dangling.
MEMORY ALLOCATION RULES If memory is allocated it must be freed.If memory is allocated it must be freed. Do not use memory after it is freed.Do not use memory after it is freed.
Do not free memory that will be used Do not free memory that will be used later.later.
Do not free a block of memory more Do not free a block of memory more than once.than once.
Do not free memory that was not Do not free memory that was not allocated.allocated.
Do not use memory outside the bounds Do not use memory outside the bounds of an allocated block.of an allocated block.
LINKED LISTS A linked list linked list is a chain of structures
(nodesnodes), with each node containing a pointer to the next node in the chain.
The last node in the list contains a null pointer.
DECLARING A NODE TYPE struct node{ int value; struct node *next; } struct point { double x,y; }; struct vertex { struct point element; struct vertex *next;}
BUILDING LINKED LIST First, create an empty list struct node *first=NULL;struct node *first=NULL; Then create nodes one by one:
Allocate memory for the node struct node *new_node;struct node *new_node; new_node=malloc(sizeof (struct new_node=malloc(sizeof (struct
node));node));
Store data into the node (*new_node)..value=10; new_node->->value=10;Insert the node into the list
10new_node
new_node
INSERTING A NODE AT THE BEGINNING OF THE LIST If firstfirst points to the first node of the linked
list: new_node->next=first;new_node->next=first; first=new_node;first=new_node;struct node *first=NULL, *new_node;
new_nodefirst
new_node=malloc(sizeof (struct node));
new_nodefirst
INSERTING A NODE AT THE BEGINNING OF THE LISTnew_node->value=10;
firstnew_node->next=first;
10new_node
first 10new_node
first=new_node;first
10new_node
INSERTING A NODE AT THE BEGINNING OF THE LISTnew_node=malloc(sizeof (struct node));
new_nodefirst 10
new_node->value=20;
new_node->next=first;
20new_node
20new_node
first=new_node;
first 10
first 10
first20
new_node10
SEARCHING A LINKED LIST for (p=first; p!=NULL; p=p->next){… }
int value=20; struct node *p; for (p=first; p!=NULL; p=p->next) { if (p->value== value) return p; }
struct node *find(struct node *list, int n){ while (list!=NULL and list->value!=n ) p=p->next; return list; }
first
20
10
INSERTING A NODE AT THE MIDDLE OF THE LIST struct *node p=first; struct node * cur= find(p, 10);
struct node *tmp =malloc(sizeof (struct node));
tmp->value= cur->value; tmp->next = cur->next_ptr;
first
20
10
cur
cur->value = 15;
cur->next = tmp;
10tmp
first 20
cur15
first 20
cur15
DELETING A NODE FROM THE LIST struct *node p=first; struct node * cur= find(p,
20); struct node *tmp; tmp = cur->next;cur->value = tmp->value;
cur->next = tmp->next;
first
20
15
cur
tmp10
first 15
cur15
10
tmp
free(tmp);
first 15
cur15
10
tmp
first 15
10
top related