Peczenyj's Blog

Just Another /Perl|Ruby|C++|Java|Python|JavaScript|Flash|Bash/ Hacker

Programando Em C Para Console - Parte 1

(Depois de um fecundo primeiro de Abril… )

Cada vez mais eu me espanto com a quantidade de novatos que tentam fazer programas para o “modo console” que não fazem o menor sentido.

Programas com menuzinho (1 - saque , 2 - deposito, 3 - sair) ou do estilo “digite um numero (q para sair)” são totalmente contra-produtivos. O novato perde TEMPO fazendo um monte de código desnecessário quando esquece o que deveria fazer (o tal do algoritmo).

Veja um exemplo: um programa que receba uma quantidade variavel de números e que imprima a soma dos mesmos. IMHO a forma mais interessante para fazer isso é pegar os números como argumentos do programa principal. Vc cria um programa console absolutamente limpo e facil de scriptar, por exemplo.

Veja só:

#include <stdio.h>

int main(int argc, char *argv[]){
double soma = 0.0;

printf("A soma dos numeros eh %g\n",soma);

return 0;
}


Feito esse simples arquivo, vamos compilar
$ gcc -Wall soma.c
$ ./a.out 1 2 3 4 5
A soma dos numeros eh 0


Ai vc fala “po, ta errado!”, mas claro, eu primeiro escrevi a base do meu programa. Perceba que eu compilei com a opção -Wall, que me informa todos os warnings que a compilação pode gerar (o que sempre é uma excelente pratica, eu procuro compilar sempre com 0 warnings).

Feito isso, vamos definir 2 coisas:
- O algoritmo da soma e
- Possiveis fluxos de excessão.

Vou partir do suposto que, se vc digitar alguma coisa que não seja um numero, eu vou ignorar e considerar como 0. Caso eu não informe nenhum numero ao programa, isso significa que estou faltando com alguma coisa, nesse caso vou informar uma mensagem elucidativa sobre o uso do programa.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
int i;
double soma = 0.0;

if(argc == 1){
fprintf(stderr,"Faltando Argumentos!\n");
fprintf(stderr,"Uso: %s x1 [ x2 .. xN ]\n",argv[0]);
return 1;
}

for(i=1;i<argc;i++)
soma += atof(argv[i]);

printf("A soma dos numeros eh %g\n",soma);

return 0;
}


Todos os argumentos que eu passo para o programa, incluindo o nome do mesmo, ficam no vetor argv, e o número de argumentos fica na variavel arcc. Dessa forma, o nome do programa é o argv[0] e, se eu não passar nenhum argumento adicional, argc será 1. A função atof converte a string para um número de ponto flutuante e retorna 0 se não for possivel converter.

Simples, não? Agora vamos executar:

$ ./a.out          
Faltando Argumentos!
Uso: ./a.out x1 [ x2 .. xN ]
$ echo $?
1
$ ./a.out 1 2 3 4 5
A soma dos numeros eh 15
$ echo $?
0


A mensagem de uso utiliza uma notação no manual de alguns programas do mundo unix: colocar os argumentos opcionais entre colchetes. Eu informo que preciso de pelo menos um argumento. Caso eu entre no fluxo de excessão, o meu main retorna um valor diferente de 0 para o sistema operacional que pode ser capturado pela variavel de ambiente $? (nesse caso estou em um linux utilizando o bash, em outros sistemas mais exotéricos como o Windows eu não imagino como vc poderia capturar essa informação, tampouco imagino se ela seria util).

Perceba que eu posso criar um script extremamente simples para utilizar esse programa, assim como testar o resultado é uma tarefa de um grep (ou diff). Eu poderia juntar um script de teste e um makefile nesse post mas estou esperando um exemplo um pouco mais interessante.

Eu criei um programa sucinto, facil de entender e muito util, sem ter que perguntar para o usuario nada. transformar esse programa num que calcula a média, por exemplo, é uma tarefa de colocar apenas uma linha (na verdade uma subtração e uma divisão) a mais. Espero que os programadores novatos se inspirem nessa forma de pensar e que utilizem os programas básicos do unix como o grep, cat, diff, cp, etc, para seus futuros trabalhos.

Comments

Felipe
Aguardando….

OFF: As mentiras de ontem forma muito engraçadas, a do Java mesmo :-)
Tiago Peczenyj
Felipem, o GDB por si só precisaria de um post exclusivo. Tenho que pensar bem no exemplo para que seja util.

Estou pensando num algoritmo de ordenação com algum errinho, ou algum processo recursivo como calcular fibonacci, etc.
Felipe
Poucos sabem o que é um UNIX. Programam no DOS usando um while(1) para não fechar a tela do DOS, não sabem nem ir no cmd e digitar o nome do programa, eles clicam no executável.

O C é uma linaguagem que os programadores mais comuns não sabem/se interessam. Ler o TCPL sem entender o que é um wc, grep, sort… é IMHO impossível.

Aguardo os posts sobre getopt e GDB(ah sim GDB não está na lista de “promessas”, mas vai ter, vai?)
Tiago Peczenyj
Duas coisas que esqueci de comentar:

1) As mensagens de erro vão para a saida de erro (stderr)

2) A mensagem “A soma dos numeros eh ” é totalmente desnecessária. Inclusive seria mais sucinto se a resposta fosse apenas o valor numérico.

fica para a proxima então: scripts de teste, makefile, getopt (posso querer utilizar uma opção -v [verbose]) e, se der tempo, localização!

Java 1.7 Vai Ter Ponteiros!!!

Sensacional.

Um dos recursos mais uteis do C finalmente conquistou o mundo java: a notação de ponteiros do Kernighan & Ritchie.

public class Example{
public static void main(String [] args){
int *x, y=0;
x = &y;
System.out.println("O valor de x eh " + *x);
}
}


Agora será possivel fazer, em java:

- Passar primitivos por referência.
- Usar malloc, realloc e free.
- Utilizar ponteiros void para converter uma URL em String, ou um Throwable em um List.
- Sem falar que as Strings terão um caracter a mais no fim: o famoso \0 (na verdade a classe String deve desaparecer no Java 1.8, sendo substituida pelo bom e velho array de char)

Parabéns Sun!

Comments

Tiago Peczenyj
É claudemiro, vc deveria observar a data que eu postei essa mensagem :)
Claudemiro
cadê a fonte disso? cara sinto muito mas acho que isso não vai acontecer. e para o tiago stos. C sempre tera ponteiros. os ponteiros são um dos recursos mais importantes da linguagem c.
Tiago Peczenyj
Sinto falta de um eval() no Java.

eval(“variavel” +i + ” = ” + j);
tiago_stos
Estranho observar essas mudanças nas linguagens. Ainda hoje ouvi dizer que na próxima versão do gcc a linguagem C não usará mais ponteiros, isso para fascilitar o aprendizado e aumentar o número de programadores C…
Claudio Rodrigues
Sinto a falta de métodos destrutores.

Novas Tecnologias .Net

A Microsoft resolveu contra-atacar a proposta da SUN com o FSP que, de uma tacada só, 6 novas linguagens no mundo dot NET: vejam exemplos dos novissimos ABAP .Net, ASM .Net, BrainFuck .Net, JCL .Net e VHDL .Net.

Para a parte web, vc poderá utilizar qualquer uma destas linguagens. Todas serão compiladas para CLI pelo ISS. A nova tecnologia permite, inclusive, rodar um .BAT, veja os exemplos abaixo!

<?ABAP
REPORT ZHB00001.
WRITE: 'Hello world'.
?>


<?ASM
SECTION .data

msg db "Hello, world!",0xa ;
len equ $ - msg

SECTION .text
global main

main:
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,len
int 0x80

mov eax,1
mov ebx,0
int 0x80
?>


<?BRAINFUCK
++++++++++[>+++++++>++++++++++>+++<<<-]>++.>+.+++++++
..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.
?>


<?MSDOS
@ECHO OFF
REM Hello World for DOS batch

ECHO Hello World!
?>


<?JCL
//HERIB JOB ,'HERIBERT OTTEN',PRTY=12
//* Hello World for MVS
//HALLO EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSUT2 DD SYSOUT=T
//SYSUT1 DD *
Hello World!
/*
//
?>


<?VHDL
ENTITY helloworld IS
END helloworld;

ARCHITECTURE hw OF helloworld IS

BEGIN

ASSERT FALSE
REPORT "HELLO, WORLD!"
SEVERITY NOTE;

END hw;
?>


Essa microsoft…