Introdução

Introdução

Continuaremos nesta parte do nosso tutorial com os tipos de dados complexos em C, e falaremos sobre estruturas. Muitas linguagens de programação modernas oferecem uma forma ou outra, e C também. Como você verá mais adiante, as estruturas permitem manipular os dados com mais facilidade, permitindo que você armazene diferentes variáveis ​​de (possivelmente) tipos diferentes sob um único "telhado".

Estruturas iniciais

Embora eu quisesse adiar a parte da definição para este sub-capítulo, parece que eu mal podia esperar e incluí-lo na introdução. Sim, pessoal, é isso que é uma estrutura, e você verá por um capricho como é útil quando mostrarei alguns exemplos. Um paralelo interessante é o que se refere a uma tabela de banco de dados: se você tiver uma tabela chamada usuários (o nome exclusivo), colocará nessa tabela os dados exatos que referem -se diretamente aos usuários: idade, gênero, nome, endereço, e assim por diante. Mas esses são tipos diferentes! Não tem problema, você pode fazer isso com uma tabela, assim como pode fazê -lo com uma estrutura: a idade será um número inteiro, o gênero será um char, o nome será uma corda e assim por diante. Então você poderá acessar o membros da tabela facilmente, referindo -se ao nome da tabela/membro. Mas este não é um curso de banco de dados, então vamos seguir em frente. Mas antes disso, vamos dar uma breve olhada em um aspecto lógico: você é convidado a criar estruturas com membros que têm algo em comum do ponto de vista lógico, como o exemplo acima. Facilite para você e as pessoas que mais tarde analisam seu código. Então, vamos ver como a tabela de banco de dados de nossos usuários se traduziria em uma estrutura C:

estrutura usuários int Age; char gênero; nome do personagem; Endereço de char *; ; 

Por favor, não se esqueça do semicolon no final. Ok, então eu me gabava de que os membros da estrutura são simples de acessar. Veja como, desde que você queira acessar a idade do usuário:

printf ("A idade do usuário é %D.\ n ", usuários.idade); 

Mas para que o printf funcione, teremos que definir a idade primeiro. Isso pode ser feito assim

estrutura usuários int age;… usrs; usrs.idade = 25;… 

O que fizemos aqui é declarar um instância da estrutura (você pode ter tantos casos quanto quiser), chamado "usrs". Você pode ter USRS1, USRS2, USRS3 e assim por diante, para que você possa usar esses atributos (como idade, sexo, endereço) em todos eles. A segunda maneira de fazer isso é declarar a estrutura como fizemos a primeira vez (e.g. sem instâncias) e depois declare as respectivas instâncias posteriormente no código:

.. estrutura usuários usrs1, usrs2, usrs3; 

… E então cuide da idade, sexo, endereço e assim por diante, como fizemos acima.

Quando falamos sobre estruturas em conjunto com as funções, a coisa mais importante a se falar é provavelmente o fato de que as estruturas são consideradas como um todo, não como um composto feito de vários elementos. Aqui está um exemplo:

void show_age (usrs i) printf ("idade do usuário é %d.\ n ", eu.idade); printf ("o nome do usuário é %s.\ n ", (& i)-> nome); 

O que essa função faz é: é preciso um argumento numérico e imprime todos os usuários que têm essa idade específica. Você deve ter notado um novo operador no código acima (se não o fizer, olhe novamente). O operador "->" faz exatamente o que o operador de DOT faz, permitindo acessar um membro da estrutura, com a especificação de que é usada quando os ponteiros estão envolvidos, assim como o operador de pontos é usado nos casos em que os ponteiros não estão envolvidos. Mais uma consideração importante aqui. Dado o seguinte código:

estrutura myStruct int myint; char *mystring;  *p; 

O que você acha que a seguinte expressão fará?

++p-> myint; 

Tópicos avançados

Uma das coisas que você verá com bastante frequência em relação às estruturas, mas não apenas, é o typedef palavra -chave. Como o nome indica, ele permite definir tipos de dados personalizados, como nos exemplos abaixo:

typedef comprimento int; / * Agora, o comprimento é sinônimo de int */ typedef char * string; 

Em relação às estruturas, typedef elimina basicamente a necessidade de usar a palavra 's'. Então, aqui está uma estrutura declarada dessa maneira:

typedef estrutura colegas int Age; char gênero;… colls; 

Para o nosso próximo tópico, teremos uma ideia encontrada em K&R e usá -la para ilustrar nosso ponto. Por que? É bem pensado e mostra muito bem e de uma maneira simples o que estamos prestes a ilustrar. Mas antes de começarmos, aqui está uma pergunta para você: saber que C permite estruturas aninhadas, você acha que estruturas aninhadas por meio de typedef podem ser aceitas? Por que?

Então, aqui está o próximo tópico: matrizes de estrutura. Agora que você sabe o que são matrizes, você pode facilmente adivinhar o que se trata. No entanto, algumas perguntas permanecem: como implementar o conceito e, mais importante, qual poderia ser o uso? O exemplo de que conversamos em breve lançará alguma luz sobre os dois assuntos. Vamos presumir que você tem um programa, escrito em C, e deseja contar o número de ocorrências de todas as palavras -chave que o padrão define. Precisamos de duas matrizes: uma para armazenar as palavras -chave e outra para armazenar o número de ocorrências correspondentes a cada palavra -chave. Esta implementação pode ser escrita como tal:

Char *Palavras -chave [nrkeywords]; INT Resultados [nrkeywords]; 

Olhando para o conceito, você verá em breve que ele usa um conceito de pares, que é descrito com mais eficiência usando uma estrutura. Então, devido ao resultado final que precisaremos, teremos uma matriz cujo elemento é uma estrutura. Vamos ver.

estrutura palavra -chave char *palavras -chave; Resultados int;  keyWrdtbl [nrkeywords]; 

Agora vamos inicializar a matriz com as palavras -chave e o número inicial de ocorrências que, é claro, serão 0.

estrutura palavra -chave char *palavras -chave; Resultados int;  KeyWrdtbl [] = "Auto", 0, "Break", 0, "Case", 0, ... "while", 0; 

Sua próxima e última tarefa, uma vez que esta tarefa é um pouco mais complexa, é escrever um programa completo que se considera o texto para trabalhar e imprimir o número de ocorrências de todas as palavras -chave, de acordo com o método acima.

O último assunto sobre estruturas com quem vou lidar é a questão dos ponteiros para as estruturas. Se você escreveu o programa no último exercício, você já pode ter uma boa ideia de como ele pode ser reescrito para que ele possa usar ponteiros em índices. Então, se você gosta de escrever código, pode considerar isso como um exercício opcional. Portanto, não há nada por aqui, apenas alguns aspectos, como (muito importante), você deve apresentar algum código extra com cuidado extra para que, ao analisar o código -fonte do arquivo que você está digitalizando para palavras -chave e, é claro, a função de pesquisa Deve ser modificado, você não criará ou tropeçará em um ponteiro ilegal. Veja a parte anterior para referência sobre aritmética do ponteiro e diferenças entre o uso de matrizes e o uso de ponteiros. Outra questão a ser cuidadosa é o tamanho das estruturas. Não se deixe enganar: só pode haver uma maneira de acertar a estrutura, e isso é usando sizeof ().

#incluir  estrutura teste int um; int dois; char *str; flutuar; ; int main () printf ("O tamanho da struct é %d.\ n ", tamanho de(estrutura teste)); retornar 0;  

Isso deve retornar 24, mas isso não é garantido, e a K&R explica isso por causa de vários requisitos de alinhamento. Eu recomendo usar o tamanho de sempre que você estiver em dúvida e não presume nada.

Sindicatos

Eu deveria ter alterado o título e incluir a palavra "sindicatos", e talvez até "Bitfields". Mas devido à importância e ao padrão de uso geral de estruturas versus sindicatos e campos de bits, especialmente agora que o hardware está se tornando uma mercadoria mais barata (não necessariamente pensamento saudável, mas de qualquer maneira), acho que o título dirá apenas "estruturas". Então, o que é uma união? Uma união se assemelha a uma estrutura, o que difere é a maneira como o compilador lida com o armazenamento (memória). Em resumo, uma união é um tipo de dados complexo que pode armazenar diferentes tipos de dados, mas um membro de cada vez. Então, independentemente do tamanho da variável armazenada, ela terá seu lugar, mas outros não serão permitidos na União naquele momento preciso. Daí o nome "Union". As declarações e definições de sindicatos são as mesmas que as estruturas, e é garantido que o sindicato terá tanta memória quanto seu 'maior membro.

Bitfields

Se você quiser usar C em programação de sistemas incorporados e/ou material de baixo nível é o seu jogo, essa parte parecerá atraente. Um campo de bits (alguns escrevem o campo de bit), não tem uma palavra -chave atribuída como enum ou união, e exige que você conheça sua máquina. Ele permite que você vá além das limitações tipicais baseadas em palavras. Ele também permite que você faça, e isso pode ser uma definição formal, “embalagem” mais de um objeto em uma única palavra.

Enums

Para começar com um breve fato histórico, as enumes foram introduzidas em C quando C89 estava fora da porta, o que significa que K&R não tinha esse tipo bacana. Uma enumeração permite que o programador crie um conjunto de valores nomeados, também conhecidos como enumeradores, que têm como principal característica de que eles têm um valor inteiro associado a eles, implicitamente (0,1,2 ...) ou explicitamente pelo programador ( 1,2,4,8,16…) . Isso facilita evitar números mágicos.

enum Pressão pres_low, pres_medium, pres_high; enum Pressão p = pres_high; 

Agora, isso é mais fácil, se precisarmos PRES_LOW para ser 0, médio 1 e assim por diante, e você não terá que usar #Defines para isso. Eu recomendo um pouco de leitura se você estiver interessado.

Conclusão

Embora a informação possa parecer um pouco mais condensada do que antes, não se preocupe. Os conceitos são relativamente fáceis de entender e um pouco de exercício fará maravilhas. Estamos esperando por você em nossos fóruns de Linux para qualquer discussão adicional.

Todos os artigos desta série:

  • EU. C Desenvolvimento no Linux - Introdução
  • Ii. Comparação entre C e outras linguagens de programação
  • Iii. Tipos, operadores, variáveis
  • 4. Controle de fluxo
  • V. Funções
  • Vi. Ponteiros e matrizes
  • Vii. Estruturas
  • Viii. E/S básico
  • Ix. Estilo de codificação e recomendações
  • X. Construindo um programa
  • XI. Embalagem para Debian e Fedora
  • Xii. Obtendo um pacote nos repositórios oficiais do Debian

Tutoriais do Linux relacionados:

  • Coisas para instalar no Ubuntu 20.04
  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Ubuntu 20.04 truques e coisas que você pode não saber
  • Mastering Bash Script Loops
  • Loops aninhados em scripts de basquete
  • Coisas para instalar no Ubuntu 22.04
  • Mint 20: Melhor que o Ubuntu e o Microsoft Windows?
  • Como fazer bota dupla kali linux e windows 10
  • Manipulação de big data para diversão e lucro Parte 1