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

// globals
char y[10];
int i,j,k = 0;  				// general counters

void printArray(int mArray[], int arraySize) {
	//
	// print contents of array
	//
	// if arraySize = -1 then array terminated
	// with null (string)
	
	printf("[");

	// is null delim.
	if (arraySize == -1) {
		for (arraySize = 0; mArray[arraySize] != NULL; arraySize++) {
		}
	}
		
	for (i = 0; i <= arraySize ; i++) {
		
		if (mArray[i] == NULL)
			printf("NULL");
		else
			printf("%d", mArray[i]);
		
		if (i < arraySize)
			printf(",");
	}

	printf("]");

}

void printCharArray(char mArray[], int arraySize) {
	//
	// print contents of array
	//
	// if arraySize = -1 then array terminated
	// with null (string)
	
	printf("[");

	// is null delim. (p.s. could use strlen!)
	if (arraySize == -1) {
		for (arraySize = 0; mArray[arraySize] != NULL; arraySize++) {
		}
	}
		
	for (i = 0; i <= arraySize ; i++) {
		
		if (mArray[i] == NULL)
			printf("NULL");
		else
			printf("%c", mArray[i]);
		
		if (i < arraySize)
			printf(",");
	}

	printf("]");

}

void initArray(char mArray[], int arraySize) {
	//
	// ensure all values in array are set to NULL
		
	for (i = 0;  i <= arraySize ; i++) {
		mArray[i] = NULL;
	}
}

char * mStrncpy1(char s1[], char s2[], int n) {
	//
	// strncpy copies exactly n characters from s2 into s1
	// -- array version
	
	int i,					  // general purpose counter
	    srcLen = strlen(s2);  // length of s2
	
	// loop n times, copying either chars or nulls
	for (i = 0; i < n; i++) {
		if (i < srcLen)
			s1[i] = s2[i];
		else
			s1[i] = NULL;
	}

	return s1;
}


char * mStrncpy2(char * s1, char * s2, int n) {
	//
	// strncpy copies exactly n characters from s2 into s1
	// -- pointer version
	
	int i = 0;          // i counts number of characters copied
	char * cpys1 = s1;  // make copy of s1 pointer to return

	// copies from s1 into s2 and checks for n limit
	while( i++ < n && (*s1++ = *s2++) ) ;

	// fill empty space with '\0'
	for(; i < n; s1++, i++) {
		*s1 = '\0';
	}

	return cpys1;
}


main()
{

	char   x[10];   /* an array of chars */
	int    a,b;     /* a couple of ints  */
	char * p;       /* one pointer       */
	int    mya[] = {1, 2, 3, 4, 5, 6};
	int    myb[] = {6, 5, 4, 3, 2, 1};
	int  * mp;
	char   s[] = "COOKIE";
	char * t = &s[2];
	
	char s1[100] = "abcdefghijklmnopqrstuvwxyz";
	char s2[100] = "12345678901234567890";
	
	// empty arrays
    initArray(x, 10);
    initArray(y, 10);

	x[2] = '1';
	a = 12;

	p = &y[3];
	strcpy(y, "abcdefg");

	printf("%u %u %u %u %u\n", y, &y[0], &y[3], y+3, p);
	printf("%u %c %d\n", x+2, x[2], x[2]);
	printf("%s %u %c %u %c\n", y, y, y[0], p-1, p[-1]);
	printf("%u %u\n", &a, &b);
	

	printf("\n________\n");
	
	printf("(type):char array \tx (address):%u \t(value):", x);
	printCharArray(x, 10); 	printf("\n");
	
	printf("(type):char array \ty (address):%u \t(value):", y);
	printCharArray(y, 10); 	printf("\n");

	printf("(type):int        \ta (address):%u \t(value):%d\n", &a, a);
	printf("(type):int        \tb (address):%u \t(value):%d\n", &b, b);
	printf("(type):char ptr   \tp (address):%u \t(value):%d\n", &p, p);
	
	printf("\n________\n");

	printf("p[0]     = %c\n", p[0]);
	printf("*p       = %c\n", *p);
	printf("&y[1]    = %u\n", &y[1]);
	printf("y[1]     = %c\n", y[1]);
	printf("y + 1    = %u\n", y+1);
	printf("*(y + 1) = %c\n", *(y + 1));

	printf("________\n");
	
	printArray(mya, 5); 	printf("\n");
	
	printf("________\n");

	printf("a) a[2]        %d\n", mya[2]);
	printf("b) *(a + 2)    %d\n", *(mya + 2));
	printf("c) a[4] - a[2] %d\n", (mya[4]-mya[2]));
	printf("d) a[a[4]-2]   %d\n", mya[mya[4]-2]);
	printf("e) (a+10)[-8]  %d\n", (mya+10)[-8]);

	printf("________\n");

	for (j = 0; mya[j] <= 2*mya[j+1]; j++) {
		mya[j+1] += mya[j];
		printArray(mya, 5); 	printf("\n");
	}

	printf("________\n");

	printArray(myb, 5); 	printf("\n");

	printf("________\n");

	//	int myb[] = {6, 5, 4, 3, 2, 1};

	mp = myb;
	printf("a) *p;             %d\n", *mp);
	printf("b) p[3];           %d\n", mp[3]);
	printf("c) *((p + 3) - 1); %d\n", *((mp + 3) - 1));
	printf("d) p[*(p + 2)];    %d\n", mp[*(mp + 2)]);

	mp = myb;
	printf("e) *(++p);         %d\n", *(++mp));
	
	mp = myb;
	printf("f) ++*p            %d\n", ++*mp);

	// undo previous statement!
	--*mp;
	
	mp = myb;
	
	printf("g) *p++;           %d\n", *mp++);
	printf("!) *p;             %d\n", *mp);

	printf("________\n");
	
	/*
	for (mp = myb ; mp < 6 ; mp++)
		printf("!!! %d/n", *mp);
	*/

	printf("XXX\n");
	printf("________\n");
	
	printf("%s\n", s);
	printf("%d\n", strlen(s));
	printf("%d\n", strlen(t));
	printf("%c %c\n", s[2], t[0]);
	printf("%d\n", strlen(t + 1));
	printf("%s\n", ++t);
	printf("________\n");

	for (i = 0 ; s[i] != NULL; i++)
		printf("%c\n", s[i]);
	
	//	putchar(s[i]);
	printf("________\n");

	for (t = s ; *t ; t++)
		printf("%s", t);

	printf("________\n");

	mStrncpy2(s1, s2, 24);
	printCharArray(s1, 30); 	printf("\n");
	printCharArray(s2, 30);     printf("\n");
}


