ANDRÉ BACKES2a
edição
LINGUAGEMCompleta eDescomplicada
Estruturalmente simples e com grande portabilidade, a linguagem C é uma lin-guagem procedural que de-compõe um problema comple-xo em módulos que apresen-tam problemas mais simples e mais fáceis de resolver.
Além disso, fornece acesso de baixo nível à memória, permite a implantação de programas utilizando ins-truções em Assembly e in-centiva a programação mul-tiplataforma.
Dessa forma, é possível ter acesso e programar diretamente o microproces-sador, programar problemas onde a dependência do tempo é crítica e compilar uma grande variedade de plataformas e sistemas operacionais com apenas pequenas alterações no seu código-fonte.
Por isso, a linguagem C se tornou uma das linguagens de programação mais utili-zadas, sendo explorada em sua totalidade neste livro, cujo intuito é separar o conhecimento básico do avançado, abordando tanto o que é usado no dia a dia quanto suas aplicações mais específicas.
Consulte nosso catálogo completo e últimos lançamentos em www.elsevier.com.br
ANDRÉ BACKES possui bacharelado em Informá-tica, e mestrado e dou-torado em Ciências da Computação pela Univer-sidade de São Paulo. Atualmente é professor associado da Universida-de Federal de Uberlân-dia. Tem experiência na área de Ciência da Com-putação, com ênfase em Processamento de Ima-gens, Visão Computacio-nal, Metodologia e Téc-nicas da Computação.
Capa
: Vi
nici
us D
ias
Criada em 1972 nos laboratórios Bell por Dennis Rit-chie, a linguagem C se tornou uma das mais bem-suce-didas linguagens de alto nível já criadas, sendo considerada até hoje, na maioria dos cursos de com-putação do país, a linguagem básica para o aprendi-zado de disciplinas introdutórias em programação. Com um teor de abstração relativamente elevado, ela está mais próxima da linguagem humana do que o código de máquina. Ainda assim, é considerada por muitos uma linguagem de difícil aprendizado.
Com o objetivo de simplificar o ensino da discipli-na, André Backes apresenta neste livro uma nova abordagem que descomplica os conceitos da linguagem por meio de diversos recursos didáticos e ilustrati-vos, incluindo lembretes e avisos que ressaltam os seus pontos-chave, além de exemplos simples e claros sobre como utilizá-la.
Este livro traz um programa de um curso completo de linguagem C, tratando com simplicidade dos assuntos mais complicados até os mais básicos. Também são abordadas, separadamente, as novidades incluídas na linguagem com o passar dos anos.
Livro-texto para estudantes de graduação e pós-gra-duação em Computação, também pode ser utilizado por profissionais que trabalham com programação e pro-fissionais de áreas não computacionais (biólogos e engenheiros, entre outros) que precisam utilizar o programa em alguma tarefa.
ANDRÉ BACKESLINGUAGEM
LINGUAGEM C: COMPLETA E DESCOMPLICADA
C0090.indd iC0090.indd i 11/10/18 4:46 PM11/10/18 4:46 PM
C0090.indd iiC0090.indd ii 11/10/18 4:46 PM11/10/18 4:46 PM
LINGUAGEM C: COMPLETA E DESCOMPLICADA
2 a edição
André Backes
C0090.indd iiiC0090.indd iii 11/10/18 4:46 PM11/10/18 4:46 PM
CIP-BRASIL. CATALOGAÇÃO NA PUBLICAÇÃOSINDICATO NACIONAL DOS EDITORES DE LIVROS, RJ
B119L2. ed.
Backes, André Linguagem C : completa e descomplicada / André Backes. - 2. ed. - Rio de Janeiro: Elsevier, 2019. : il.
Apêndice Inclui bibliografia ISBN 978-85-352-9106-3
1. C (Linguagem de programação de computador). I. Título.18-52029 CDD: 005.13 CDU: 004.43
© 2019, Elsevier Editora Ltda. Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998.
Nenhuma parte deste livro, sem autorização prévia por escrito da editora, poderá ser reproduzida ou transmitida sejam quais forem os meios empregados: eletrônicos, mecânicos, fotográficos, gravação ou quaisquer outros.
ISBN: 978-85-352-9106-3 ISBN (versão digital): 978-85-352-9107-0
Copidesque: Vania Santiago Revisão tipográfica: Augusto Coutinho Editoração Eletrônica: Thomson Digital
Elsevier Editora Ltda. Conhecimento sem Fronteiras
Rua da Assembléia, n° 100 – 6° andar 20011-904 – Centro – Rio de Janeiro – RJ
Av. Nações Unidas, n° 12995 – 10° andar 04571-170 – Brooklin – São Paulo – SP
Serviço de Atendimento ao Cliente 0800 026 53 40 [email protected]
Consulte nosso catálogo completo, os últimos lançamentos e os serviços exclusivos no site www.elsevier.com.br
NOTA Muito zelo e técnica foram empregados na edição desta obra. No entanto, podem ocorrer erros de digitação, impressão ou dúvida conceitual. Em qualquer das hipóteses, solicitamos a comunicação ao nosso serviço de Atendimento ao Cliente para que possamos esclarecer ou encaminhar a questão. Para todos os efeitos legais, a Editora, os autores, os editores ou colaboradores relacionados a esta obra não assumem responsabilidade por qualquer dano/ou prejuízo causado a pessoas ou propriedades envolvendo responsabilidade pelo produto, negligência ou outros, ou advindos de qualquer uso ou aplicação de quaisquer métodos, produtos, instruções ou ideias contidos no conteúdo aqui publicado.
A Editora
C0095.indd ivC0095.indd iv 10/10/18 6:41 PM10/10/18 6:41 PM
À minha esposa, Bianca, que sempre me apoiou e incentivou a cada novo passo. E ao meu filho, Pedro, que me ensinou o verdadeiro significado de ensinar.
C0100.indd vC0100.indd v 10/10/18 6:53 PM10/10/18 6:53 PM
C0100.indd viC0100.indd vi 10/10/18 6:53 PM10/10/18 6:53 PM
Agradecimentos
A os amigos que fiz no convívio diário da Faculdade de Computação da Universidade Federal de Uberlândia (FACOM-UFU).
Aos meus pais, que sempre me apoiaram em todas as etapas da minha vida.
Ao Prof. Dr. Odemir Martinez Bruno, pela confiança depositada em mim, orientação e amizade, sem as quais eu não teria me tornado professor.
Aos meus alunos, que atuaram como guias. Foi pensando em ajudá-los que me arrisquei a produzir esta obra.
C0105.indd viiC0105.indd vii 10/10/18 6:56 PM10/10/18 6:56 PM
C0105.indd viiiC0105.indd viii 10/10/18 6:56 PM10/10/18 6:56 PM
Sumário
Agradecimentos vii
C A P Í T U L O 1
INTRODUÇÃO 1
1.1 A linguagem C 2
1.1.1 Influência da linguagem C 2
1.2 Utilizando o Code::Blocks para programar em C 4
1.2.1 Criando um novo projeto no Code::Blocks 4
1.2.2 Utilizando o debugger do Code::Blocks 8
1.3 Esqueleto de um programa em linguagem C 12
1.3.1 Indentação do código 13
1.4 A compilação do programa 14
1.5 Comentários 15
1.6 Usando uma biblioteca: o comando #include 15
1.6.1 Criando suas próprias bibliotecas 16
1.7 Bibliotecas e funções úteis da linguagem C 19
1.7.1 Funções de entrada e saída: stdio.h 19
Operações em arquivos 19
Acesso a arquivos 19
Entrada/saída formatada 19
Entrada/saída de caracteres 19
Entrada/saída direta 19
Posicionamento no arquivo 19
Tratamento de erros 20
Tipos e macros 20
1.7.2 Funções de utilidade padrão: stdlib.h 20
Conversão de strings 20
Geração de sequências pseudoaleatórias 20
Gerenciamento de memória dinâmica 20
Ambiente do programa 20
Pesquisa e ordenação 20
Aritmética de inteiro 21
C0110.indd ixC0110.indd ix 11/10/18 4:42 PM11/10/18 4:42 PM
x L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
1.7.3 Funções matemáticas: math.h 21
Funções trigonométricas 21
Funções hiperbólicas 21
Funções exponenciais e logarítmicas 21
Constantes 21
Funções de potência 21
Funções de arredondamento, valor absoluto e outras 22
1.7.4 Testes de tipos de caracteres: ctype.h 22
1.7.5 Operações em string: string.h 22
Cópia 22
Concatenação 22
Comparação 22
Busca 22
Outras 23
1.7.6 Funções de data e hora: time.h 23
Manipulação do tempo 23
Conversão 23
Tipos e macros 23
Usando a função strftime() 24
C A P Í T U L O 2
LENDO E ESCREVENDO NAS VARIÁVEIS 27
2.1 Variáveis 27
2.1.1 Declarando uma variável 28
2.1.2 Dando um nome à nossa variável 29
2.1.3 Definindo o tipo da nossa variável 30
O tipo char 31
O tipo int 31
Os tipos float e double 32
O tipo void 33
2.1.4 Os modificadores de tipo de uma variável 33
O modificador signed 33
O modificador unsigned 33
O modificador short 33
O modificador long 33
Tipos e combinações de modificadores possíveis 34
2.2 Escrevendo suas variáveis na tela 34
2.2.1 Printf 34
Escrevendo uma mensagem de texto 35
Escrevendo valores formatados 35
2.2.2 Putchar 37
2.3 Lendo suas variáveis do teclado 38
2.3.1 Scanf 38
2.3.2 Getchar 40
C0110.indd xC0110.indd x 11/10/18 4:42 PM11/10/18 4:42 PM
Sumário xi
2.4 Escopo: o tempo de vida da variável 41
2.4.1 O escopo global 41
2.4.2 O escopo local 42
2.5 Constantes 44
2.5.1 Valor literal 45
2.5.2 O comando #define 45
2.5.3 O comando const 46
2.5.4 As sequências de escape 46
2.6 Exercícios 47
C A P Í T U L O 3
AS OPERAÇÕES QUE PODEMOS FAZER COM AS VARIÁVEIS 49
3.1 O operador de atribuição “ = ” 49
3.2 Operadores aritméticos 52
3.3 Operadores relacionais 54
3.4 Operadores lógicos 55
3.5 Operadores bit a bit 57
3.6 Operadores de atribuição simplificada 59
3.7 Operadores de pré e pós-incremento/decremento 61
3.8 Modeladores de tipos (casts) 63
3.9 Operador vírgula (,) 64
3.10 Precedência de operadores 64
3.11 Exercícios 65
C A P Í T U L O 4
COMANDOS DE CONTROLE CONDICIONAL 69
4.1 Definindo uma condição 70
4.2 Comando if 71
4.2.1 Uso das chaves { } 73
4.3 Comando else 73
4.4 Aninhamento de if 77
4.5 Operador ? 79
4.6 Comando switch 81
4.6.1 Uso do comando break no switch 83
4.6.2 Uso das chaves { } no case 85
4.7 Exercícios 86
C A P Í T U L O 5
COMANDOS DE REPETIÇÃO 89
5.1 Repetição por condição 89
5.1.1 Laço infinito 91
C0110.indd xiC0110.indd xi 11/10/18 4:42 PM11/10/18 4:42 PM
xii L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
5.2 Comando while 92
5.3 Comando for 94
5.3.1 Omitindo uma cláusula do comando for 96
Comando for sem inicialização 96
Comando for sem condição 96
Comando for sem incremento 97
5.3.2 Usando o operador de vírgula (,) no comando for 98
5.4 Comando do-while 99
5.5 Aninhamento de repetições 102
5.6 Comando break 103
5.7 Comando continue 104
5.8 Goto e label 106
5.9 Exercícios 107
C A P Í T U L O 6
VETORES E MATRIZES ARRAYS 111
6.1 Por que utilizar 111
6.2 Array com uma dimensão – vetor 113
6.2.1 Declarando um vetor 113
6.2.2 Acessando um elemento do vetor 114
6.3 Array com duas dimensões – matriz 117
6.3.1 Declarando uma matriz 117
6.3.2 Acessando um elemento da matriz 117
6.4 Array com mais de duas dimensões 119
6.5 Inicialização de arrays 120
6.5.1 Inicialização sem tamanho 124
6.6 Exemplos de uso de arrays 125
6.6.1 Somando os elementos de um vetor 125
6.6.2 Encontrando o maior valor de um vetor 126
6.6.3 Calculando a média dos elementos de um vetor 126
6.6.4 Somando os elementos de uma matriz 127
6.7 Exercícios 128
6.7.1 Vetores 128
6.7.2 Matrizes 129
C A P Í T U L O 7
ARRAYS DE CARACTERES STRINGS 131
7.1 Definição e declaração de uma string 131
7.1.1 Inicializando uma string 132
7.1.2 Acessando um elemento da string 132
C0110.indd xiiC0110.indd xii 11/10/18 4:42 PM11/10/18 4:42 PM
Sumário xiii
7.2 Trabalhando com strings 133
7.2.1 Lendo uma string do teclado 134
Usando a função scanf() 134
Usando a função gets() 134
Usando a função fgets() 134
Limpando o buffer do teclado 136
7.2.2 Escrevendo uma string na tela 136
Usando a função printf() 136
Usando a função fputs() 136
7.3 Funções para manipulação de strings 137
7.3.1 Tamanho de uma string 137
7.3.2 Copiando uma string 137
7.3.3 Concatenando strings 138
7.3.4 Comparando duas strings 139
7.4 Exercícios 139
C A P Í T U L O 8
TIPOS DEFINIDOS PELO PROGRAMADOR 141
8.1 Estruturas: struct 141
8.1.1 Declarando uma estrutura 142
8.1.2 Declarando uma variável do tipo da estrutura 143
8.1.3 Acessando os campos de uma estrutura 144
8.1.4 Inicialização de estruturas 145
8.1.5 Array de estruturas 146
8.1.6 Atribuição entre estruturas 147
8.1.7 Estruturas aninhadas 148
8.2 Uniões: union 149
8.2.1 Declarando uma união 150
8.2.2 Diferença entre estrutura e união 150
8.3 Enumerações: enum 152
8.3.1 Declarando uma enumeração 152
8.3.2 Declarando uma variável do tipo da enumeração 153
8.3.3 Enumerações e constantes 153
8.4 Comando typedef 155
8.5 Exercícios 157
C A P Í T U L O 9
FUNÇÕES 159
9.1 Definição e estrutura básica 159
9.1.1 Declarando uma função 160
Local de declaração de uma função 160
Funcionamento de uma função 161
C0110.indd xiiiC0110.indd xiii 11/10/18 4:42 PM11/10/18 4:42 PM
xiv L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
9.1.2 Parâmetros de uma função 162
Declarando os parâmetros de uma função 162
Funções sem lista de parâmetros 163
9.1.3 Corpo da função 164
9.1.4 Retorno da função 166
Funções sem retorno de valor 167
Funções com retorno de valor 167
9.2 Tipos de passagem de parâmetros 171
9.2.1 Passagem por valor 171
9.2.2 Passagem por referência 172
9.2.3 Passagem de arrays como parâmetros 174
9.2.4 Passagem de estruturas como parâmetros 178
Passagem de uma estrutura por valor 178
Passagem de um campo da estrutura por valor 178
Passagem de um campo da estrutura por referência 179
Passagem de uma estrutura por referência 179
9.2.5 Operador seta 181
9.3 Recursão 182
9.3.1 Solução recursiva 182
9.3.2 Como funciona a recursividade 184
9.3.3 Cuidados na implementação da recursividade 187
9.4 Exercícios 190
9.4.1 Passagem por valor 190
9.4.2 Passagem por referência 192
9.4.3 Recursão 193
C A P Í T U L O 10
PONTEIROS 195
10.1 Definição 195
10.2 Declaração 196
10.3 Manipulando ponteiros 197
10.3.1 Inicialização e atribuição 197
Apontando um ponteiro para nenhum lugar 198
Apontando um ponteiro para algum lugar da memória 198
Os operadores “*” e “&” 200
Atribuição entre ponteiros 200
10.3.2 Aritmética com ponteiros 202
10.3.3 Operações relacionais com ponteiros 203
10.4 Ponteiros genéricos 204
10.5 Ponteiros e arrays 206
10.5.1 Ponteiros e arrays multidimensionais 208
10.5.2 Array de ponteiros 209
10.6 Ponteiro para ponteiro 210
10.7 Exercícios 212
C0110.indd xivC0110.indd xiv 11/10/18 4:42 PM11/10/18 4:42 PM
Sumário xv
C A P Í T U L O 11
ALOCAÇÃO DINÂMICA 215
11.1 Definição 215
11.2 Funções para alocação de memória 217
11.2.1 sizeof() 217
11.2.2 malloc() 218
11.2.3 calloc() 220
11.2.4 realloc() 221
11.2.5 free() 224
11.3 Alocação de arrays multidimensionais 225
11.3.1 Solução 1: Usando array unidimensional 226
11.3.2 Solução 2: Usando ponteiro para ponteiro 227
11.3.3 Solução 3: Ponteiro para ponteiro para array 230
11.4 Exercícios 232
C A P Í T U L O 12
ARQUIVOS 235
12.1 Definição 235
12.2 Tipos de arquivos 236
12.3 Sobre escrita e leitura em arquivos 237
12.4 Ponteiro para arquivo 238
12.5 Abrindo e fechando um arquivo 238
12.5.1 Abrindo um arquivo 238
Caminho absoluto e relativo para o arquivo 238
Como posso abrir meu arquivo 239
Finalizando o programa no caso de erro 241
12.5.2 Fechando um arquivo 241
12.6 Escrita e leitura em arquivos 242
12.6.1 Escrita e leitura de caractere 242
Escrevendo um caractere 242
Lendo um caractere 243
12.6.2 Fim do arquivo e a função feof() 245
12.6.3 Arquivos predefinidos 247
12.6.4 Forçando a escrita dos dados do buffer 247
12.6.5 Sabendo a posição atual dentro do arquivo 248
12.6.6 Escrita e leitura de strings 249
Escrevendo uma string 249
Lendo uma string 251
12.6.7 Escrita e leitura de blocos de bytes 252
Escrevendo blocos de bytes 252
Lendo blocos de bytes 254
12.6.8 Escrita e leitura de dados formatados 257
Escrevendo dados formatados 258
Lendo dados formatados 259
C0110.indd xvC0110.indd xv 11/10/18 4:42 PM11/10/18 4:42 PM
xvi L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
12.7 Movendo-se dentro do arquivo 261
12.7.1 Voltando ao começo do arquivo 262
12.8 Excluindo um arquivo 263
12.9 Erro ao acessar um arquivo 263
12.10 Exercícios 264
C A P Í T U L O 13
AVANÇADO 267
13.1 Recursos avançados da função printf() 267
13.1.1 Os tipos de saída 268
Exibindo os tipos básicos 269
Exibindo valores no formato octal ou hexadecimal 269
Exibindo valores como notação científica 270
Exibindo valores inteiros “sem sinal” e endereços 270
Exibindo o símbolo de “%” 271
13.1.2 As “flags” para os tipos de saída 271
Justificando um valor à esquerda 272
Forçar a impressão do sinal do número 272
Imprimindo “espaços” ou zeros antes de um número 272
Imprimindo o prefixo hexadecimal e octal e o ponto 273
13.1.3 O campo “largura” dos tipos de saída 273
13.1.4 O campo “precisão” dos tipos de saída 274
O campo precisão para valores inteiros 274
O campo precisão para valores reais 275
O campo precisão usado com strings 275
O campo precisão definido por uma variável inteira 276
13.1.5 O campo comprimento dos tipos de saída 276
13.1.6 Usando mais de uma linha na função printf() 276
13.1.7 Imprimindo constantes de caracteres com printf() 277
13.2 Recursos avançados da função scanf() 277
13.2.1 Os tipos de entrada 278
Lendo os tipos básicos 279
Lendo valores no formato octal ou hexadecimal 280
Lendo valores como notação científica 280
Lendo uma string do teclado 281
13.2.2 O campo asterisco “*” 281
13.2.3 O campo largura dos tipos de entrada 282
13.2.4 Os modificadores dos tipos de entrada 283
13.2.5 Lendo e descartando caracteres 283
13.2.6 Lendo apenas caracteres predeterminados 284
Usando um intervalo de caracteres predeterminados 285
Invertendo um scanset 285
C0110.indd xviC0110.indd xvi 11/10/18 4:42 PM11/10/18 4:42 PM
Sumário xvii
13.3 Mudando a localidade do computador 286
13.4 Trabalhando com caractere amplo (wide char) 287
13.5 Classes de armazenamento de variáveis 288
13.5.1 A classe auto 289
13.5.2 A classe extern 289
13.5.3 A classe static 290
13.5.4 A classe register 291
13.6 O modificador de tipo volatile 292
13.7 Trabalhando com campos de bits 293
13.8 Funções com número de parâmetros variável 295
13.9 Argumentos na linha de comando 298
13.10 Trabalhando com ponteiros 300
13.10.1 Array de ponteiros e ponteiro para array 300
13.10.2 Ponteiro para função 301
Declarando um ponteiro para uma função 301
Apontando um ponteiro para uma função 302
Passando um ponteiro para função como parâmetro 303
Criando um array de ponteiros para função 304
13.11 Diretivas de compilação 305
13.11.1 O comando #include 306
13.11.2 Definindo macros: #define e #undef 306
Definindo símbolos com #define 306
Definindo constantes com #define 307
Definindo funções macros com #define 307
Funções macro com mais de uma linha 309
Operadores especiais: # e ## 309
Apagando uma definição: #undef 310
13.11.3 Diretivas de inclusão condicional 310
Diretivas #ifdef e #ifndef 310
Diretivas #if, #else e #elif 311
13.11.4 Controle de linha: #line 313
13.11.5 Diretiva de erro: #error 313
13.11.6 A diretiva #pragma 314
13.11.7 Diretivas predefinidas 314
13.11.8 Limites dos tipos básicos 315
13.12 Alinhamento e preenchimento 316
13.12.1 Alinhamento e preenchimento de estruturas 317
13.12.2 Alinhamento e preenchimento de estruturas com campo de bits 319
13.12.3 Reorganizando a estrutura 321
13.12.4 Substituindo regras de alinhamento 322
C A P Í T U L O 14
O PADRÃO C99 323
14.1 Habilitando o padrão C99 no Code::Blocks 323
14.2 Detectando a versão do compilador 325
C0110.indd xviiC0110.indd xvii 11/10/18 4:42 PM11/10/18 4:42 PM
xviii L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
14.3 Variáveis, identificadores e operadores 325
14.3.1 O especificador %n da função printf() 325
14.3.2 Declarações de variáveis 326
14.3.3 Novos tipos de dados 326
Novos tipos inteiros 326
O tipo long long int 330
O tipo booleano 331
O tipo complexo 331
14.3.4 O identificador __func__ 333
14.3.5 Valores inteiros em binário 333
14.3.6 Valores de ponto flutuante em hexadecimal 333
14.3.7 Suporte a ponto flutuante padrão IEEE 754 334
14.3.8 O operador _Pragma 336
14.4 Novas bibliotecas e funções 337
14.4.1 Funções matemáticas de tipo genérico 337
14.4.2 Novos especificadores para a função strftime() 338
14.4.3 Funções de gerenciamento de ponto flutuante 339
14.4.3.1 Tipos para manipular um ambiente de ponto flutuante 339
14.4.3.2 Definindo um ambiente de ponto flutuante 339
14.4.3.3 Salvando um ambiente de ponto flutuante 340
14.4.3.4 Salvando um ambiente de ponto flutuante e limpando suas flags 340
14.4.3.5 Restaurando um ambiente de ponto-flutuante e suas flags 340
14.4.3.6 Macros usadas para tratamento de exceções 340
14.4.3.7 Limpando um conjunto de exceções 341
14.4.3.8 Verificando qual exceção ocorreu 341
14.4.3.9 Ativando uma flag de exceção 341
14.4.3.10 Usando uma variável para definir o estado das flags de exceção 342
14.4.3.11 Salvando o estado das flags de exceção em uma variável 342
14.4.3.12 Definindo a direção do arredondamento 342
14.4.3.13 Verificando qual a direção do arredondamento 343
14.5 Novidades no uso de arrays 343
14.5.1 O uso dos colchetes do array 343
14.5.2 Arrays de comprimento variável 344
14.5.3 Arrays de comprimento variável e funções 345
14.5.4 Qualificadores de arrays 346
14.5.5 Campo array flexível dentro de estruturas 347
14.6 Funções e funções macro 348
14.6.1 Funções em linha 348
14.6.2 A macro va_copy() 349
14.6.3 Macros com número de parâmetros variável 350
14.7 A palavra-chave restrict 352
14.8 Inicialização designada 352
14.8.1 Inicializando algumas posições de um array 352
14.8.2 Inicializando alguns dos campos de uma estrutura 353
14.8.3 Inicializando um array de estrutura 354
14.9 Literais compostos 355
C0110.indd xviiiC0110.indd xviii 11/10/18 4:42 PM11/10/18 4:42 PM
Sumário xix
C A P Í T U L O 15
O PADRÃO C11 357
15.1 Novas macros, especificadores e identificadores 357
15.1.1 Macros para ponto flutuante 357
15.1.2 Macros para ponto flutuante 359
15.1.3 Novo modo de abertura de arquivos 360
15.1.4 O especificador _Noreturn para funções 360
15.1.5 Especificando o alinhamento das variáveis na memória 361
15.2 Asserção estática 363
15.3 Melhoria do suporte unicode 365
15.4 Estruturas e uniões anônimas 366
15.5 Funções com verificação de limites 368
15.5.1 Leitura segura de strings com gets_s() 369
15.6 Seleção de tipo genérico 370
15.6.1 O comando _Generic 370
15.6.2 Criando funções de tipo genérico usando _Generic 371
15.7 Suporte multithreading 373
15.7.1 Trabalhando com threads 374
O tipo thread 375
Criando uma thread 375
Comparando duas threads 376
Obtendo o identificador da thread atual 376
Suspendendo temporariamente a thread 377
Interrompendo a thread 377
Terminando a thread 378
Unindo a execução das threads 378
Separando a execução das threads 378
15.7.2 Executando uma função uma única vez 378
15.7.3 Trabalhando com mutex (exclusão mútua) 379
O tipo mutex 380
Criando um mutex 380
Destruindo um mutex 381
Bloqueando a thread até obter o mutex 381
Liberando o mutex 382
Bloqueando a thread por um tempo específico 383
Tentando obter o mutex 383
15.7.4 Trabalhando com variáveis de condição 383
O tipo variável de condição 384
Criando uma variável de condição 384
Destruindo uma variável de condição 385
Desbloqueando uma thread 385
Desbloqueando todas as threads 385
Liberando o mutex e bloqueando a thread 386
Liberando o mutex e bloqueando a thread por um tempo específico 387
C0110.indd xixC0110.indd xix 11/10/18 4:42 PM11/10/18 4:42 PM
xx L I N G UAG E M C CO M P L E TA E D E S CO M P L I C A D A
15.7.5 Objetos locais e armazenamento específico da thread 388
A classe de armazenamento _Thread_local 388
O tipo para armazenamento específico da thread 388
Criando um armazenamento específico para a thread 388
Liberando o armazenamento específico da thread 389
Definindo o bloco de memória do armazenamento específico 390
Acessando o armazenamento específico 391
15.7.6 A função quick_exit() 391
15.8 Suporte a objetos atômicos 392
15.8.1 Declarando um objeto atômico 393
15.8.2 Verificando se um objeto atômico é lock-free (livre de bloqueio) 395
15.8.3 Definindo a ordem de acesso à memória 396
15.8.4 Estabelecendo barreiras de acesso a memória 398
15.8.5 Eliminando as dependências de acesso à memória 399
15.8.6 Protegendo o acesso com uma flag atômica 399
15.8.7 Inicializando, lendo e escrevendo em um objeto atômico 401
15.8.8 Comparando e trocando o valor de um objeto atômico 403
15.8.9 Comparando e trocando o valor de um objeto atômico 405
APÊNDICE 407
16.1 Sistemas numéricos 407
16.1.1 Conversão de binário para decimal 408
16.1.2 Conversão de decimal para binário 408
16.1.3 Conversão de hexadecimal para decimal 409
16.1.4 Conversão de decimal para hexadecimal 409
16.1.5 Conversão entre sistemas: hexadecimal e binário 410
16.1.6 Conversão de octal para decimal 411
16.1.7 Conversão de decimal para octal 411
16.2 Tabela ASCII 412
Referências 417
índice 419
C0110.indd xxC0110.indd xx 11/10/18 4:42 PM11/10/18 4:42 PM
ANDRÉ BACKES2a
edição
LINGUAGEMCompleta eDescomplicada
Estruturalmente simples e com grande portabilidade, a linguagem C é uma lin-guagem procedural que de-compõe um problema comple-xo em módulos que apresen-tam problemas mais simples e mais fáceis de resolver.
Além disso, fornece acesso de baixo nível à memória, permite a implantação de programas utilizando ins-truções em Assembly e in-centiva a programação mul-tiplataforma.
Dessa forma, é possível ter acesso e programar diretamente o microproces-sador, programar problemas onde a dependência do tempo é crítica e compilar uma grande variedade de plataformas e sistemas operacionais com apenas pequenas alterações no seu código-fonte.
Por isso, a linguagem C se tornou uma das linguagens de programação mais utili-zadas, sendo explorada em sua totalidade neste livro, cujo intuito é separar o conhecimento básico do avançado, abordando tanto o que é usado no dia a dia quanto suas aplicações mais específicas.
Consulte nosso catálogo completo e últimos lançamentos em www.elsevier.com.br
ANDRÉ BACKES possui bacharelado em Informá-tica, e mestrado e dou-torado em Ciências da Computação pela Univer-sidade de São Paulo. Atualmente é professor associado da Universida-de Federal de Uberlân-dia. Tem experiência na área de Ciência da Com-putação, com ênfase em Processamento de Ima-gens, Visão Computacio-nal, Metodologia e Téc-nicas da Computação.
Capa
: Vi
nici
us D
ias
Criada em 1972 nos laboratórios Bell por Dennis Rit-chie, a linguagem C se tornou uma das mais bem-suce-didas linguagens de alto nível já criadas, sendo considerada até hoje, na maioria dos cursos de com-putação do país, a linguagem básica para o aprendi-zado de disciplinas introdutórias em programação. Com um teor de abstração relativamente elevado, ela está mais próxima da linguagem humana do que o código de máquina. Ainda assim, é considerada por muitos uma linguagem de difícil aprendizado.
Com o objetivo de simplificar o ensino da discipli-na, André Backes apresenta neste livro uma nova abordagem que descomplica os conceitos da linguagem por meio de diversos recursos didáticos e ilustrati-vos, incluindo lembretes e avisos que ressaltam os seus pontos-chave, além de exemplos simples e claros sobre como utilizá-la.
Este livro traz um programa de um curso completo de linguagem C, tratando com simplicidade dos assuntos mais complicados até os mais básicos. Também são abordadas, separadamente, as novidades incluídas na linguagem com o passar dos anos.
Livro-texto para estudantes de graduação e pós-gra-duação em Computação, também pode ser utilizado por profissionais que trabalham com programação e pro-fissionais de áreas não computacionais (biólogos e engenheiros, entre outros) que precisam utilizar o programa em alguma tarefa.
ANDRÉ BACKESLINGUAGEM