Wednesday, October 21, 2009

Array of character pointers

/* A simple demonstration of an array of character pointers.
notice the declaration: char* family[] : similar to how you would declare an integer array int arr[].

Here is a layout of the family array in memory:

----------------------------------
| x | y | p | q | r | '\0'|
----------------------------------
A A+8 A+16 A+24 A+32

The address of family[0] is A. A points to X which contains the string "Homer".
The address of family[1] is A+8. A+8 points to Y which contains the string "Marge".

Notice that the address of family[0], family[1],family[2] etc are spaced exactly 8 bytes apart. Strictly speaking, they are spaced
sizeof(char*) bytes apart in memory.

Each element of the family array points to an address in memory. So family[0] points to an address X in memory,
family[1] points to address Y etc. Here is a representation of "Homer" in memory:

----------------------------------
| H | o | m | e | r | '\0'|
----------------------------------
x x+1 x+2 x+3 x+4 x+5

x+5 points to the terminating NULL character .

Similarly family[1] contains Y which contains marge:

----------------------------------
| M | a | r | g | e | '\0'|
----------------------------------
y y+1 y+2 y+3 y+4 y+5

familyptr is declaread as char** . It is a pointer to a character pointer.

Initially familyptr is assigned to family. This means familyptr has the address A. *familyptr will then point to address X. When you
print the string from address X , it prints the value "Homer". Then familyptr is incremented familyptr++. Pointer arithmetic comes into
play here. since familyptr is a char** , familyptr++ increments the value by 8. So familyptr now becomes A+8. *familyptr will then point to address Y. When you print the string from address Y , it prints the value "Marge". You can thus increment and print all the members of the family.
*/
#include <stdio.h>
#include <string.h>
int main(){
char* family[]= {"Homer","Marge","Bart","Lisa","Maggie"};
char** familyptr;
familyptr = family;
//Homer
printf("%s\n",family[0]);
printf("%s\n",*familyptr);
//Marge
printf("%s\n",family[1]);
familyptr++;
printf("%s\n",*familyptr);
//Bart
printf("%s\n",family[2]);
familyptr++;
printf("%s\n",*familyptr);
//Lisa
printf("%s\n",family[3]);
familyptr++;
printf("%s\n",*familyptr);
//Maggie
printf("%s\n",family[4]);
familyptr++;
printf("%s\n",*familyptr);
return 0;
}

Monday, October 19, 2009

Pointers - Example 4

/*Function Pointers: Just like integer and character pointers but points to a function. They are declared as follows: <return-type> (*functionname) (arglist)
Assigning a function pointer: functionpointer = name-of-the-function
for eg, in the code below: fptr = findsum; and later fptr = finddiff;
The only catch is that the return-type and arglist of both functions must be the same(Note that findsum and finddiff have the same proto-type).
*/

#include <stdio.h>
void findsum(int *n1, int *n2);
void finddiff(int *n1, int *n2);


int main() {
int n1 = 5, n2 = 3;
void (*fptr) (int *n1, int *n2);
fptr = findsum;
(*fptr) (&n1,&n2); //fptr points to findsum
fptr = finddiff;
(*fptr) (&n1,&n2); //fptr points to finddiff
return 0;
}

void findsum(int *n1, int *n2) {
printf("Sum is %d\n", (*n1+*n2));
}

void finddiff(int *n1, int *n2) {
printf("Diff is %d\n", (*n1-*n2));
}

Pointers- Example 3

/*Program to reverse the string using pointers.
name contains the string to be reversed.
revname will contain the reversed string.
first allocate memory for revname which will be
equal to the string-length of name plus the null-character.
Then start scanning the last byte of name and put it in the first
byte of revname(pointed to by the variable dummy). Continue this until
the number of bytes transferred equals the string-length of name. Finally
insert the null character in revname and terminate the string.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *name = "Leprechaun";
int length = strlen(name);
char *revname = malloc(length+1);
char *dummy = revname;
length = length -1; //index to the last byte of name.
for(;length>=0;length--){
*dummy = *(name+length); //or name[length]
dummy++;
}
*dummy = '\0'; //Put the null character in the reversed string.
printf("The reverse of %s is %s\n", name,revname);
free(revname);
return 0;
}

Pointers - Example 2

To find the length of the string without using strlen:
Strings are terminated by a NULL character. So scan the string character-by-character until you hit the null character in memory. The number of characters traversed until you reach the NULL character is the string-length.

#include <stdio.h>
int main() {
char* name = "Leprechaun";
int length = 0;
char *p = name;
//easy way: use built-in function. include string.h for this.
//length = strlen(name);
//using pointers
for(;*name!='\0';name++) {
length++;
}
printf("Length of %s is %d\n", p, length);
return 0;
}

Sunday, October 4, 2009

Pointers - Example 1

Program displays elements of the array in reverse order using pointers.Array has 5 elements. If p is the pointer to the first element in the array, then p+4 is the pointer to the last element in the array.The address of the last element is 16 bytes more than the address of the first element. But p is declared an integer pointer so adding 4 to the pointer advances it by 16 bytes in memory(pointer arithmetic).

Note: The stdio.h must be enclosed in between "<" and ">".

#include stdio.h
void main(){
int a[5] = {1,2,3,4,5};
int *p;
p = a ; //or p = &a[0]

printf("%x\n",p);
p=p+4; // the 4 is for the last index
//now p points to the address of the last element in the array

for(int i = 4; i>=0;i--) {
printf ("%d\n", *p); //print a[4]
p--;
}
}

Monday, September 28, 2009

Strtok function - sample implementation

The string token function (strtok) function splits a string into tokens.
In this example the de-limiter is ":". The input string is :

Himy*:name:is:bozo:

The function 'stok' will split the above string into individual strings. The output will be something like:

Himy*
name
is
bozo

The first time the function is called from main() , it is of the form:
finalstr = stok(mystr, ':');

The subsequent calls are of the form:
finalstr = stok(NULL, ':');

When the string runs out, the function returns null.


Here is a sample implementation:


//////////////////////////////////////////////////////////////////////
#include <stdio.h>

char* stok(char* teststr, char ch);

int main() {
char mystr[] = "Himy*:name:is:bozo:";
//char mystr[] = ":*&Fight!:the^%:^^&)Man\n";
char *finalstr;
finalstr = stok(mystr, ':');
printf("%s\n", finalstr);
while(finalstr!=NULL){
finalstr = stok(NULL, ':');
if(finalstr) printf("%s\n", finalstr);
}
return 0;
}


char* stok(char* teststr, char ch) {
char *dummystr=NULL;
char *start=NULL;
char *end=NULL;
char nullch = '\0';
char* address_of_null=&nullch;
static char* nexttok;

if(teststr!=NULL) {
dummystr = teststr;
} else {
if(*nexttok=='\0') return NULL;
dummystr = nexttok;
}


while(dummystr!=NULL) {
//empty string
if(*dummystr=='\0') break;
if(*dummystr!=ch){
if(!start) start = dummystr;
dummystr++;
//to handle the case where the delimiter is not at the end of the string.
if(*dummystr=='\0') {
nexttok = dummystr;
break;
}
}else{
if(start) {
end = dummystr;
nexttok = dummystr+1;
*end = *address_of_null;
break;
} else {
dummystr++;
}
}
}
return start;
}
//////////////////////////////////////////////////////////////////