O tipo Char no C/C++
Devido a minha grande dificuldade em entender os diversos tipos de char que a linguagem C apresenta, decidi escrever esse post para aprender mais sobre essa variável que certamente é a pior das variáveis que existe nas linguagens de programação, na minha opinião.
Particularmente eu acho que programar em C puro hoje em dia não é viável, eu programo em C++ usando as bibliotecas do Qt 4.5 o que é um mundo totalmente diferente do C, mas como nesse semestre na faculdade estou fazendo a cadeira de programação paralela e distribuída, e o cluster da faculdade onde testamos os nosso programas só compila programa em C, me obriguei a estudar o C novamente linguagem que eu já tinha abandonado a algum tempo.
Tipo char[] e o char[X]
Essas duas formas de declaração do char são equivalentes, sendo que declarando o char[] dessa forma o compilador será o responsável por determinar o tamanho do espaço que será alocado na pilha para a variável local.
Ex:
char var1[10] = “teste”; // Ocupa 10 caracteres na pilha
char var2[] = “teste”; // Ocupa 6 caracteres na pilha (5 mais o ‘\0’ que indica fim da string
Como a constante “teste” é copiada para o espaço alocado, você pode alterar o conteúdo da variável sem ter nenhum problema. Mas não pode retornar esse tipo de variável, pois elas são destruídas ao finalizar a execução da função que as criou, pois elas estão na pilha.
Tipo char *
O tipo char* você aloca apenas o espaço para um endereço de memória, então:
char *var3 = “outro”;
Aponta diretamente para a constante “outro”, de modo que você não pode alterar esta variável. No entanto você pode retornar a variável, pois nesse caso você estaria retornando apenas um número que representa um endereço para uma constante.
Obs.: A declaração para esse tipo de variável deve ser “const char *var3= …”, pois aponta para uma constante.
Outra dúvida que tinha é com relação a passagem de parâmetros char em funções, não existe diferença na passagem dos parâmetros com char[], char[10] ou char*, em todos estes casos está sendo passado o endereço da variável. Se este parâmetro pode ser alterado ou não, depende inteiramente de como a variável passada foi declarada na rotina que chamou a função em questão. Para que o usuário da função saiba se o parâmetro será alterado ou não, você deve indicar isto através do modificador ‘const’.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include void f1(char s[10]) { s[0] = 't'; } void f2(char s[]) { s[0] = 'n'; } void f3(char *s) { s[0] = 'o'; } int main(void) { char s1[10] = "Teste..."; char s2[] = "Teste..."; char *s3 = "Outro..."; printf("1a: "); f1(s1); printf("%sn", s1); printf("1b: "); f2(s1); printf("%sn", s1); printf("1c: "); f3(s1); printf("%sn", s1); printf("2a: "); f1(s2); printf("%sn", s2); printf("2b: "); f2(s2); printf("%sn", s2); printf("2c: "); f3(s2); printf("%sn", s2); printf("3a: "); // Nesta chamada vai gerar o erro f1(s3); printf("%sn", s3); printf("3b: "); f2(s3); printf("%sn", s3); printf("3c: "); f3(s3); printf("%sn", s3); return 0; } |
A saída do programa foi essa:
1a: teste…
1b: neste…
1c: oeste…
2a: teste…
2b: neste…
2c: oeste…
Segmentation fault (core dumped)
O programa compila sem problemas, mas durante a execução ele apresenta erro ao ser passado a variável ‘s3’ para ‘f1’, pois esta variável aponta para uma constante do programa, que a função tenta alterar. Se você declarasse ‘s3’ como ‘char *s3 = s1;’ ou ‘char *s3 = s2’ ou ‘char *s3; s3 = malloc(10);’ o erro não aconteceria.
Inicialização com new char(10) ou malloc(10)
A declaração do char da forma “char *var = new char(10)” é equivalente em C á “char *var = malloc(10)”, fazendo a declaração dessa forma, as variáveis são alocadas em um outro espaço de memória, chamado “heap” ou “free store”. Dessa forma não só é possível alterar a variável como também é possível retorna-la.
Um cuidado importante quando for feita a alocação dessa forma é não esquecer de realizar a liberação da memória que foi alocada, para liberar a memória alocada com o “new” usa-se o comando “delete var”, nesse caso em C++ e para liberar a memória alocada com o malloc ou calloc usa-se o “free(var)” essa é a versão em C.
Se você vai alocando espaço de memória, e nunca desaloca, o resultado é um “vazamento de memória”. Que significa que a aplicação vai ficando cada vez mais lenta e que em alguns casos pode acabar alocando toda a memória RAM do computador.
Esse texto foi totalmente feito utilizando a dica do Márcio Gil, que me postou essa resposta através do grupo linguagem-C do yahoo grupos.