500 likes | 526 Views
Dive into C programming with a focus on local and global variables, storage classes, pointers, and function call structures. Learn about storage classes like auto, register, static, and extern, as well as the scope and lifetime of variables in C.
E N D
Program Structure • Local and Global Variable • Storage Classes • Pointers • Function Call
Local Variable • variables declared within a function body #include <stdio.h> int main() { int next, n; /* next input, number of inputs */ long sum = 0; /* running total */ double avg; /* average of input values */ for (n = 0; scanf("%i", &next) == 1; n++) sum += next; avg = (n == 0) ? 0.0 : (double) sum / n; printf("Average of %i values is %f.\n", n, avg); return 0; } next, sum, avg are local variables of main
Local Variable • initializing local variables • don’t count on local variables automatically being initialized to zero long sum = 0; /* running total */
Local Variable • variables declared within a block #include <stdio.h> int main() { int next, n; /* next input, number of inputs */ long sum = 0; /* running total */ for (n = 0; scanf("%i", &next) == 1; n++){ sum += next; { /* compute and print input average */ double avg = (n == 0) ? 0.0 : (double) sum / n; printf("Average of %i values is %f.\n", n, avg); } return 0; } avg is declared when it is needed.
Local Variable • block/compound statements • group of statements surrounded by braces { statement; . . statement; } or statement, statement;
int main() { int x; x= 25; x= sq (x); printf(“%d\n”, x); return 0; } int sq ( int x) { x=x*x; return x; } Scope of Variable
Scope of Variable #include <stdio.h> int sq(int x); int main() {int x; x= 25; printf(" The address of x in main is %d\n", &x); x= sq(x); printf("%d\n", x); return 0; } int sq(int a) { printf(" The address of a in sq is %d\n", &a); printf(" what is x %d\n", x); a=a*a; return a; }
Local Variable Lifetime • they exist only from block entry to block exit • they exist/are accessible only within the function where they are declared • when enter a block/function, space is reserved for its local variables • when exit the block/function, the reserved space is free
Global Variable • exist throughout the life of the program • known to all program • AVOID GLOBAL VARIABLES WHENEVERPOSSIBLE (for information hidden)
unsigned long charcnts[UCHAR_MAX + 1]; /* 0..UCHAR_MAX */ int main() { void print_counters(void); int c; while(c = getchar(), c != EOF) charcnts[c]++; print_counters(); return 0; } void print_counters(void) { int i; for (i = 0; i < UCHAR_MAX; i++) if (charcnts[i]) /* write count only when nonzero */ { printf("\\%03o ", i); isprint(i) ? printf("(%c)", i) : printf(" "); printf(": %lu\n", charcnts[i]); } }
Storage Classes • A variable’s storage class provides information about its visibility, lifetime, and location. • auto • register • static • extern
Storage Class - Auto • it is the default storage class • it derives from automatic creation and removal on block entry and exit • it is used to make local variable explicit • it is stored in memory • { { • auto int x, y; int x, y; • . . • } }
Storage Class • it is the default storage class • it derives from automatic creation and removal on block entry and exit • it is used to make local variable explicit • it is stored in memory • { { • auto int x, y; int x, y; • . . • } }
Storage Class - Register • variables are stored in the machine’s high speed registers • making frequently accessed variables register leads to faster and smaller programs • restrictions • only local variables and function parameters • not global variables • register variables is not kept in memory so can’t take it address with &
Storage Class - register • restrictions • can’t use scanf/similar functions to read a value directly into a register variable Example /* Faster version of array searching function. */ int table_search(int a[], register int n, register int t) { register int i; for (i = 0; i < n && a[i] != t; i++) ; /* search for matching value */ return (i != n) ? i : -1; }
Storage Class - static • as local variables live only within the block in which they reside, it will be erased when exits the block/function • keep the variable alive after leaving the block • alternative to global variable
Storage Class - static Example /* Keep a count of times function is called (buggy version). */ #include <stdio.h> int main() { void testfunc(void); testfunc(); testfunc(); testfunc(); return 0; } void testfunc(void) { int cnt = 0; printf("testfunc call #%i\n", ++cnt); }
Storage Class - static Example /* Keep a count of times function is called (working version). */ #include <stdio.h> int main() { void testfunc(void); testfunc(); testfunc(); testfunc(); return 0; } void testfunc(void) { staticint cnt= 0; printf("testfunc call #%i\n", ++cnt); }
Storage Class - extern • use with global variables • to refer to global variable • its declaration will not lead to any memory allocation • usage • define global variable once, and use external declaration everywhere else
Storage Class - extern Example /* A program to count the different characters in its input. Ituses global variables to hold the counts. */ #include <stdio.h> #include <limits.h> unsigned long charcnts[UCHAR_MAX + 1]; /* 0..UCHAR_MAX */ int chars = UCHAR_MAX + 1; int main() { void print_counters(void); int c; while(c = getchar(), c != EOF) charcnts[c]++; print_counters(); return 0; }
Storage Class - extern Example /** Function to print the character counts. */ #include <stdio.h> #include <ctype.h> void print_counters(void) {extern unsigned long charcnts[];/* table of counts */ extern int chars; /* entries in table */ int i; for (i = 0; i < chars; i++) if (charcnts[i]) /* write count only when nonzero */ { printf("\\%03o ", i); isprint(i) ? printf("(%c)", i) : printf(" "); printf(": %lu\n", charcnts[i]); } }
Storage Class - extern • void function(void) • { • extern variable.. • . • } • an extern within a function provides type information to just that function
Storage Class - extern Example /* A program to count the different characters in its input. Ituses global variables to hold the counts. */ #include <stdio.h> #include <limits.h> unsigned long charcnts[UCHAR_MAX + 1]; /* 0..UCHAR_MAX */ int chars = UCHAR_MAX + 1; void print_counters(void); int main() {int c; while(c = getchar(), c != EOF) charcnts[c]++; print_counters(); return 0; }
Storage Class - extern Example /* Function to print the character counts. */ #include <stdio.h> #include <ctype.h> extern unsigned long charcnts[];/* table of counts */ extern int chars; /* entries in table */ void print_counters(void) {int i; for (i = 0; i < chars; i++) if (charcnts[i]) /* write count only when nonzero */ { printf("\\%03o ", i); isprint(i) ? printf("(%c)", i) : printf(" "); printf(": %lu\n", charcnts[i]); } }
Storage Class - extern • extern variable.. ; • void function(void) • { • . • } • an extern declared outside provides type information to all functions within a file by placing external declarations before any of them
Type Qualifier • Storage Classes provide information about a variable’s lifetime and visibility • Type Qualifiers provide additional information about how the variable is going to be used • const int PAGELEN =60; • declares PAGELEN as an int and its value should remain constant throughout its lifetime
Type Qualifier #include <stdio.h> #include <ctype.h> #include <limits.h> int main() { void print_counters(const unsigned long charcnts[]); static unsigned long charcnts[UCHAR_MAX + 1]; /* 0..UCHAR_MAX */ int c; while(c = getchar(), c != EOF) charcnts[c]++ print_counters(charcnts); return 0; }
Type Qualifier void print_counters(const unsigned long charcnts[]) { int i; for (i = 0; i < UCHAR_MAX; i++) if (charcnts[i]) /* write count only when nonzero */ { printf("\\%03o ", i); isprint(i) ? printf("(%c)", i) : printf(" "); printf(": %lu\n", charcnts[i]); } }
Type Qualifier • why not using #define instead of const • constallows the compiler to flag as an error any attempt to assign a value to that variable • #define is can’t be replaced with const totally • Example • #define MAXVALS 100 • const int MAXVALS = 100 • unsigned long buckets[MAXVALS];
Header File • to avoid defining external declarations for constantly used variables and definition /*Main program using extern yes or no. */ #include <stdio.h> int main() { int yesorno(void); extern const int YES, NO; printf("Enter a YES or NO answer: "); (yesorno() == YES)?printf("YES!\n"):printf("NO!\n"); return 0; }
Header File / * Prototypes and constants in "yesorno.h".*/ extern const int YES; extern const int NO; int yesorno(void); /*Main program using extern yes or no. */ #include <stdio.h> #include “yesorno.h” int main() { printf("Enter a YES or NO answer: "); (yesorno() == YES)?printf("YES!\n"):printf("NO!\n"); return 0; }
Pointer • What is it? It is simply a data type that can hold address int data; • the compiler reserves a memory location to data • lets it be location 10000 10000 • 10000 is data’s address or it is a pointer to data 10000
Pointer • In C, a data’s value can be accessed directly by providing its name or indirectly through a pointer • its called indirect pointer access or call-by-reference for parameter passing in function call
Pointer • int *iptr ; /* pointer to integer */ • declaration allocates space for the named pointer variable, but not make it point to anything • to use it, use the address operator & to return the address of its operand • iptr = &data ; pointer iptr points to data, assuming data is stored in memory location 10000, then iptr contains 10000
Pointer • Accessing the pointed to value uses the indirection * operator int data=0; int value; int *iptr; iptr = &data; value = *iptr; what is value? 0
Pointer int *iptr=NULL; int i =0; int n=17; int j=23; Addresses: &i=8eac8 &n=8eac4 &j=8eac0 Initial values: iptr=0 i=0 n=17 j=23 iptr = &i; n = *iptr; Later values: iptr=8eac8 i=0 n=0 j=23 *iptr = j; *iptr = *iptr + 10; Final values: iptr=8eac8 i=33 n=0 j=23
Pointer • Possible error • Dereference a pointer variable before it is assigned with an address • Without initialization of pointer variable as NULL
BASIC DATA OPERATION C passes data/parameters by value. Calling a function, the following will be processed: allocates space for its parameters copies the values passed as the function’s arguments When the function returns, this space is de-allocated. That is, a function cannot change values of its arguments.
BASIC DATA OPERATION int main( ){ int x,y; scanf(“%d”, &x); y= square(x); } int square(data) int data; { return(data*data); } A memory location is allocated for data when the square function is called. It is also for the storage of the intermediate result data*data. After that, the locations for data and data*data will be de-allocated.
PASS-BY-VALUE int main( ){ .. functionx(arg); …. void functionx(arg) int arg; {…… When calling a function, the value of the argument is passed. The function will operate on the value passed from the calling statement, but not on the argument itself. value
PASS-BY-VALUE int main( ){ int x; scanf(“%d”, &x); x = square(x); } void square(data) int data; { return(data*data); } int main( ){ int x; scanf(“%d”, &x); square(x); } void square(data) int data; { return(data*data); } * bad function call
PASS-BY-REFERENCE #include <stdio.h> int main( ) { int x; scanf("%d", &x); square(&x); printf("%d \n", x); } int square(int *data) { *data=(*data)*(*data); }
PASS-BY-REFERENCE use & to pass a pointer to the variable the function then dereferences the pointer with * to access or modify the variable’s value
PASS-BY-REFERENCE /* A program that doesn't exchange two values.*/ #include <stdio.h> int main() { void swap(int x, int y); int s, t; s = 10; t = 20; printf("Before swap, s=%i, t=%i\n", s, t); swap(s, t); printf("After swap, s=%i, t=%i\n", s, t); return 0; } /* Incorrectly exchanges only values of its parameters*/ void swap(int x, int y) { int temp; temp = x; x = y; y = temp; }
PASS-BY-REFERENCE /*A program that does exchange two values.*/ #include <stdio.h> int main() { void swap(int *xptr, int *yptr); int s, t; s = 10; t = 20; printf("Before swap, s=%i, t=%i\n", s, t); swap(&s, &t); printf("After swap, s=%i, t=%i\n", s, t); return 0; } /* Correctly exchanges a pair of values in caller */ void swap(int *xptr, int *yptr) { int temp; temp = *xptr; *xptr = *yptr; *yptr = temp; }
PASS-BY-REFERENCE function (&var) . address of variable . function (*ptr) pointer { ..dereference using *operator Statement operates on *ptr; . }