Você já conhece a Struct em C?

Quando precisamos construir um sistema personalizado para algum ou alguma cliente, devemos ter uma ferramenta que seja flexível para as diversas regras de negócio do projeto. Algo que nos dê liberdade de criar uma estrutura que todas as pessoas desenvolvedoras consigam entender.

Pensando nisso, sabemos que em algumas linguagens o conceito de POO trabalha com classes que são traduzidas em objetos. Por outro lado, no Javascript, conseguimos criar objetos quando necessitamos.

Dessa forma, foi criado com esses objetivos a estrutura de dados Struct, que tem o papel de facilitar a organização de diversas informações — algo que só é possível no C++, já que ele tem o suporte a POO. Siga lendo o nosso post para entender mais sobre como funciona o Struct!

O que é Struct?

Struct é uma abreviação para Structure, que significa estrutura em português. Na linguagem de programação C (e em muitas outras) é uma estrutura de dados composto que define fisicamente uma lista de variáveis agrupadas sob um nome em um bloco de memória, logo, todas as variáveis conseguem ser acessadas por meio de um único ponteiro ou pelo que é declarado na estrutura que retorna o mesmo endereço.

No Struct, conseguimos agrupar diversos tipos de dados, portanto, é usado com frequência para registros de tipos de dados mistos, algo como um cadastro que requer vários dados diferentes (nome, endereço, telefone, etc.).

O Struct em C faz a referência direta a bloco contíguo de memória física, geralmente delimitado (dimensionado) por limites de comprimento de palavra. A palavra Struct corresponde ao recurso com nome semelhante disponível em algumas linguagens de baixo nível e até processadores Intel. Sendo um bloco de memória contígua, cada campo dentro de uma estrutura está localizado em um determinado deslocamento fixo desde o início.

Já que o conteúdo de uma Struct é armazenado em memória contígua, o operador sizeof deve ser usado para obter o número de bytes necessários para armazenar um tipo específico de estrutura, da mesma forma que pode ser usado para variáveis primitivas. 

O alinhamento de campos específicos na Struct (com relação aos limites das palavras) é específico da implementação e pode incluir preenchimento, embora os compiladores modernos normalmente suportam a diretiva #pragmapack, que altera o tamanho em bytes usados para o alinhamento.

Na linguagem C++, observamos que o Struct é idêntico a uma classe C ++, mas tem uma visibilidade padrão diferente: os membros da classe são privados por padrão, enquanto os membros da estrutura são públicos por padrão.

Qual o significado da palavra struct?

Como já comentado, Struct nada mais é do que uma estrutura com diversos tipos de dados, também é conhecido pelo nome de registro. A ideia do Struct é de armazenar os dados em uma mesma entidade, em apenas uma única variável. Se quisermos guardar o nome, telefone e o e-mail de uma pessoa, podemos criar uma Struct chamada Pessoa, por exemplo, e agrupar essas informações em um único tipo de dado.

Quais as diferenças entre Arrays e Structs?

A principal diferença é que uma Array suporta vários dados de apenas um tipo e uma Struct consegue guardar vários dados de diversos tipos. Podemos também observar algumas outras diferenças entre essas estruturas de dados:

Base para comparaçãoArrayStruct
Conceito básicoUma Array é uma coleção de variáveis do mesmo tipo de dados.Uma Struct é uma coleção de variáveis de diferentes tipos de dados.
MemóriaOs elementos de uma Array são armazenados em um local de memória contíguo.Os elementos da Struct não podem ser armazenados em um local de memória contíguo.
AcessoOs elementos da Array são acessados por seu número de índice.Os elementos da Struct são acessados por seus nomes.
OperadorTanto a declaração como o operador de acesso da Array é o elemento “[]” (colchete).O operador de acesso do elemento de uma Struct é o “.” (Operador ponto).
PonteiroO nome da Array aponta para o primeiro elemento desse array, portanto, o nome da array é um ponteiro.O nome da Struct não aponta para o primeiro elemento dessa struct, portanto, o nome da struct não é um ponteiro.
TamanhoCada elemento na Array tem o mesmo tamanho.Cada elemento em uma Struct possui diferentes tipos de dados.
Tempo de acessoAcessar o elemento da array requer menos tempo.Acessar os elementos de uma struct requer comparativamente mais tempo.
BuscaPesquisar um elemento da array leva menos tempo.Pesquisar um elemento de uma struct leva comparativamente mais tempo do que um elemento da array.
Definido pelo usuárioOs arrays não são definidos pelo usuário, eles são declarados automaticamente.O struct é um tipo de dados definido pelo usuário.

As array são acessadas rapidamente, já que o tamanho de cada elemento em uma array é constante. Já na Struct, temos um acesso um pouco mais defasado, já que cada elemento de uma variável da estrutura tem um tamanho diferente entre si.

Definição de uma Array

Uma array é uma lista de variáveis ou elementos do mesmo tipo de dados. Os elementos em uma array são referidos coletivamente por um nome comum, que é o nome da array em si. 

O número de variáveis que uma array pode ter é definido no momento da declaração entre colchetes precedidos pelo nome dessa array. Em C++, há uma verificação bem restrita de limite nas array, você não conseguirá armazenar mais elementos do que uma array suporta.

Para que serve Struct em C e quando usar?

O principal objetivo do Struct, como já vimos, é criar uma estrutura de dados que junte vários tipos de dados em apenas um bloco de memória, tanto para facilitar o acesso, como também melhorar o entendimento da arquitetura do programa.

Podemos utilizar o Struct para criar diversas estruturas personalizadas para o nosso sistema.

Por exemplo, se quisermos criar um sistema que cadastre uma pessoa, é recomendável criar um Struct com todas as informações necessárias para esse cadastro, algo como, nome, endereço, idade, altura…

Com essas informações, criamos uma Struct declarando os tipos das variáveis e os seus respectivos nomes. Logo após isso, basta utilizar a estrutura em qualquer local do código.

Seguindo nessa linha, temos a chance de criar funções que aceitam o parâmetro personalizado da nossa estrutura de dados e que pode ou não retornar também uma outra estrutura de dados, conseguimos até mesmo modificar os valores através dos operadores de acesso que são disponibilizados pela linguagem.

Por fim, podemos reutilizar todas essas informações em várias partes do nosso código e torná-lo muito mais simples.

Como usar Struct em C? 6 exemplos na prática!

Logo abaixo veremos alguns exemplos práticos para melhor compreender a utilização do Struct.

Definindo uma estrutura

Vamos começar criando uma estrutura do zero, e para isso devemos utilizar a instrução Struct para criar um novo tipo de dados. A sintaxe dessa instrução é a seguinte:

struct [tag da estrutura] {
   tipo_da_variavel nome_da_variavel;
   tipo_da_variavel nome_da_variavel;
   ...
   tipo_da_variavel nome_da_variavel;
} [uma ou mais variáveis da estrutura]; 

A tag de estrutura é opcional e cada definição de uma variável é igual, como int i; ou float f; ou qualquer outra definição de variável válida. No final da definição da estrutura, antes do ponto e vírgula final, você pode especificar uma ou mais variáveis de estrutura, mas também é opcional. Esta é uma maneira de como você declararia uma estrutura de um livro:

struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
} livro;

Declarando as variáveis de uma Struct

A declaração das variáveis em um registro pode ser feito de algumas maneiras, tais como:

struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};

struct Livros Livro1, Livro2;        /* Declarando Livro1 e Livro2 do tipo Livro */

e também:

struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
} Livro1, Livro2; // declarando as variáveis na própria estrutura, não é muito recomendável

Nesse último código, as variáveis Livro1 e Livro2 são criadas a partir da estrutura Livros, no entanto, essa fórmula não é muito recomendada.

Inicializando uma estrutura

Podemos adicionar os valores para os dados de uma struct de duas formas:

struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};

struct Livros Livro1 = { "Título genérico", "Blog Trybe", "Um livro bem genérico", 6495407 };    // inicializando

Ou também:

struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};

struct Livros Livro1;        /* Declarando Livro1 do tipo Livro */
strcpy( Livro1.titulo, "Título genérico"); // inicializando os valores para cada variável separada
strcpy( Livro1.autor, "Blog Trybe"); 
strcpy( Livro1.assunto, "Um livro bem genérico");
Livro1.id_livro = 6495407;

Acessando os dados de uma estrutura

Para acessar algum dado de uma estrutura, utilizamos o operador de acesso que é o ponto (.). O operador de acesso é escrito entre o nome da variável e o dado da estrutura que desejamos acessar. Você também pode usar a palavra-chave struct para declarar variáveis a partir de outras structs. Podemos ver mais sobre o funcionamento do struct em um programa:

#include <stdio.h>
#include <string.h>
 
struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};
 
int main( ) {

   struct Livros Livro1;        /* Declaramos Livro1 do tipo Livro */
   struct Livros Livro2;        /* Declaramos Livro2 do tipo Livro */
 
   /* especificações do livro 1 */
   strcpy( Livro1.titulo, "Título genérico");
   strcpy( Livro1.autor, "Blog Trybe"); 
   strcpy( Livro1.assunto, "Um livro bem genérico");
   Livro1.id_livro = 6495407;

   /* especificações do livro 2 */
   strcpy( Livro2.titulo, "Outro título genérico");
   strcpy( Livro2.autor, "Blog Trybe 2");
   strcpy( Livro2.assunto, "Mais um livro bem genérico");
   Livro2.id_livro = 6495700;
 
   /* mostrando as informações do livro 1 */
   printf( "Livro 1 titulo : %s\n", Livro1.titulo);
   printf( "Livro 1 autor : %s\n", Livro1.autor);
   printf( "Livro 1 assunto : %s\n", Livro1.assunto);
   printf( "Livro 1 id_livro : %d\n", Livro1.id_livro);

   /* mostrando as informações do livro 2 */
   printf( "Livro 2 titulo : %s\n", Livro2.titulo);
   printf( "Livro 2 autor : %s\n", Livro2.autor);
   printf( "Livro 2 assunto : %s\n", Livro2.assunto);
   printf( "Livro 2 id_livro : %d\n", Livro2.id_livro);

   return 0;
}

Quando você compila e executa o código acima, temos o seguinte resultado:

Resultado acessando dados struct em C

Struct como um argumento de uma função

Você pode passar uma estrutura como um argumento de uma função da mesma maneira que passa qualquer outra variável ou ponteiro, veja como:

#include <stdio.h>
#include <string.h>
 
struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};
 
void printLivro( struct Livros livro );

int main( ) {

   struct Livros Livro1;        /* Declaramos Livro1 do tipo Livro */
   struct Livros Livro2;        /* Declaramos Livro2 do tipo Livro */
 
   /* especificações do livro 1 */
   strcpy( Livro1.titulo, "Título genérico");
   strcpy( Livro1.autor, "Blog Trybe"); 
   strcpy( Livro1.assunto, "Um livro bem genérico");
   Livro1.id_livro = 6495407;

   /* especificações do livro 2 */
   strcpy( Livro2.titulo, "Outro título genérico");
   strcpy( Livro2.autor, "Blog Trybe 2");
   strcpy( Livro2.assunto, "Mais um livro bem genérico");
   Livro2.id_livro = 6495700;
 
   /* mostrando as informações do livro 1 */
   printLivro( Livro1 );
   
   /* mostrando as informações do livro 1 */
   printLivro( Livro2 );

   return 0;
}

void printLivro( struct Livros livro ) {
   printf( "Livro titulo : %s\n", livro.titulo);
   printf( "Livro autor : %s\n", livro.autor);
   printf( "Livro assunto : %s\n", livro.assunto);
   printf( "Livro id_livro : %d\n", livro.id_livro);
}

Quando o código é compilado e executado, obtemos um resultado bem semelhante ao outro exemplo:

Outro resultado de struct em C

Ponteiros para Structs

Você pode definir ponteiros para estruturas da mesma forma que define ponteiros para qualquer outra variável.

struct Livros *struct_ponteiro;

Dessa maneira, você consegue armazenar o endereço de uma variável de struct em uma variável de ponteiro definida acima. Para encontrar o endereço de uma variável de estrutura, coloque o operador & antes do nome da estrutura da seguinte forma:

struct_ponteiro = &Livro1;

Para acessarmos os dados de uma estrutura usando um ponteiro, devemos utilizar o operador -> da seguinte maneira:

struct_ponteiro->titulo;

Vamos reescrever o nosso código utilizando os ponteiros.

#include <stdio.h>
#include <string.h>
 
struct Livros {
   char  titulo[50];
   char  autor[50];
   char  assunto[100];
   int   id_livro;
};

/* declaração da função */
void printLivro( struct Livros *livro );

int main( ) {

   struct Livros Livro1;        /* Declarando Livro1 do tipo Livro */
   struct Livros Livro2;        /* Declarando Livro2 do tipo Livro */
 
   /* especificações do livro 1 */
   strcpy( Livro1.titulo, "Título genérico");
   strcpy( Livro1.autor, "Blog Trybe"); 
   strcpy( Livro1.assunto, "Um livro bem genérico");
   Livro1.id_livro = 6495407;

   /* especificações do livro 2 */
   strcpy( Livro2.titulo, "Outro título genérico");
   strcpy( Livro2.autor, "Blog Trybe 2");
   strcpy( Livro2.assunto, "Mais um livro bem genérico");
   Livro2.id_livro = 6495700;
 
   /* mostrando informações do Livro1 passando o endereço da memória */
   printLivro( &Livro1 );

   /* mostrando informações do Livro2 passando o endereço da memória */
   printLivro( &Livro2 );

   return 0;
}

void printLivro( struct Livros *livro ) {
   printf( "Livro titulo : %s\n", livro->titulo);
   printf( "Livro autor : %s\n", livro->autor);
   printf( "Livro assunto : %s\n", livro->assunto);
   printf( "Livro id_livro : %d\n", livro->id_livro);
}

O resultado continuará sendo igual:

Mesmo resultado da estrutura

Quais as vantagens do Struct em C?

A principal vantagem de um Struct é que temos a possibilidade de armazenar diversos tipos de dados que não são possíveis nas arrays. Os arrays só podem lidar com o mesmo tipo de dados. Recorrendo a algumas práticas incertas, conseguimos guardar e acessar as informações em uma array, porém acabamos perdendo a identidade particular que relaciona os dados a apenas um lugar.

Utilizando Struct conseguimos criar uma estrutura de dados para guardar e acessar todos os dados de um tipo sem perder a sua identidade particular, mesmo tendo uma enorme quantidade de dados.

Somos capazes também de simplificar o nosso código, de uma maneira que, se for necessário passar vários parâmetros para uma função, conseguimos criar uma estrutura que pode ser utilizada para isso.

Quais as limitações do Struct em C?

Logo abaixo você pode ver algumas limitações na forma de criar e utilizar o Struct em C:

  • Não é permitido que uma estrutura seja tratada como um tipo de dados integrado.
  • Não conseguimos usar os operadores matemáticos, como o +, -, etc.
  • As estruturas em C não suportam a ocultação de dados. Os membros da estrutura conseguem ser acessados por qualquer função, em qualquer lugar no escopo da Struct.
  • Não é permitido adicionar funções dentro de uma Struct
  • Também não é possível adicionar dados estáticos dentro de seu corpo.
  • Na linguagem C não temos o suporte aos modificadores de acesso, logo, eles não podem ser usados nas Structs.
  • Por último, não se pode colocar construtores dentro de uma Struct.

Como declarar um Struct em C++?

A declaração de uma Struct em C++ é totalmente semelhante ao da linguagem C, portanto, podemos escrever o código da seguinte maneira que ele funcionará no compilador do C++.

#include <iostream>    
using namespace std;

struct Comprimento {
	int metros;
	float centimetros;
};

int main(void) {
	struct Comprimento c;
	c.metros = 2;
	c.centimetros = 34;
	cout << "Metros: " << c.metros << endl;
	cout << "Centímetros: " << c.centimetros << endl;

	return 0;
}

Como declarar um Struct em Java?

Para criar uma solução parecida com uma Struct em Java, podemos utilizar o conceito de classe, que é bem semelhante às estruturas em C. Primeiro criamos a classe e depois a chamamos para alterar e acessar os dados.

final class Comprimento { 
    private final int metros;
    private final float centimetros;

    // inicializando valores do comprimento
    public Comprimento(int Metros, float centimetros) {
        this.metros = metros;
        this.centimetros = centimetros;
    }

    // métodos para acessar os dados
    public int metros() { return metros; }
    public float centimetros() { return centimetros; }
}

Para usar essa classe devemos fazer assim:

// Adicionando os valores
Comprimento c = new Comprimento(2, 34);
// Acessando os valores
System.out.println("metros: " + c.metros());
System.out.println("centimetros: " + c.centimetros());

Como declarar um Struct em C#?

Mesmo C# sendo uma linguagem orientada a objetos, temos a liberdade de utilizar a estrutura de dados Struct.

struct Comprimento {
    public int metros;
    public float centimetros;
}

// Declarando a Struct para uma variável
Comprimento comprimento;

// Adicionando os valores
comprimento.metros = 2;
comprimento.centimetros = 0.34;

// Recuperando os valores
Console.Write(comprimento.metros);  
Console.Write(comprimento.centimetros);

Quando queremos guardar uma sequência longa de dados, utilizamos a Array para facilitar o nosso trabalho e quando queremos organizar os nossos dados em uma interface que aceita diversos tipos de dados e tornar as identidades únicas, então escolhemos utilizar o Struct.

Como em outras linguagens, temos algumas estruturas e procedimentos que são semelhantes ao do Struct em C, o conceito é bem simples, codificamos algumas variáveis que vão ser aceitar tanto para escrita como para leitura em cada bloco de um Struct, conforme a declaração das variáveis, obtemos a possibilidade de replicar a estrutura de dados criada previamente, tanto nos parâmetros de funções como nos retornos. 

Se for de seu interesse, leia um pouco mais sobre a Linguagem C: o que é e quais os principais fundamentos!

0 Shares:
Você também pode gostar