Extension

C Language

Introduction

In this lesson, we will describe in a little more depth about pointers and arrays, as well as explain the concept of enum and typedef. With pointers and arrays, we will focus on pointers' relationship with two-dimensional arrays and array of strings.

Pointers and Two-Dimensional Arrays

We discussed briefly in Lesson Pointers about pointers to two-dimensional arrays. First, let's explain the relationship between two-dimensional arrays and pointers.

As we explained in the Pointers Lesson, an array variable stores the address of the initial value of that array. Therefore, it is closely related with pointers. As you remember, *(p+i) is the same as array [i]. Two dimensional arrays is an array of pointers, each pointing to another array. Using arrays, we can visualize two-dimensional arrays like:

Two-Dimensional Array Diagram Array Version

With pointers, you can point to different arrays of different lengths with much more flexibility and change lengths of arrays during execution:

Two-Dimensional Array Diagram Pointer Version

The two are the same, but different ways to visualize.

When we have int **p:

Expression Meaning
p,p+0 The address to the first element (p [0][0])
p+i The address of the ith element
*(p+i) The address of the first element of the ith array in p (p [i][0])
*(p+i)+j The address of the jth element of the ith array in p (p [i][j])
*(*(p+i)+j) p [i][j]

Here is an example of use of pointers with two-dimensional arrays:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **app(char **orig,int currlen,int slen)
{
    char **rslt;
    int i;
    rslt=malloc(sizeof(char *)*(currlen+1));
    for(i=0;i<currlen;i++)
    {
      *(rslt+i)=malloc(sizeof(char)*slen);
      strncpy(*(rslt+i),*(orig+i),slen-1);
    }
    *(rslt+currlen)=malloc(sizeof(char)*slen); 
    for(i=0;i<currlen;i++)
    {
      free(*(orig+i));
    }
    free(orig);
    return rslt;
}

int main(void) {
    char **strlst=malloc(sizeof(char *)*2);
    strlst [0]=malloc(sizeof(char)*30);
    strlst [1]=malloc(sizeof(char)*30);
    strlst=app(strlst,2,30);
    strcpy(strlst [0],"This is the first string.");
    strcpy(strlst [1],"This is the second string.");
    strcpy(strlst [2],"This is the third string.");
    printf("%s\n%s\n%s\n",strlst [0],strlst [1],strlst [2]);
    free(strlst [0]);
    free(strlst [1]);
    free(strlst [2]);
}


typedef

typedef in C allows you to define your own data type. A typedef use can be like:
typedef char **StringList;
Creating your own data type StringList, which is type two-dimensional array. This is similar to the #define macro substitution, but can be a little more flexible in some situations. For example, you can use typedef to define a pointer to a function (you can define normal pointer to functions with: return_type (*name)(parameters_type_list);, such as int (*fnc_ptr)(int,int,char);) like:
typedef int (*FncPtr)(int,int,char);
to create a type FncPtr that points to a function which accepts arguments of type int, int, and char, returning a integral value.

With typedef, you can make your intentions with a variable clearer, for example, when we have typedef int Len;, we know that a variable of type Len stores a length, instead of when we only know it is an integer.

Note: with pointers to functions, after you assign a function to them, call them like: fp(arguments);


enum

enum in C allows you to create a type of data with a specified range of values. For example, we can declare a data type mode with values of "TEXT", "URL", or "NONE":
enum mode
{
NONE,
TEXT,
URL,
};
This will create a data type mode with possible values of NONE, TEXT, and URL. Note that in enum, the values are integral starting from 0 for the first value by default (NONE: 0, TEXT: 1, URL: 2), but you can assign other values to them in your declaration (only integers).

To declare a variable of type mode:
mode curr_m=TEXT;

enum can be useful in situations such as:

#include <stdio.h>
/*Calculates and lists all the possibilities of randomly drawing three balls from a bag with balls
of colors red, blue, and yellow (assume each has an infinite amount and considering order of draw)*/

enum color
{
  RED,
  BLUE,
  YELLOW,
};

void print_color(enum color ball)
{
  if(ball==RED)
   {
     printf("Red ");
   }
  else if(ball==BLUE)
   {
     printf("Blue ");
   }
  else
   {
     printf("Yellow ");
   }
}

int main()
{
  int b1,b2,b3;
  for(b1=RED;b1<=YELLOW;b1++)
   {
     for(b2=RED;b2<=YELLOW;b2++)
      {
        for(b3=RED;b3<=YELLOW;b3++)
         {
           print_color(b1);
           print_color(b2);
           print_color(b3);
           printf("\n");
         }
      }
   }
}

Red Red Red
Red Red Blue
Red Red Yellow
Red Blue Red
Red Blue Blue
Red Blue Yellow
Red Yellow Red
Red Yellow Blue
Red Yellow Yellow
Blue Red Red
Blue Red Blue
Blue Red Yellow
Blue Blue Red
Blue Blue Blue
Blue Blue Yellow
Blue Yellow Red
Blue Yellow Blue
Blue Yellow Yellow
Yellow Red Red
Yellow Red Blue
Yellow Red Yellow
Yellow Blue Red
Yellow Blue Blue
Yellow Blue Yellow
Yellow Yellow Red
Yellow Yellow Blue
Yellow Yellow Yellow



<< Previous TOC Next >>