lo del tamaño depende del compilador, por ejemplo el c18 un int son 16bits, (2bytes) un char 8bits(1byte), es algo que debes tener muy en cuenta con los pics.
El ultimo numero del array no se usa, si pones 8 quieres decir que tienes un array desde 0 hasta 7 (ambos incluidos), osea un arreglo de 8.
En una string unicamente se le pone el 0 despues del ultimo caracter para que si trabajamos con una funcion que maneje strings (strcat por ejemplo) toma el 0 como el final de la "palabra", osea un "hola" tendria un tamaño de 5 bytes, el 5º byte es el 0 que "delimita" el final de la palabra".
Los punteros son sencillos y a la vez liosos.
si tu declaras un int *a; estas diciendo que en la "variable a" apuntara a una direccion de memoria.
Osea imaginemos, si ponemos a=0xFF; estamos diciendo que "a" esta apuntando a la memoria direccion de memoria 0xFF.
Ahora queremos que un puntero apunte a la memoria de otra variable.
int *a, var;
a=&var (el & se pone para indicar que queremos saber su direccion de memoria).
si var esta almacenado en la ram, en la posicion 0x01 de la ram, entonces "a" apuntara tambien a 0x01.
ahora queremos saber que "valor" contiene nuestra posicion de memoria, seria asi:
int *a, var, b;
a=&var;
b=*a; (el * se pone para que te muestre el VALOR DE LA DIRECCION A LA QUE APUNTA "a"). si var vale 90, entonces *a tambien vale 90, y b en este caso tambien valdra 90.