Dúvida em c [RESOLVIDO]

1. Dúvida em c [RESOLVIDO]

Aterson lino
Atr

(usa openSUSE)

Enviado em 21/08/2019 - 18:09h

Boa noite!
Pra que serve o typedef?
Sei que é para criar um novo tipo, mas não entendi seu funcionamento!


  


2. Re: Dúvida em c

Paulo
paulo1205

(usa Ubuntu)

Enviado em 21/08/2019 - 18:33h

typedef não cria tipos novos, mas cria apelidos para tipos existentes, e é, por isso, mais útil no caso de tipos compostos.

typedef unsigned char uint8_t;  // Declara “uint8_t” como apelido para o tipo simples (não-composto) “unsigned char”.

typedef uint8_t byte; // Agora “byte” também é um sinônimo de “unsigned char”, assim como “uint8_t”.

typedef char string50[51]; // Declara “string50” como apelido para array com 51 elementos do tipo char.

struct no_lista {
struct no_lista *anterior, *proximo;
void *dados_no;
};
typedef no_lista *no; // Declara “no” como apelido para ponteiro para struct no_lista.
// Note que os campos ‘anterior’ e ‘proximo’ não puderam usar o typedef porque ele ainda não havia sido declarado.

typedef struct lista {
no primeiro, ultimo, corrente;
} t_lista; // Numa tacada só, declara o tipo “struct lista” e seu apelido “t_lista”. Ambos podem ser usados de modo intercambiável no programa.

typedef struct {
char nome[50];
int idade;
char sexo;
} t_registro; // Declara “t_registro” como apelido para essa estrutura anônima. A equivalência existe, mas como é anônima, não tem como ser recuperada mais tarde, e é obrigatório usar o nome do typedef.



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


3. Re: Dúvida em c

???
gokernel

(usa Linux Mint)

Enviado em 22/08/2019 - 11:40h


O paulo acima já falou praticamente tudo ... isso é só um complemento ( um modelo que utilizo ) ...

Geralmente gosto de declarar todas as ( "typedef struct" ) em um só lugar para ter uma visão geral de todas as structs ... exemplo abaixo:


//-------------------------------------------------------------------
//
// SIMPLE TEMPLATE:
//
// Main Header.
//
// FILE:
// simple.h
//
// START DATE: 27/07/2019 - 08:30
//
//-------------------------------------------------------------------
//
#ifndef _SIMPLE_H_
#define _SIMPLE_H_

#ifdef __cplusplus
extern "C" {
#endif

//-----------------------------------------------
//------------------ INCLUDE ------------------
//-----------------------------------------------
//
#include "algum_arquivo.h"

//-----------------------------------------------
//--------------- DEFINE / ENUM ---------------
//-----------------------------------------------
//
#define LEXER_NAME_SIZE 1024
#define LEXER_TOKEN_SIZE 1024 * 4

//-----------------------------------------------
//------------------- STRUCT ------------------
//-----------------------------------------------
//
typedef union VALUE VALUE;
typedef struct TVar TVar;
typedef struct LEXER LEXER;
typedef struct ASM ASM; // JIT opaque struct in file: "asm.c"

union VALUE {
long l; //: type integer
float f; //: type float
char *s; //: type pointer of char
void *p; //: type pointer
};
struct TVar {
char *name;
int type;
VALUE value;
void *info; // any information ... struct type use this
};
struct LEXER {
char *text;
char name [ LEXER_NAME_SIZE + 1 ];
char token [ LEXER_TOKEN_SIZE + 1 ];
int tok;
int pos;
int line;
int level; // in: '{' := level++ | in: '}' := level--;
int ifdef_block;
};

//-----------------------------------------------
//-------------- GLOBAL VARIABLE --------------
//-----------------------------------------------
//

//-----------------------------------------------
//----------------- PUBLIC API ----------------
//-----------------------------------------------
//
void funcao_prototipo (void);

#ifdef __cplusplus
}
#endif
#endif // ! _SIMPLE_H_





4. Re: Dúvida em c

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/08/2019 - 15:51h

Outro aspecto, que vale no caso de typedefs que envolvem struct ou union: de modo geral, o uso de apelidos por meio de typedef ocorre quando você deseja esconder do usuário a existência da struct ou union, para que ele não tente manipular diretamente os campos que formam tais tipos estruturados. Por outro lado, quando se espera ou deseja que o usuário veja ou manipule os campos individualmente, evita-se o uso do typedef, expondo-lhe que ele tem de lidar com uma estrutura ou união.

De modo mais geral, mais do que esconder apenas campos de tipos compostos, typedefs também podem ser usandos para definir detalhes de implementação que usem até mesmo tipos nativos.

Exemplos:

  • O tipo FILE é declarado em <stdio.h> com algo parecido com “typedef struct _IO_FILE FILE;”. Você, como programador, não é exposto em momento nenhum ao conteúdo da estrutura _IO_FILE, e todas as interações do seu programa com objetos desse tipo serão feitas por meios de ponteiros para FILE.

  • O tipo struct tm de <time.h> é exposto como estrutura para o usuário, porque é esperado que o usuário deseje examinar e manipular campos individuais da representação de data e hora que um dado desse tipo armazena.

  • No mesmo <time.h>, o tipo time_t é definido como um typedef. Usuários de UNIX e outros sistemas compatíveis com POSIX estão acostumados a tratar time_t como um apelido de long ou long long, mas o padrão do C não obriga a que seja assim, limitando-se a dizer que deve ser um tipo aritmético (i.e. uma outra implementação pode escolher usar números de ponto flutuante, também). Ser inteiro ou de ponto flutuante é um detalhe de implementação, que fica escondido do usuário final pelo uso do typedef. Nós, usuários, deveríamos ter sempre o cuidado de não assumir que é um tipo ou outro, e usar funções da biblioteca ou conversões explícitas quando quisermos usá-los de uma maneira específica.
// Código inseguro.
time_t t1, t2;
t1=time(NULL);
/* Realiza ação demorada. */
t2=time(NULL);
printf("Início: %d. Fim: %ld. Duração: %lld\n", t1, t2, t2-t1);
// Essas conversões de printf() podem gerar alarmes durante a compilação e imprimir lixo durante a execução.

// Versão um pouco mais segura, com conversão explícita.
time_t t1, t2;
t1=time(NULL);
/* Realiza ação demorada. */
t2=time(NULL);
printf("Início: %d. Fim: %ld. Duração: %lld\n", (int)t1, (long)t2, (long long)t2-(long long)t1);
// Elimina alarmes durante a compilação, mas ainda pode imprimir lixo, se houver truncamento ou arredondamento em alguma conversão forçada de tipos.

// Versão mais robusta, usando difftime(), que devolve sempre um valor do tipo double, e uma referência de tempo (t0).
const time_t t0=(time_t)0;
time_t t1, t2;
t1=time(NULL);
/* Realiza ação demorada. */
t2=time(NULL);
printf("Início: %0.15g. Fim: %0.15g. Duração: %0.15g\n", difftime(t1, t0), difftime(t2, t0), diffime(t2, t1));
// Todos os valores relativos a outro time_t, e não haverá erros por conversão forçada, mas inadequada, de tipos.



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


5. Re: Dúvida em c

Aterson lino
Atr

(usa openSUSE)

Enviado em 23/08/2019 - 14:28h

Tentei fazer assim:

#include <stdio.h>
int main(void){
typedef struct dd dd;
struct dd{
char *n;

};
printf("nome: ");
scanf("%[^\n]s%*c", &dd.n);
return 0;
}

Mas não funciona


6. Re: Dúvida em c

???
gokernel

(usa Linux Mint)

Enviado em 24/08/2019 - 14:53h

O seu código acima em momento nenhum cria uma struct ( tipo dd ) ... apenas declara:

Modifiquei para isso:


#include <stdio.h>

int main (void) {
typedef struct dd dd;
struct dd {
char n[1024];
};

//-----------------------
// cria aqui:
//-----------------------
//
dd my_struct_dd;

printf ("nome: ");
// scanf ("%[^\n]s%*c", &dd.n); // <<<<<<<<<< seu codigo antigo >>>>>>>>>>
scanf ("%[^\n]s%*c", &my_struct_dd.n); // modifiquie para esse ...

return 0;
}


E cuidado:
Você declarou a ( struct dd.n ) como um ponteiro ... e em nenhum momento alocou memória esse ponteiro ... então modifiquei para uma "array de char" . OK ?



7. Re: Dúvida em c [RESOLVIDO]

Aterson lino
Atr

(usa openSUSE)

Enviado em 27/08/2019 - 16:11h

obrigado pelas explicações, consegui entender agora!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts