-
Notifications
You must be signed in to change notification settings - Fork 1
C Language
A linguagem de programação C foi desenvolvida por Dennis Ritchie na Bell Labs a partir de 1972. Ritchie, motivado pela ideia de uma linguagem adequada para re-implementação do sistema operacional Unix, planejou C como uma extensão da linguagem B, com suporte a tipos nativos e definidos pelo usuário. Considere abaixo um programa mínimo escrito na linguagem em acordo com a norma ISO/IEC 9899 (1999, p. 12).
int main(void)
{
return 0;
}No trecho acima, temos a definição da função que serve como ponto de entrada para o programa, denominada main().
O primeiro palavra do código int antes do nome da função main indica que o valor retornado pela função será armazenado em uma posição de memória associada a um tipo inteiro.
O tipo void em C é usado para explicitar a não necessidade de definição de tipo.
Segundo a norma ISO/IEC 9899 (1999, p. 35), esse tipo compreende um conjunto vazio de valores.
Dessa forma, a palavra void indica na definição da função denominada main, que a função não deve receber parâmetros.
A palavra return indica um ponto de término da função.
No código acima, a função main() termina retornando para quem a chamou o valor 0 (zero) armazenado em uma posiçao de memória do tipo int.
Antes de ser executado, o código acima precisa ser traduzido para a linguagem de máquina da arquitetura a que se propõe a ser executado. Para isso, é necessário o uso de um programa denominado compilador. Como ilustrado abaixo.
flowchart LR
X["code.c\n(fonte)"]
Y["gcc\n(compilador)"]
Z["code\n(programa)"]
X -->|input| Y
Y -->|output| Z
Assumindo que o código C apresentado é o do arquivo code.c, abaixo é apresentado o uso do compilador GCC em um ambiente Linux.
term@alg$ gcc code.c -o codeO uso da opção -o indica o nome do arquivo a ser gerado como programa executável.
Com a utilização do programa hexdump, apresenta-se abaixo o conteúdo dos primeiros 32 bytes dos dois arquivos.
term@alg$ hexdump -C -n 32 code.c
00000000 69 6e 74 20 6d 61 69 6e 28 76 6f 69 64 29 0a 7b |int main(void).{|
00000010 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d |. return 0;.}|
00000020
term@alg$ hexdump -C -n 32 code
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 03 00 3e 00 01 00 00 00 40 10 00 00 00 00 00 00 |..>.....@.......|
00000020
term@alg$Na saída referente ao arquivo code.c, persebe-se o conteúdo na representação ASCII dos bytes apresentados.
Na saída referente ao arquivo code, tem-se a identificação de um cabeçalho ELF (Executable and Linkable Format).
Trata-se de um formato de descrição de arquivos binários (código objeto) utilizado pelo sistema operacional Linux, para o qual o código fonte foi compilado.
Após o processo de tradução do código fonte em código objeto, é possível executar o programa digitando o caminho do arquivo.
Utilizando o diretório especial . do terminal (caminho do diretório corrente), é possível executar o programa com o comando ./code.
term@alg$ ./code
term@alg$Como nosso programa não produz texto para a saída padrão, o programa é executado pelo sistema operacioal, termina com retorno 0 (zero) e o prompt do terminal é disponibilizado ao usuário novamente. Esse processo pode ser ilustrado pelo diagrama a seguir.
flowchart LR
X["Bash\n(terminal)"]
Y["Linux\n(sistema operacional)"]
X -->|"code (binário)"| Y
Y -->|"0 (inteiro)"| X
O terminal aramazena o retorno do programa em uma variável de ambiente denominada $?.
É possível verificar o valor de retorno do último programa executado utilizando o programa echo.
term@alg$ echo $?
0
term@alg$No trecho acima é possível verificar que o valor da variável de ambiente $? é 0 (zero), como esperado.
A linguagem C geralmente possui mais de uma forma realizar desvio de fluxo de execução e laço de repetição.
Aqui, serão descritos o condicional if e o laço while.
Na linguagem C, o valor 0 (zero) é considerado como falso em testes condicionais. Qualquer coisa diferente de 0 (zero) é considerada verdadeira.
flowchart LR
c{c não é 0?}
A --> c
c -->|sim| B
c -->|não| C
B --> D
C --> D
// [A]
if (c)
{
// [B]
}
else
{
// [C]
}
// [D]flowchart LR
c{c não é 0?}
A --> c
c -->|sim| B
c -->|não| C
B --> c
// [A]
while (c)
{
// [B]
}
// [C]-
int: tipo básico de inteiro com sinal (capaz de representar o intervalo [−32767, +32767]). -
float: tipo básico de real com sinal (capaz de representar em módulo o intervalo [1.175494e-38, 3.402823e+38]). -
char: inteiro usado para representação de caracteres (capaz de representar a tabela ASCII).
flowchart TB
subgraph point["struct point"]
c["float x;\nfloat y;"]
end
struct point
{
float x;
float y;
};flowchart TB
subgraph circle["struct circle"]
subgraph point["struct point origin;"]
p["float x;\nfloat y;"]
end
c["float radius;"]
end
struct circle
{
struct point origin;
float radius;
};É possível utilizar o qualificador de tipo * para dizer que uma variável guarda o endereço de uma variável que armazena aquele tipo.
Por exemplo, considere o código abaixo.
int main()
{
int a;
int *p;
a = 42;
p = &a;
printf("%p\n", p);
printf("%d\n", *p);
*p = 21;
printf("%d\n", a);
return 0;
}No arquivo pointer.c acima, é declarada uma variável a do tipo int.
Em seguida, é declarada uma variável p do tipo int *.
A variável p deve armazenar o endereço de uma variável de tipo int.
Após a declaração de p, é armazenado o valor 42 em a e é armazenado em p o endereço da variável a utilizando o operador de endereço &.
Na chamada printf() logo após, é utiliza-se %p para imprimir na saída padrão o valor armazenado em p.
Na chamada printf() seguinte, utiliza-se o operador conteúdo * para recuperar o valor armazenado na posição de memória contida na variável p e imprimi-lo na saída padrão (deve-se notar a utilização de %d dessa vez, uma vez que o conteúdo da posição de memória armazeda em p é do tipo int).
Em seguida, o valor contido na variável a é alterado de forma indireta pela expressão *p = 21;.
Essa instrução faz com que se armazene o valor 21 como conteúdo da posição de memória armazenada em p.
Para verificar a alteração, utiliza-se uma última vez a função printf() para imprimir na saída padrão o valor contido na variável a.
Veja a saída do programa abaixo.
term@alg$ cc -Wall pointer.c -o pointer
term@alg$ ./pointer
0x7ffd24143ea4
42
21ISO/IEC 9899:1999 - Programming languages - C
GCC - the GNU Compiler Collection
ASCII Table
C Data Types