Ir ao conteúdo

Posts recomendados

  • Membro VIP
Postado
// Online C compiler to run C program online
#include <stdio.h>
char *string="0011001";
char num1=0;
int main() {
    // Write C code here
    printf("Uns=");
    while (*string) 
        {
        if (*string=='1') ++num1;
        *string++;    
        }
    printf("%d",num1);
    return 0;
}

Testei em https://www.programiz.com/c-programming/online-compiler/

O preço: entenda e me  explique porquê até hoje não entendo esta porcaria de ponteiros e vetores!! 🤬

😁

  • Curtir 2
  • Obrigado 1
Postado
25 minutos atrás, .if disse:

O preço: entenda e me  explique porquê até hoje não entendo esta porcaria de ponteiros e vetores!!


o computador guarda dados de duas formas...
Em disco e em memoria. No caso da memória, ela tem endereços.

tudo que se salva vai para algum endereço na memoria. Mas quando se faz esses ponteiros, isso significa que nesse momento você tem o interesse em trabalhar com segmentos desses endereços que vão guardar conteudo que deseja.

Qualquer variavel possui endereço namemoria, que pode ser obtido colocando um & na grente. Mas quando você coloca * na frente, está dizendo que irá usar uma sequencia desses endereços pra guardar algo. isso é muito util na programação em c porque você consegue ter uma ordem e saber onde estão cada pedaço das variaveis que guardou porque elas estão em sequencia.

Quando se faz o ponteiro, quer dizer que vai usar uma sequencia desses endereços pra guardar algo. Esse ponteiro vai te ajudar a trabalhar, por exemplo, com strings... que é um vertor (matriz linear, ou array) de char(caracteres).

então, ao fazer algo assim:
char *p = "olá!";

você está reservando na memoria um espaço com 4 chars

Ou assim, também funciona:

tipoDeDado *p;

p = malloc(tamanho);

você reserva um espaço do tamanho (inteiro) que desejar.
OBS: Mas sempre que usar malloc, deve-se lebrar de usar o free antes de terminar o programa, porque se não o espaço vai ficar cheio e sinalizado que não pode ser usado por nenhum outro programa. Esse espaço só vai ser iberado se desligar seu PC e ligar de novo... o que não é muito util. E algo assim, a todo momento, vai fazer o computador ficar mais lento.

Agora, esses segmentos podem ser acessados se você souber pegar o endereço desses ponteiros ou de uma variavel qualuqer. Que é utilizando o caractere '&'.

Então, para qualquer variavel que criar, mesmo que seja ponteiro, se quiser saber onde está essa variavel no endereço de memoria basta fazer isso:



Se quiser, pode fazer endereco++ para pegar o endereço do compartimento seguinte.

int endereco = &p;

que vai lhe dar o endereço do primeiro compartimento do seguimento que criou em *p, por exemplo. No caso se fizer endereço ++, vai para o endereço do caractere 'l' da string olá!.


Bem... é claro que essa é uma explicação muito superficial. Estou certo de que outros podem dar explicações melhores e mais robustas, mas no geral isso funciona pra mim.


 

  • Curtir 2
Postado

@.if Vetor é só um conjunto contíguo de blocos de memória, e daí você pode alocar estática ou dinamicamente...

// alocacao estatica
int x[10];
// alocacao dinamica
int* x = (int*)malloc(10*sizeof(int));

De ambas as formas, reservamos 10 espaços do tamanho de int para uso, e como o nome já diz, se eu precisar mudar o tamanho do vetor dinâmico x, eu posso

x = (int*)realloc(x, 15*sizeof(int));

Aliás, se o tamanho do vetor for uma variável, a declaração de um vetor estático pode não ser efetivada, embora C99 permita esse tipo de coisa.

 

Sobre esse programa que mostrou, alguns comentários devem esclarecer :)

#include <stdio.h>

int main()
{
    /*
    O valor apontado por string eh o
    elemento na posicao 0 da string
    "0011001".
    */
    char *string = "0011001";
    /*
    printf("%c", *string); imprime '0'.
    O * significa valor apontado pelo
    ponteiro. Mude o valor na posicao
    0 da string e veja o que imprime.
    */
    
    char num1 = 0;
    
    printf("Uns = ");
    
    /*
    Strings são vetores de char terminados
    em um caractere nulo ('\0' ou 0), e 0
    eh falso, entao o controle eh transferido
    pra fora do loop quando chegar ao fim da
    string.
    */
    while(*string) 
    {
        /*
        Se o valor apontado pelo ponteiro string
        for '1', incrementa num1.
        */
        if (*string=='1') ++num1;
        
        /*
        Incrementa o ponteiro para que possa
        apontar para a posicao seguinte na memoria
        e consequentemente, para o proximo valor
        na string.
        */
        string++;    
    }
    
    printf("%d", num1);
    
    return 0;
}
  • Curtir 4
  • Membro VIP
Postado

Esqueci de dizer que o programa foi de minha autoria mesmo kk... embora eu acho que deu pra sacar 🤪

 

Eu vejo o vetor ou ponteiro como posição de memória que o compilador ou sistema se vira pra definir pra mim qual é. Algo como: qual o conteúdo do  endereço *tal? P.ex. num sistema que tem 64K digamos que ele defina que a string tem que ficar em no end 40.000 (nem quero saber porquê). Se ela tiver 8 dados (bytes) como no...

17 horas atrás, Ana Carolina Martins disse:

Exemplo: “0011001”

... da garota, vai ocupar de 40.000 a 40.007 + um 0 (zero) como finalizador. Assim sendo string não é o dado propriamente dito mas onde ele está byte a byte. Assim sendo string pode ser de 40.000 a 40.008 mas vai retornar o valor '0' ou '1' apenas (naquele caso). Percebo sim também uma relação entre

*string= “0011001” e string[]={'0','0','1','1','0','0','1'}

Daqui a pouco vou testar pra ver...

Alocações e realocaçṍes não fazem parte do meu pobre micromundo pois trabalho com pisca led com mc de 16 bytes de ram e 128 bytes de flash kk... obs.. nada de assembly .. iéca.. kk 😁

 

Será que acertei algo nesta automicroaula ? 😜

  • Curtir 2
Postado
4 horas atrás, .if disse:

Será que acertei algo nesta automicroaula ? 😜

 

:) Acho que sim 

 

Talvez o mais simples para entender esse lance de variável e ponteiro é a analogia com um envelope. O que o programa acessa está em variáveis. Essas variáveis estão na memória em endereços. Ao declarar
 

    char b = '@';

 

quando seu programa for carregado para rodar vai ter um lugar para esse char b. Esse lugar é um endereço de memória e nesse exemplo tem 32bits, no pular 4 bytes. E Nesse lugar vai estar o valor '@'. Veja esse endereço como um envelope. E o conteúdo é o valor.

 

E ao declarar

 

    char*        p = &b;

 

image.png.d84151a49ab512ee49e3189f6345bf13.pngVocê está reservando um envelope p que vai ter um endereço de um char, e colocando nele o endereço de b. É uma referência indireta. Como ir buscar um carro com o prisma 12 no estacionamento. A cada momento pode ter um carro com esse prisma ou não. O prisma é uma referência, como um ponteiro. E se você imaginar uma relação de prismas associando cada prisma em uso com uma vaga lá no pátio então está na presença de uma analogia para a memória e o programa. 

 

 

 

Um programa exemplo
 

#include <stdio.h>
int main(void)
{
    char string[]    = "0011001";
    char str0[]      = "00000000000";  // 11 + 1
    char str3[]      = "33333333333";
    char strA[]      = "AAAAAAAAAAA";
    char       b     = '@';
    char*      p     = &b;
    printf("%p valor %d\n", &b, b);
    printf("a partir do ponteiro, valor = %d\n", *p );
    return 0;
}

 

Esse complexo programa apenas declara umas strings um char e um ponteiro para char. E faz o ponteiro para char p apontar para o endereço do char b.

 

E o programa mostra o endereço e o valor de b e o valor apontado por p, que deve ser o mesmo...

 

00CFFD0B valor 64
a partir do ponteiro, valor = 64

 

64 é o valor decimal de '@' e está tudo certo.

 

Mas como é isso na memória? 

 

Usando uma ferramenta, eis o conteúdo

 

M1.png.e445ff24f3be7e7ba34fb28bfcb9d0e9.png

 

 

Veja lá em amarelo a tal '@', bem no endereço que o programa mostrou no printf().

 

 

 

 

 

 

 

 

 

m2.jpg.61870fa2cb1ca832aedfb004f46d84a6.jpg

 

E veja as strings logo a seguir...

 

 

Vai reparar que a ordem está invertida em relação ao programa.

 

 

É uma pilha, o tal stack. Onde ficam as variáveis estáticas, as que já foram declaradas e em espeço reservado.

 

 

Mas e o ponteiro p?

 

Como foi declarado por último deve estar lá no começo, antes de b. É uma pilha afinal. E o valor dele é conhecido, já que é o endereço de b que está escrito aí na tela: 0x000CFD0B, claro. Usei compilação em 32 bits para ter um ponteiro pequeno, 4 bytes, 8 digitos hexa.

 

Estará lá?

m3.png.66ccaad7d16164a49fc57eefedd534fb.png

 

 

 

E não é que está? Vejao valor de p lá em laranja, um pouco antes de b, a tal '@'

 

Os bytes estão invertidos por causa do modo que o sistema usa para salvar os valores

 

E o conteúdo de p é o endereço de b.

 

Espero que isso ajude a entender o mecanismo...

 

Porque essa referência? Porque você pode ter serviços que fazem uma mesma coisa a vida toda, como fechar uma conta no restaurante, e você só passa o escaninho do caixa onde estão os pedidos da mesa. O serviço é o mesmo, mas fica mais ágil e reaproveita a área.

 

Ao reocupar a mesa os pedidos da mesa voltam a ser empilhados no mesmo escaninho. Acho que já viu isso em restaurantes... Em C seria um ponteiro para uma struct :) 

 

 

  • Curtir 2
  • Obrigado 1
Postado

@Ana Carolina Martins    a linguagem c não é a mesma linguagem c++ ,  apenas que c++ aceita os comandos da linguagem c , mas são bem diferentes ,  e se você Quer fazer em c++ , então use as bibliotecas de c++ que precisa da

#include <iostream>

using namespace std;

int mai(){

string str = "00011001";            int cont=0     ;

for(int i=0;str[i]!=0 /* i < str.size()*/ ; i++){     cout << str[i] << " "  ;

if(str[i]=='1')cont++              ;

}

    cout << str << " -> " << cont << endl  ;

}

  • Curtir 1
  • Membro VIP
Postado

Ainda sobre ponteiros e vetores que considero entidades tão sinistras como struct e union, permita-me linkar o post...

Certa feita precisei gravar um valor de um float 32 bits na eeprom de um mc de 8 bits. Com um pouco de esforço consegui bolar uma estrutura com struct e union. Compartilhei minha "descoberta" com um amigo Shultz do asm51.com.br e ele me humilhou (saudavelmente claro) com algo ainda mais simples e sinistro. Ele disse que não entendeu como fez aquilo mas que deu certo, deu kk.

Nem tenho certeza se a esta altura quero entender como funciona....😁. Mas fica aí (de novo) a título de curiosidade.

int main( void )
{
float float0;
float *ponteiro;
  
ponteiro = &float0; 
  
float0=3.141592;

//grava os pedaços na eeprom
eepw(0,*((unsigned char *)(ponteiro)+0)); //grava 8 bits
eepw(1,*((unsigned char *)(ponteiro)+1)); 
eepw(2,*((unsigned char *)(ponteiro)+2)); 
eepw(3,*((unsigned char *)(ponteiro)+3)); 

float0=0; //destroi

//reconstroi float0 a partir dos pedaços da eeprom
*((unsigned char *)ponteiro + 0)=eepr(0); //retorna 8 bits
*((unsigned char *)(ponteiro)+1)=eepr(1);
*((unsigned char *)(ponteiro)+2)=eepr(2);
*((unsigned char *)(ponteiro)+3)=eepr(3);
  
pi=float0; //taí

de novo.. oriundo de meu mundinho 8 bits 🙃

  • Curtir 1

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...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!