Enviado em 11/12/2012 - 15:21h 
		1 e 2)
Eu recomendo que você leia a documentação para aprender com detalhes.  Resumidamente, a diferença entre 
strcpy () e 
strncpy () é que a segunda tem um campo a mais que informa o número máximo de caracteres que serão copiados.  A razão pela qual você deve preferir 
strncpy () a 
strcpy () é que é muito fácil, com esta última, exceder o tamanho máximo da string destino, e escrever bytes em áreas de memória inválidas, provocando falhas impredizíveis no programa, ou áreas ocupadas por outras variáveis, corrompendo-as.  Por exemplo, o código abaixo demonstra uma corrpução desse tipo.
#include <stdio.h> 
Ao compilar e executar o programa, eu recebo o seguinte.
$ gcc lixo.c  
Se eu transformar as variáveis em globais, movendo as três primeiras linhas de 
main () para fora do corpo da função, eu recebo o seguinte.
$ gcc lixo.c  
Em ambos os casos, se eu tivesse usando 
strncpy () com o tamanho máximo apropriado para a string destino, conforme mostrei na mensagem anterior, o conteúdo de 
str  ficaria apenas como "Est", não provocando stack smashing nem corrompendo os valores de outras variáveis.
3) Não.  O 
origem+3  significa pular os três primeiros elementos de 
origem , começando, portanto, a contar do quarto elemento.
4) Por convenção, toda string em C termina obrigatoriamente com um byte nulo (valor zero).  No programa acima, você vê que eu faço 
str[4]="str"  porque ela de fato tem quatro elementos, que são os bytes 's', 't', 'r' e nulo (em C, o byte nulo pode ser escrito como o caráter de barra invertida ("\") seguido de zero, mas o fórum do VoL engasga quando se escrevem esses dois caracteres aqui).  Assim, forçar o n-ésimo elemento (geralmente o último) de um array de caracteres a ter o byte nulo é uma forma de garantir que todas as funções do sistema conseguirão determinar o fim da string com sucesso.
Para você ver o problema de esquecer-se de garantir isso, veja o seguinte código, que deliberadamente cria um array que não tem o byte nulo na última posição de memória alocada, e, logo em seguida, a saída correspondente quando eu o compilei e executei na minha máquina (note que o tamanho e os bytes adicionais que aparecem são meio que por acaso; é imprevisível o que vai sair se você fizer o mesmo na sua máquina, podendo até dar erro fatal no programa).
#include <stdio.h> 
$ gcc lixo.c