Programar em C/Mais sobre funções: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
EvertonS (discussão | contribs)
Criou nova página com '== Os argumentos <tt>argc</tt> e <tt>argv</tt> == A função main(), como dissemos antes, é uma função especial. Introduzimo-la como uma função sem parâmetros; no ...'
 
EvertonS (discussão | contribs)
Sem resumo de edição
Linha 12:
 
Só não vamos ilustrar aqui o uso de ''argc'' e ''argv'' pois ainda não foram apresentadas as matrizes.
 
== Lista de argumentos==
Na linguagem C é possível funções como "printf" onde o número de argumentos podem variar.
As reticências ( ... ) indicam um numero variável de argumentos ou argumentos com tipos variável.
Ex:
void f_erro(int n, char *fmt, ...);
 
Essa declaração indica que se deve fornecer pelo menos dois argumentos, um do tipo int e um do tipo char mais pode se fornecer argumentos suplementares. Ou seja, "não há limites para sua criatividade"!
Ex:
f_erro( 3, "Erro: missão impossível ");
f_erro( valor, "%s %d\n", mensagem, errno);
 
E necessário ter pelo menos um argumento antes dos pontos. Veja um exemplo incorreto.
 
void erreur(...);
 
O arquivo de cabeçalho stdarg.h declara um tipo va_list e define três macros para manipular uma lista de argumentos cuja quantidade e tipos são desconhecidos pela função.
 
va_start, va_arg et va_end (va como variable argument)
 
'''Sintaxe:'''
#include <stdarg.h>
 
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
 
'''Descrição:'''
 
'''va_start:'''
:A macro va_start inicializa ap para uso posterior por va_arg e va_end e deve ser chamada primeiro.
:O parâmetro last é o nome do último parâmetro antes da lista de argumentos variáveis, isto é, o último parâmetro o qual a função conheçe o tipo.
:Porque o endereço deste parâmetro pode ser usado na macro va_start, ele não deve ser declarado como uma variável register, ou como uma função ou como um array.
 
'''va_arg:'''
:A macro va_arg retorna o primeiro argumento variável e faz ap apontar o próximo argumento. O parâmetro ap é aquele inicializado por va_start. O parâmetro type é um nome de tipo. Pode-se apontar para um objeto de um tipo específico simplesmente adicionando um * ao tipo.
:O primeiro uso da macro va_arg após a macro va_start retorna o argumento após last. Chamadas sucessivas retornam os valores dos outros argumentos.
:Se não existe próximo argumento, ou se type não é compatível com o tipo do próximo argumento, erros aleatórios ocorrerão.
:Se ap é passado para uma função que usa va_arg(ap,type) então o valor de ap é destruído após o retorno da função.
 
'''va_end:'''
:Cada chamada de va_start deve ter uma chamada correspondente a va_end na mesma função. Após a chamada de va_end a variável ap é destruída. Várias chamadas com va_start e va_end aninhadas são possíveis. va_end pode ser uma macro ou uma função.<br>
 
'''Exemplo 1'''
<source lang="C">
/* Calcula a soma de n inteiros */
/* o ultimo argumento deve ser 0 */
#include <stdio.h>
#include <stdarg.h>
 
int soma(int n1, ...) {
va_list pa;
int som, n;
som = n1;
va_start(pa, n1);
while( (n = va_arg(pa, int)) != 0)
som = som + n;
va_end(pa);
return som;
}
 
main() {
printf("1 + 3 + 5 + 7 + 9 = %d\n", soma(1,3,5,7,9,0));
printf("1 + 1 = %d\n", soma(1,1,0));
return 0;
}
/*-- resultado ----------------------------
1 + 3 + 5 + 7 + 9 = 25
1 + 1 = 2
---------------------------------------------------------*/
</source>
 
'''Exemplo 2'''
<source lang="C">
#include <stdio.h>
#include <stdarg.h>
 
void meu_printf(char *fmt, ...) {
va_list pa;
int n;
char *s, c;
float f;
va_start(pa, fmt);
while (*fmt != '\0') {
if ( *fmt == '%' ) {
/* (*++fmt) equivale a (*fmt = *fmt + 1 )*/
switch (*++fmt) {
case '%' : putchar('%'); break;
case 'c' : /* char*/
c = va_arg(pa, int);
putchar(c);
break;
case 'd' : /* int */
n = va_arg(pa, int);
printf("%d", n);
break;
case 'f' : /* float */
f = va_arg(pa, double); /* !!!!! */
printf("%f", f);
break;
case 's' : /* string */
s = va_arg(pa, char *);
for ( ; *s != '\0'; s++ )
putchar( *s );
break;
} /* end switch */
}
else
putchar( *fmt );
/*incrementa o ponteiro*/
fmt++;
}
va_end(pa);
}
 
int main() {
meu_printf("float = %f\n", (float) 1.2345);
meu_printf("int = %d char = %c String = %s\n", 123, 'A', "C is beautiful !" );
return 0;
}
</source>