Dúvida de Iniciante Como enviar valor a uma variável [RESOLVIDO]

1. Dúvida de Iniciante Como enviar valor a uma variável [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/03/2019 - 12:04h

Tentarei explicar minha dificuldade, olhem o exemplo abaixo que fiz e os comentários para essa pergunta.
Quero entender porque no exemplo 2 eu consigo fazer o que não consigo aqui no exemplo 1
#include <stdio.h>
#include <string.h>

int main(void){

/* 1) QUERO PREENCHER UM VETOR COM VALORES IGUAIS. NÃO ESTOU CONSEGUINDO FAZER!

OBS: SEI SOBRE O FINAL DA LINHA \0 MAS VAMOS IGNORAR POR ENQUANTO POR FAVOR!
ESTES TESTES QUE ESTOU FAZENDO O OBJETIVO É EU ENTENDER MELHOR AS VARIÁVEIS */

char Text[50] = {0}; // FUNCIONA, Preencho o vetor com ZEROS

/* OBS AQUI nesta linha não quero varrer o vetor para preencher! Tipo com for ou while.
A idéia seria preencher de uma só vez na declaração */
char Text2[50] = {1}; // NÃO FUNCIONA, Preencher o vetor com números 1. Ele só escreve em Text2[0]
// EU queria preencher como consegui fazer com os ZEROS acima

// COMPILADOR NÃO ACEITA ISSO
// char Text3[50] = {a}; // Preencher ele inteiro com alguma letra

char Text4[50] = {'x'}; // FALHA só preenche a posição Text4[0]
char Text5[50] = {"x"}; // FALHA só preenche a posição Text5[0]


/* DÚVIDA ABAIXO, eu estou apanhando muito, minha cabeça deu um nó pois não sei
porque não sei colocar um valor em uma posição da variável */

strcpy(Text, "Vivx o Linux"); // Preenchi minha variável com um texto menor que o vetor.

/* Quero agora colocar a letra a no lugar do x!

PORÉM: Não quero localizar o x, Não quero varrer a variável!
Quero somente atribuir um valor a uma posição que eu determinar! Mas não sei se é posível ou permitido isso!

ISSO É POSSÍVEL? */

Text[3] = "a"; // Não funciona Ele colocou um 4 ao invés de a
Text[1] = "b"; // Não funciona Ele colocou um 6 ao invés de b

// Eu queria colocar a LETRA não o decimal
Text[3] = 'a'; // Ele colocou o Decimal de a 97
Text[1] = 'b'; // Ele colocou o Decimal de b 98

// EXISTE alguma forma de eu atribuir valor de forma parecida com a de cima?
}


Abaixo um exemplo de como eu consigo fazer. Porém como ainda estou aprendendo, não entendi porque usando uma função eu consigo escolher onde eu quero colocar o valor por exemplo Texto1[4] pois no exemplo abaixo eu varro os caracteres pela posição onde eles estão. Esse exemplo abaixo eu peguei na internet simplifiquei e estou tentando entender ele. As Dúvidas estão no comentário dele.
#include <stdio.h>
#include <string.h>

void concatenate(char [], char []);

int main(){
char Texto1[20] = "Nick", Texto2[] = " usa Slackware";
concatenate(Texto1, Texto2);
printf("Texto = %s\n", Texto1);
}

void concatenate(char Texto1[], char Texto2[]){
/* Aqui dentro, os Texto1 e Texto2 viraram ponteiros não são vetores! PORQUE?
Não entendo eles serem ou parecerem ponteiros, porque não existe nenhuma declaração com *
para indicar que é um ponteiro */

int c = strlen(Texto1), d = 0;
while(Texto2[d] != '\0'){
Texto1[c] = Texto2[d]; // Ele junta os textos como se fossem ponteiros. SÃO PONTEIROS OU NÃO?
d++;
c++;
}
// Aqui posso escolher a posição que quero escrever meu texto. E no caso do 1º Código acima não consigo de forma alguma
Texto1[c] = '\0';
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/03/2019 - 17:21h

No primeiro programa, nas declarações de Text1, Text2, Text4 e Text5, as atribuições de valores iniciais funcionam todas corretamente. Você informa apenas um valor de elemento a ser preenchido, e todos os demais são preenchidos com zero, que é o valor a ser usado em todos os casos em que a lista de elementos aparece apenas parcialmente. Se você quisesse preenchê-los com cinquenta caracteres não-nulos, teria de listar todos os cinquenta elementos, individualmente, mesmo que eles sejam todos iguais entre si.

As atribuições de strings (usando aspas) a elementos específicos de Text1 produzem resultados inesperados porque Text1 é um array de caracteres, não um array de strings. O que acaba acontecendo como resultado das operações é que as strings são convertidas em ponteiros, e os ponteiros convertidos em inteiros, e os inteiros são truncados de forma a caber em bytes únicos, que então são gravados nos respectivos elementos de Text1.

Se você estiver com um compilador minimamente moderno, essa conversão de ponteiro para inteiro deve ter produzido mensagem de alerta, que você talvez não tenha visto. Eu gosto sempre de ligar opções de compilação que transformam alertas em erros, de modo a impedir que o que provocou o alerta (que é uma condição que não necessariamente tem de fazer a compilação parar, mas que indica algo que pode ser fruto de acidente, e merece uma atenção especial), e ainda costumo pedir que se gera a maior quantidade possível de alertas/erros, do modo a ter um código mais seguro. Para o GCC, eu recomendo sempre as opções “-Wall -Werror -pedantic-errors -O2”.

Já as atribuições usando caracteres (entre apóstrofos) são o que se deve mesmo usar. Não entendi sua reclamação a respeito de valor decimal. Em C, apesar do nome que tem, char é um tipo aritmético inteiro, de modo que caracteres são facilmente conversíveis em números (normalmente o índice desses caracteres na tabela de caracteres) e vice-versa.


No segundo programa, as declarações dos parâmetros da função concatenate() especificam ponteiros mesmo, não arrays (a sintaxe de colchetes vazios para indicar ponteiros é outro fóssil histórico herdado da linguagem B). Assim, não lhe deveria causar qualquer estranheza esse ponto.

Na passagem de argumentos para a função, tanto Texto1 quanto Texto2 são arrays, respectivamente com 20 e com 15 elementos (a declaração de Texto2 usa colchetes vazios, mas num contexto diferente: na declaração de arrays acompanhada da atribuição de valores iniciais, ela significa que o compilador deve inferir automaticamente a quantidade de elementos). Contudo, quando usados como argumentos da função, os arrays decaem automaticamente para ponteiros constantes, os quais apontam para os primeiros elementos dos respectivos arrays,

Assim, não há qualquer problema de incompatibilidade de tipos: a função tem parâmetros que são ponteiros, e os argumentos usados na invocação da função são ponteiros produzidos por decaimento.

O problema, em ambos os casos, é que geralmente não se ensina sobre aspectos da linguagem como decaimento automático e ponteiros com aparência de arrays quando aparecem na declaração de parâmetros de função. Ao longo das minhas três décadas de C (comecei em 1989... o tempo voa!), minha experiência é que muitas pessoas não tem a menor ideia sobre essas partes normais da linguagem — eu mesmo já paguei mico aqui neste mesmo fórum do VoL por minha ignorância a respeito do decaimento automático, há alguns anos.


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

3. Re: Dúvida de Iniciante Como enviar valor a uma variável [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 01/03/2019 - 19:50h

paulo1205 escreveu: Se você quisesse preenchê-los com cinquenta caracteres não-nulos, teria de listar todos os cinquenta elementos, individualmente, mesmo que eles sejam todos iguais entre si.

Ok, Agora então já sei! É importante para mim saber esses detalhes, para compreender se existe formas melhores de fazer.

Para o GCC, eu recomendo sempre as opções “-Wall -Werror -pedantic-errors -O2”.

Eu já conhecia essas opções, mas agradeço sua recomendação a elas. Pois -Werror eu não conhecia e vou adicionar a minhas anotações. Em meus testes somente compilo rápido básico: gcc nome_programa.c
Mas acho que antes até de eu postar uma pergunta, eu deveria realmente usar a ajuda do compilador antes! Principalmente qdo eu não consigo entender algo. Ficarei mais atento a isso.

Já as atribuições usando caracteres (entre apóstrofos) são o que se deve mesmo usar.

Bom Saber!

No segundo programa, as declarações dos parâmetros da função concatenate() especificam ponteiros mesmo, não arrays (a sintaxe de colchetes vazios para indicar ponteiros é outro fóssil histórico herdado da linguagem B). Assim, não lhe deveria causar qualquer estranheza esse ponto.
Assim, não há qualquer problema de incompatibilidade de tipos: a função tem parâmetros que são ponteiros, e os argumentos usados na invocação da função são ponteiros produzidos por decaimento.

Extremamente importante para mim saber isso e entender, pq passarei a observar isso, pois para mim eles seriam o que estivessem escritos kkkkkkkkk
Obrigado pelas explicações, são de muita utilidade!







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts