Ir ao conteúdo
  • Cadastre-se

C Qual a diferença da função STRUCT para TYPEDEF STRUCT? E quando devo usar?


Posts recomendados

Basicamente comodidade, se você usar apenas struct para criar uma estrutura, toda vez que quiser usar essa estrutura, terá que usar a palavra struct.

Já declarando a estrutura com o typedef, você pode usar a estrutura diretamente.

Exemplo com código:

#include <stdio.h>
#include <stdlib.h>

struct Estrutura1 {
    int elemento;
};

typedef struct {
    int elemento;
} Estrutura2;

int main() {
    // Sem typedef precisa de struct
    struct Estrutura1 e1;
    
    // Com typedef nao precisa
    Estrutura2 e2;
    
    return EXIT_SUCCESS;
}

 

  • Curtir 2
  • Obrigado 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Igor Soares da Paixão

 

Estrutura:

struct
{
  int dia;
  int mes;
  int ano;
}DATA;
//
DATA.dia = 18;
DATA.mes = 10;
DATA.ano = 2020;

Como não há um rótulo, você não consegue criar mais variáveis do tipo DATA.

 

Estrutura apenas nomeada:

typedef struct
{
  int dia;
  int mes;
  int ano;
}DATA;
//
DATA amanha, ontem, hoje;

Nesse caso, foi omitido o rótulo. Ainda existem as estruturas apenas rotuladas e as rotuladas e nomeadas. 

  • Curtir 1
  • Obrigado 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

Citação

Qual a diferença da função STRUCT para TYPEDEF STRUCT? E quando devo usar?

 

Essa é uma confusão comum. typedef struct não existe. typedef struct é um pedaço de um comando. Os comandos são

  • typedef
  • struct.

Vou tentar explicar melhor.

 

O que importa é entender o que é um typedef. Esse comando permite que você defina um tipo. Só isso.

 

Você pode escrever 
 

typedef int Inteiro;


E aí declarar 
 

    int A = 12;
    Inteiro B = 56;


porque Inteiro passa a ser um alias para int, um sinônimo, um nick.

 

Quando usar algo assim?


Quando tiver alguma vantagem. typedef cria um tipo de encapsulamento e pode ser muito útil, muito além de economizar umas letras nas declarações.
 

Exemplo: stdlib


O protótipo de malloc() por exemplo é

void *malloc(size_t n);


O protótipo de read() é 
 

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);


Pra que isso de size_t? 


size_t é apenas um int sem sinal. Um typedef. E faz sentido, porque é um valor em bytes e não pode ser negativo. É mais fácil digitar o nome menorzinho, certo? Mas não é só isso: ao usar um novo tipo você permite que se possa mudar o tipo sem ter que mudar TODOS os programas que usam isso.

 

Exemplo: csdtint
 

    uint64_t bytes8 = 0;
    uint32_t bytes4 = 0;
    uint16_t bytes2 = 0;
    uint8_t  byte1  = 0;

Esses tipos definem inteiros sem sinal, com 1, 2, 4 ou 8 bytes, e assim você pode usar nos programas e ter certeza do tamanho, sem ter que saber o tamanho de um int na máquina em que está compilando o programa. Essa é uma aplicação do conceito de encapsulamento. Eles estão em stdint.h em Windows.

 

Em um IDE moderno você pode colocar o ponteiro sobre uma definição dessas e o IDE mostra o que é. Basta parar o ponteiro e esperar um ou dois segundos. E em geral tem uma tecla que você aperta para ir direto à defini;cão do tipo. No caso do que estou usando agora --- o Visual Studio da  Microsoft ---  é F12

 

 

image.png.65b54cb2fab9d50bd8b9dc84fa221573.png

 

image.png.f3252fbd858f96499cc371c283a38200.png

 

E ao usar F12
 

image.png.a9988a5b596008ae9eed304e555d44ce.png

 

É uma boa maneira de aprender o que é o que, e funciona com os seus typedef também.

 

Se usa um IDE que não tem isso apenas mude para outro que tenha

 

E o typedef struct afinal?


Pois é: não existe um. O que existe é um typedef struct xxx Nome por exemplo. Um typedef usado para criar um novo tipo para uma estrutura precisa fornecer duas coisas: o nome antigo e o novo. Os dois vem em seguida como no exemplo
 

Exemplo
 

#include <stdio.h>
#include <stdint.h>

struct st_Perfil
{
	int  idade;

};

typedef struct st_Perfil Perfil;

typedef int Inteiro;

struct st_Perfil* copia_perfil(struct st_Perfil, struct st_Perfil );

Perfil* copia_perfil_B( Perfil*, Perfil* );

int main(void)
{
	int A = 12;
	Inteiro B = 56;
	size_t  semSinal = 3456;

	uint64_t bytes8 = 0;
	uint32_t bytes4 = 0;
	uint16_t bytes2 = 0;
	uint8_t  byte1  = 0;

	return 0;
}

 


Quando é um tipo comum, não-struct:
 

typedef int Inteiro;


Quando é uma estrutura precisa da palavra struct antes
 

typedef struct st_Perfil Perfil;

Vendo o exemplo fica claro que é melhor usar a declaração com o typedef , no mínimo pra não ter que ficar repetindo a palavra struct toda hora. Mas é muito mais que isso: o typedef permite que você mude completamente a estrutura sem ter que mudar as declarações em todos os programas que usam isso.

 

  • Curtir 1
  • Obrigado 2
  • Amei 3
Link para o comentário
Compartilhar em outros sites

2 horas atrás, arfneto disse:

Um typedef usado para *criar um novo tipo para uma estrutura precisa fornecer duas coisas: o nome antigo e o novo. Os dois vem em seguida como no exemplo

 

*Anteriormente é dito que a palavra reservada é útil para: definir, criar outros nomes (sinônimos), simplificar sintaxe de declaração de tipos e estruturas, esconder, ou melhor, agrupar e esconder outras palavras reservadas  (encapsulamento).

 

Menos 'criar um novo tipo', que não é só desnecessário como é errado de várias maneiras, a informação importante é: typedef e outros especificadores, não criam tipos.

"

 

 

Link para o comentário
Compartilhar em outros sites

Em 18/10/2020 às 14:33, mauro_b disse:

Menos 'criar um novo tipo', que não é só desnecessário como é errado de várias maneiras, a informação importante é: typedef e outros especificadores, não criam tipos

 

Então typedef, um acrônimo em inglês para type definition, não cria um tipo! Apenas define um nome. Fascinante. 

 

 

Então apenas como eu disse também
 

Em 18/10/2020 às 12:25, arfneto disse:

porque Inteiro passa a ser um alias para int, um sinônimo, um nick

 

Então deve ser porque definir não é criar.  Pode ser visto como algo um tanto quanto pedante se ater a essa possível diferenciação.

 

Depois do que  foi explicado no tópico #5 com as definições e exemplos, não vejo a importância dessa distinção. Na definição da linguagem typedef está definido como... type definition e não type creation é verdade, no item 6.7.8 cujo título é: type definitions e não type creation. [ISO 9899.201x] 

 

Um tanto pedante essa distinção, eu diria. E pouco acrescenta ao tópico se algo: typedef faz o que eu disse que faz. Os exemplos fazem o que eu disse que fazerm, e o uso é aquele que eu mostrei. 

 

Mas será que depois de um
 

typedef unsigned int size_t;


size_t será um tipo? Não, tem razão: pela norma é um typedef name. Uma pedante distinção

 

Quando você declara
 

    size_t valor = 300;


qual o tipo de valor?  claro, valor é unsigned int. size_t é só um typedef name, um alias. Claro que no mundo real se vai dizer que é do tipo size_t, assim vai estar nos livros e manuais. Autores escrevem que malloc() recebe um parâmetro do tipo size_t

 

 

 

 

 

 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...