%cabeçalho para todos os capítulos
%\input{cabecalho}

%\begin{document}

%Opções para o pacote listings
%\input{listingOptions}

\chapter{O C que há em Java}

\begin{center}
\shabox{
  \begin{Bitemize}
    \item[]\textbf{Quais novidades veremos nesta aula?}
    \item Veremos como escrever programas na linguagem C \\
          a partir de nossos conhecimentos de Java.
  \end{Bitemize}
} % \shabox
\end{center}
\bigskip

\section{O C que há em Java}

Veremos nessa aula como são os programas na linguagem C e como podemos
escrevê-los usando o que aprendemos em nosso curso de introdução à
computação. Em resumo podemos pensar que um programa em C é uma única
classe Java sem a presença de atributos e composta apenas com métodos
estáticos. Fora isso o resto é perfumaria. Vamos pensar um pouco quais
são as conseqüências da frase acima:

\begin{itemize}
\item Como há apenas uma classe e não há atributos não é possível
      organizar o programa como diversos objetos, eventualmente
      pertencentes a classes diferentes, interagindo.
\item Como não há atributos só existem dois tipos de variáveis: os
      parâmetros e as variáveis locais às funções.
\item Como não há classes e objetos de verdade, todas as variáveis são
      de tipos primitivos: \texttt{int}, \texttt{double} ou \texttt{char}. Pelo menos há
      também a idéia de array, ou vetor, e matrizes em C.
\item Em C não há o tipo \texttt{boolean}. No seu lugar usamos inteiros com o 0
      representando falso e qualquer número não-nulo representando
      verdadeiro. Note que as expressões lógicas passam então a gerar
      valores inteiros como resultados.
\end{itemize}

Esses pontos já são interessantes o suficiente para vermos o que
acontece. Consideremos o primeiro exemplo visto neste livro: o
conversor de temperaturas. Você lembra que ele era um objeto sem
atributos? Vejamos o seu código (adicionamos um \texttt{main} e os
identificadores de acesso):

\begin{lstlisting}
public class Conversor
{
  static double celsiusParaFahrenheit (double c)
  {
    return 9.0 * c / 5.0 + 32.0;
  }
  static double fahrenheitParaCelsius(double f)
  {
    return 5.0 * (f - 32.0) / 9.0;
  }
  public static void main(String[] args)
  {
    double far, cel;

    System.out.print("De um temperatura em Fahrenheint: ");
    far = SavitchIn.readDouble();
    cel = fahrenheitParaCelsius(far);
    System.out.println("A temperatura em Celsius é: " + cel);
    System.out.print("De um temperatura em Celsius: ");
    cel = SavitchIn.readDouble();
    far = celsiusParaFahrenheit(cel);
    System.out.println("A temperatura em Fahrenheit é: " + far);
  }
}
\end{lstlisting}

Vejamos como ficaria esse programa na linguagem C:

%\lstset{alsolanguage=C}

\begin{lstlisting}
/* Sempre coloque a proxima linha no inicio do programa. */
/* Ela permite que você imprima na tela e leia do teclado. */
#include <stdio.h>

/* Como nao ha classes simplemenste apagamos a refencia a ela. */
/* Do mesmo modo, como todos os metodos sao estaticos nao      */
/* precisamos escrever isso.                                   */
/* Por fim nao existem especificadores de acesso em C, logo    */
/* eles tambem sumiram.                                        */

double celsiusParaFahrenheit (double c)
{
  return 9.0 * c / 5.0 + 32.0;
}
double fahrenheitParaCelsius(double f)
{
  return 5.0 * (f - 32.0) / 9.0;
}

/* Veja que a cara da main mudou. Agora ela não recebe nada */
/* e devolve um inteiro.                                    */
int main()
{
  double far, cel;

  /* Oba, imprimir ficou mais facil: o comando e mais curto. */
  printf("De um temperatura em Fahrenheint: ");
  /* A leitura tambem mudou, veja detalhes abaixo. */
  scanf("%lf", &far);
  cel = fahrenheitParaCelsius(far);
  printf("A temperatura em Celsius é: %f\n", cel);
  printf("De um temperatura em Celsius: ");
  scanf("%lf", &cel);
  far = celsiusParaFahrenheit(cel);
  printf("A temperatura em Fahrenheit é: %f\n", far);

  /* Para nos esse retorno nao serve para nada, e um topico avancado. */
  return 0;
}
\end{lstlisting}


\section{Detalhes de entrada e saída}

Além do sumiço das classes, dos indicadores de acesso e dos termos
\texttt{static} (pois todas as funções são assim) dos programas em C, uma outra
mudança bastante visível é que os comandos para escrever na tela e para
leitura do teclado mudam bastante. No lugar do \texttt{System.out.println}
aparece o \texttt{printf} e no lugar dos métodos da classe \texttt{SavitchIn} usamos o
\texttt{scanf}. A forma de usá-los também muda um pouco:

\begin{enumerate}
\item \texttt{printf}: Imprime na tela. O primeiro parâmetro deve ser sempre uma
      string (texto entre aspas). Diferente do que ocorria com Java, não
      podemos usar a soma para concatenar cadeias. Como apresentar então
      variáveis no meio a string que será impressa pelo printf? Usamos
      nesse caso uns marcadores especiais para "deixar espaço" para
      imprimir o valor da variável e em seguida passamos estas variáveis
      como parâmetro. Vejamos um exemplo.

\begin{lstlisting}
printf("Esse e inteiro %d, esse double %f, e o ultimo um char %c",
       umInteiro, umDouble, umChar);
\end{lstlisting}

      Caso desejemos que o \texttt{printf} pula de linha ao final, devemos
      adicionar um $\backslash$\texttt{n} no final da string do \texttt{printf}:

\begin{lstlisting}
printf("Esse e inteiro %d, esse double %f, e o ultimo um char %c\n",
       umInteiro, umDouble, umChar);
\end{lstlisting}

      Vale a pena consultar um manual de C para ver o \texttt{printf} em ação.
      Ele é um comando mais poderoso do que parece.

\item \texttt{scanf}: Para ler valores do teclado usamos o \texttt{scanf}. Ele também
      recebe uma string com marcadores semelhantes do \texttt{printf} (a
      principal diferença é que para ler um double usamos \texttt{\%lf} e não \texttt{\%f}).
      Depois aparecem as variáveis que devem ser lidas antecedidas de um
      \texttt{\&}. Por exemplo se queremos ler um inteiro e um double fazemos:


\begin{lstlisting}
scanf("%d%lf", &umInteiro, &umDouble);
\end{lstlisting}

\end{enumerate}

\section{Declaração de variáveis}

Em C, é comum que a declaração de todas as variáveis seja no início da
função. Isso porém não é obrigatório (já foi, não é mais). Para declarar
vetores em C a sintaxe é mais simples do que em Java. Por exemplo se
queremos que a variável a seja um vetor de 100 inteiros basta:

\begin{lstlisting}
int a[100];
\end{lstlisting}

A mesma coisa para matrizes:

\begin{lstlisting}
int a[100][100];
\end{lstlisting}

\section{Parâmetros de funções}

Assim como em Java, os parâmetros que são tipos primitivos modificados
dentro da função não se refletem fora dela. Já se alterarmos o conteúdo
de um vetor ele se reflete fora. Uma coisa interessante é que é possível
pedir ao C que ele permita que a alteração de parâmetros que são de tipo
primitivo reflita-se fora da função. Para isso deve-se anteceder o
parâmetro de um asterisco em toda a função (inclusive na declaração do
parâmetro). Ao chamar a função, a variável que queremos alterar deve
estar precedida de um \texttt{\&}.

\begin{lstlisting}
 #include <stdio.h>

 /* Troca duas variáveis de lugar*/
 void swap(int *a, int *b)
 {
   int temp;
   temp = *a;
   *a = *b;
   *b = temp;
 }

 int main()
 {
   int c, d;
   c = 1;
   d = 2;
   swap(&c, &d);
   printf("c = %d, d = %d", c, d);
 }
\end{lstlisting}

Outra mudança é que os colchetes de parâmetros que são vetores e
matrizes devem vir após os seus nomes (e não antes como em Java). Além
disso, se o parâmetro é um matriz, você deve informar na declaração da
função qual o número de linhas que a matriz tem. Por exemplo

\begin{lstlisting}
void umaFuncao(int umVetor[], int umaMatriz[100][])
\end{lstlisting}

\section{Um último exemplo}

Vejamos um último exemplo de programa em C. Queremos escrever um
programa que lê uma seqüência de inteiros estritamente positivos
terminada por zero e imprime o número e imprime a sua mediana.

\begin{lstlisting}
#include <stdio.h>

void selecaoDireta(int numeros[], int fim)
{
  int i, j, minimo, temp;
  for (i = 0; i < fim - 1; i = i + 1)
  {
    /* Inicialmente o menor elemento ja visto e o primeiro elemento. */
    minimo = i;
    for (j = i + 1; j < fim; j = j + 1)
    {
      if (numeros[j] < numeros[minimo])
    minimo = j;
    }
    /* Coloca o menor elemento no inicio do sub-vetor atual. */
    temp = numeros[i];
    numeros[i] = numeros[minimo];
    numeros[minimo] = temp;
  }
}

int main()
{
  /* Aceita no maximo 100 numeros no vetor. */
  int numeros[100];
  int i = -1;

  /* Le o vetor. */
  do
  {
    i++;
    scanf("%d", &numeros[i]);
  } while (numeros[i] > 0);

  /* Ordena para encontrar a mediana. */
  selecaoDireta(numeros, i);

  /* Agora ficou fácil. */
  printf("A mediana e: %d\n", numeros[(i-1)/2]);

  /* O tal return inutil. */
  return 0;
}
\end{lstlisting}

%\end{document}
