Address
Review of Arrays
                                             int m[4]
   Array name                               m   (int [])   100
       refers to constant memory location
       Cant change the memory location           ???      100
                                                   (int)
        but the array elements can be
        changed                                    ???      104
                                                   (int)
       Space is allocated at declaration          ???      108
                                                   (int)
        time                                       ???
                                                   (int)
                                                            112
         Review of call-by-value
   Arguments passed by value
       A temporary copy of each argument is created,
        solely for use within the function call
                                               f()
    void f(int x, int y) { }           17           42
                                       (int)      (int )
                                       x         y
        main() {
            int a = 17, b = 42;         17           42
            f(a,b);                    (int)         (int)
            .... }                         a        b
                                               main()
       Passing Arrays to functions
   Specify the name of the array without brackets [].
   Name of array is address of first element.
   Function knows where array is stored: modifies
    original location                       f()
    (Call by Reference)                 int     2
                                                 (int )
    void f(int x[],int y) {}         x[]       y
    main() {
        int b=2, a[b]={1,2};            int         2
        f(a,b);                                   (int)
        .... }                          a          b
                                              main()
#include<stdio.h>
float avg(int a[], int size)
{
      int i;
      float total = 0.;
      for(i = 0; i < size; i++)
         total+=a[i];
      return total/size;
}
main(){
    int array[4] = {2, 4, 6, 8};
     printf("Average : %f",avg(array,4));
}
#include <stdio.h>
void printArray(int array[][4]); /* declare function */
int main() {
  int array[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
  printArray(array);
  return 0;
}
void printArray(int a[][4]) { /* define function */
  int i, j;
  for(i=0 ; i<3 ; i++) {
    for(j=0 ; j<4 ; j++) {
      printf("%2d ", a[i][j]);
                                           Output
    }
                                           0 1 2 3
    printf("\n");
                                            4 5 6 7
  }
                                            8 9 10 11
}
                        Row of house 
                        Row of memory cells    House No. 
                                               Memory Address
       Pointers
                                          House No:
                                          0x1234
                                          0x1236
People inside house 
 Content of memory
cells                                         0x1238
                                              0x1240
&<variable-name>: specifies the address of the variable
Print the address
 #include <stdio.h>
 int main() {
        int x = 0;
        printf("Address of x ");
        printf("= 0x%p \n", &x);
        return 0;
 }
Address of x = 0x7fffbfbf34dc
        What are pointers?
   Variables that store the address of other
    variables.
   Declared just like a variable except that
    it has the dereference operator
       int *p;
  Example
                        a       b   p
int a = 1, b = 2, *p;       1   2
    p = &a;             a       b   p
                            1   2
                        a       b   p
     b = *p;            1
#include <stdio.h>
int main() {
     int x = 12; int *ptr = &x;
     printf("Address of x: 0x%p\n", ptr);
     printf("Address of x: 0x%p\n", &x);
     printf("Address of ptr: 0x%x\n", &ptr);
     printf("Value of x: %d\n", *ptr);
     return 0;
}
Declarations and Initializations
int i = 3, j = 5, *p = &i, *q = &j, *r;
double x;
Expression          Value                   Type
p == &i                   p == (&i)          1
**&p                      *(*(&p))           3
r = &x                     illegal
7 ** p / *q + 7      ((7 *(* p)) / (*q)) + 7 11
* (r = &j) *=* p (* (r = (&j))) *= (* p)      15
  Call-by-Reference
void swap(int *p, int *q) {
  int tmp;
  tmp=*p; *p=*q; *q=tmp; }
int main(void) {
  int i = 3, j = 5;
 printf(Value of i=%d,j=%d\n,i,j);
   }
  Call-by-Reference
void swap(int *p, int *q) {
     int tmp;
     tmp=*p; *p=*q; *q=tmp;
}
   p       ?=100      q       ?=200
   100      int1      200     int2
  Call-by-Reference
void swap(int *p, int *q) {
     int tmp;
     tmp=*p; *p=*q; *q=tmp;
}
   p       ?=100      q       ?=200
   100     int1       200     int2
 tmp
  int1
  Call-by-Reference
void swap(int *p, int *q) {
     int tmp;
     tmp=*p; *p=*q; *q=tmp;
}
   p       ?=100      q       ?=200
   100     int2       200     int2
 tmp
  int1
  Call-by-Reference
void swap(int *p, int *q) {
     int tmp;
     tmp=*p; *p=*q; *q=tmp;
}
   p       ?=100      q       ?=200
   100     int2       200     int1
 tmp
  int1
                        1. Declare function parameter
                        to be a pointer
  Call-by-Reference
void swap(int *p, int *q) {
  int tmp;
  tmp=*p; *p=*q; *q=tmp; }
                          2. Use dereferenced pointer
int main(void) {          in the function body
  int i = 3, j = 5; 3. Pass address as argument
  swap(&i, &j);      to the function call
  printf(Value of i=%d,j=%d\n,i,j);
    }
    Pointer Arithmetic
   int *p = &i;         p: 100
                            104
                         i: 104
                             int
     Pointer Arithmetic (2)
                                    p: 100
   int *p = &i;
                                      108
   ++p;
                                    i: 104
       Assuming an integer
                                        int
        is 4 bytes, it will store
        the value 108.              : 108
   += and -= are valid                int
   *= and /= are illegal
Arrays & Pointers
   An array name stores the address of the
    first element of the array. Pointers also
    store address of memory locations.
   An array name is an address or pointer
    that is fixed but the values of pointer
    variables are not fixed.
       a[0] is equivalent to *a
       a[i] is equivalent to *(a + i)
#include<stdio.h>
float avg(int a[], int size)
{
      int i;
      float total = 0.;
      for(i = 0; i < size; i++)
         total+=a[i];
      return total/size;
}
main(){
    int array[4] = {2, 4, 6, 8};
     printf("Average : %f",avg(array,4));
}
#include<stdio.h>
float avg(int *a, int size)
{
      int i;
      float total = 0.;
      for(i = 0; i < size; i++)
         total+=*(a+i);
      return total/size;
}
main(){
    int array[4] = {2, 4, 6, 8};
     printf("Average : %f",avg(array,4));
}
Write a program that takes as input N
 integers and print the numbers in
 reverse order?
Dynamic Memory Allocation
   So far, memory allocation was handled
    automatically at compile time.
   Certain cases you dont know how
    much memory to set aside
       Dynamically allocate memory to variables
        at run-time. Example is an unsized array.
   The following four functions are used:
    malloc(), calloc(), realloc() and free().
malloc()
   Requires one argument, the number of
    bytes you want to allocate dynamically
   If successful, returns a void pointer
       assign this to a pointer variable
       int *p;
        p = malloc(10 * sizeof(int));
   If memory allocation fails, malloc will
    return a NULL pointer.
free()
   free(ptr) will release the memory that
    was allocated to the pointer variable ptr.
   It is good practice to free memory when
    you have finished with it.
#include <stdio.h>
#include <stdlib.h> /* required for the malloc and free
                       functions */
int main() {
       int number, i;
       int *ptr;
       printf("How many ints would you like store? ");
       scanf("%d", &number);
        /* allocate memory */
       ptr = malloc(number*sizeof(int));
       if(ptr!=NULL) {
               for(i=0 ; i<number ; i++)
                       scanf("%d",(ptr+i));
/* print out in reverse order */
for(i=number - 1 ; i>=0 ; i--) {
      printf("%d\n", *(ptr+i));
    }
/* free allocated memory */
    free(ptr);
    return 0;
  }
  else {
    printf("\nMemory allocation failed.\n");
    return 1;
  }
}
     Review
     Allocating memory @run-time
    char *ptr;
    ptr = malloc(100);
    if (ptr == NULL) printf(..!!);
   malloc allocates contiguous block of
    memory of at least 100 bytes and
    returns the address of the first byte
   Returns NULL if the allocation fails.
     Review
     De-allocating memory
free(ptr);
   De-allocates the block of memory
    pointed to by ptr.
   After calling free, ptr is uninitialized
    and using ptr will result in error
   The lifetime of an allocated block is
    determined by malloc/calloc/realloc
    and free; other functions have no
    effect on its existence.
calloc()
   Allocates continuous space for an array
    of elements.
   Requires two arguments,
       calloc(n, el_size), allocate space for n
        elements each of el_size
       space shall be all initialized to 0 bits
   If successful, returns a void pointer else
    NULL
#include <stdio.h>
#include <stdlib.h> /* required for the malloc and free
                       functions */
int main() {
       int number, i;
       int *ptr;
       printf("How many ints would you like store? ");
       scanf("%d", &number);
        /* allocate memory */
       ptr = malloc(number*sizeof(int));
       if(ptr!=NULL) {
               for(i=0 ; i<number ; i++)
                       scanf("%d",(ptr+i));
#include <stdio.h>
#include <stdlib.h> /* required for the malloc and free
                       functions */
int main() {
       int number, i;
       int *ptr;
       printf("How many ints would you like store? ");
       scanf("%d", &number);
        /* allocate memory */
       ptr = calloc(number,sizeof(int));
       if(ptr!=NULL) {
               for(i=0 ; i<number ; i++)
                       scanf("%d",(ptr+i));
     malloc          Vs.          calloc
   Allocates memory        Allocates as a
    in bytes                 sequence of bytes
   Allocated space is      Allocated space
    not initialized          initialized to zero.
realloc()
   Allows to allocate more memory space
    without losing data.
   Requires two arguments,
       realloc(*ptr, el_size),
       First is the pointer referencing memory
       Second is the total no. of bytes you want to
        reallocate.
   If successful, returns a void pointer else
    NULL
#include<stdio.h>
#include <stdlib.h>
int main() {
  int *ptr;
  int i;
 ptr = calloc(5, sizeof(int));
 if(ptr!=NULL) {
        *ptr = 1;
        *(ptr+1) = 2;
        ptr[2] = 4;
        ptr[3] = 8;
        ptr[4] = 16;
ptr = realloc(ptr, 7*sizeof(int));
    if(ptr!=NULL) {
      printf("Now allocating more memory... \n");
      ptr[5] = 32; /* now it's legal! */
      ptr[6] = 64;
        for(i=0 ; i<7 ; i++) {
          printf("ptr[%d] holds %d\n", i, ptr[i]);
        }
        realloc(ptr,0); /* same as free(ptr); - just fancier! */
        return 0;
    }
}
Using const qualifier with pointers
   const qualifier means variable cannot
    be changed
   int *const ptr1;
       points to a constant memory location
       must be initialized when defined
   *const int ptr2;
       ptr2 points to a memory location that stores
        constant integers.
#include <stdio.h>
void xyz(int *number) {
       *number = *number/2;
}
void xyz2(int number) {
       number = number/2;
}
int main() {
       int i = 8;
       int *ptr = &i;
       xyz(ptr);
       printf("The value of i is %d\n", i);
       xyz(&i);
       printf("The value of i is %d\n", i);
       xyz2(i);
       printf("The value of i is %d\n", i);
       return 0;
}
    Character Array versus Strings
   A character array
       char array1[4] = {d','e','e',r};
   A string constant
       char array2[7]
           ={c','o','f','f','e','e','\0'};
Strings
   A string is an array of characters
    terminated by the end of string sentinel
    \0 or null character.
   String constants are written within
    double quotes ().
   Conversion parameter %s causes the
    value of the corresponding string
    argument to be printed.
Initializing & Printing Strings
   char str1[] = Hello World; // Compiler
    counts the number of characters
   char *str2 = Hello World;
   printf(%s, str1);
   printf(%s, str2);
   printf(First Character = %c, str1[0]);
   printf(First Character = %c, *str2);
Declarations and Initializations
      char str1[] = "Hello World!";
      char *str2 = "Hello World";
Expression                 Value
printf(" %s", str1+1);        ello World!
printf(" %s", str2+1);        ello World
printf(%c, str1[2]);            l
printf(%c, *(str2+2));          l
printf(%c, *(str2)+2);          J