Ir ao conteúdo

C++ Enviar endereço de memoria do vetor para função e QListWidget ( QTCREATOR + C++)


Ir à solução Resolvido por arfneto,

Posts recomendados

Postado

 

Boa noite!!

 

 

Eu to precisando de uma ajuda para entender como funciona o qtcreator e C++:

 

//C++// 

eu to com uma dúvida sobre utilização de vetor + funções, veja o código:

 

// variavel global:
	int vetor[23];

void teste (int *vetor){
	for (int i = 0 ; i < 23 ; i ++){
             *(vetor+1) = 1;              
                           }
}
                           
    teste(vetor);

 

eu to tentando mandar p/ função o endereço do vetor desta maneira mas não tá funcionando.

 

 

// QTCREATOR // 

 

      Alguem tem uma recomendação de tutorial legal para ensinar a mexer em QListWidget????

 

 

     Não dá pra utilizar o this em outra função?

 

image.png.7b2af8e9fc9d7def73de163cfd9abc62.png

  • Obrigado 1
Postado
2 horas atrás, Luís Roberto C. da Silva disse:

Pra enviar o endereço da memória tem que ser assim:


teste(&vetor);

 

 

Criei um projeto de console no QT com o código para testar:

 

#include <iostream>
#include <QCoreApplication>
using namespace std;

void teste(int *vetor){
    cout << "entrou na função";
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

       int vet[3];

       for(int i = 0; i < 3 ; i++){
           vet[i] = 59;
       }

       teste(&vet);
    return a.exec();
}

 

 

a saída foi:

Citação

image.thumb.png.fe2bc0691a9c4c3df5e7b938a3038200.png

 

 

/////////////////////////////////////////////////////////////////////////

 

Eu só consegui enviar o endereço do vetor sem o &...

 

  • Obrigado 1
  • Solução
Postado
Em 05/10/2019 às 10:41, Luís Roberto C. da Silva disse:

void teste(int *vetor[]){

 

Olá. Ainda está bem errado :( 

 

Note que o argumento da função não é apenas um vetor: é um vetor de ponteiros para int.

Então quando chega em teste() ...

void teste(int *a[])
{ 
   printf("%d", *a);
}

*a é do tipo int[]

e está errado o printf(). Como você disse e declarou, vetor é um vetor, então podia ser, para imprimir o primeiro

    printf("%d", (*a)[0]);

 

Agora em main() também está errado...

    a[0] = 1;

Veja, você declarou vetor como int*[] na função: vetor é um vetor de ponteiros para int. Então você atribuir um valor a ele por sua conta é quase sempre um erro e vai cancelar seu programa.

 

Ao invés disso:
 

int main(void)
{ 
int a[1]; 
    a[0] = 1; 
    teste(&a); 
    return 0; 
}

Escreva assim:

int main(void) {
    int* a[1];

    std::cout << ":) testando teste()" << std::endl;

    a[0] = new(int);
    *a[0] = 12345678;
    teste(a);

    std::cout << std::endl << "deve ter mostrado... " << *a[0] << std::endl;
    free(a[0]);	// melhor se acostumar a liberar tudo que aloca
    return 0;
}    // end main()

E verá isso

:) testando teste()
12345678
deve ter mostrado... 12345678

Use seu programa para testar seu programa...

 

 
adicionado 17 minutos depois

Por outro lado, pela documentação de QListWidget() essa função só tem um parâmetro, que é o endereço da parent window, do tipo QWidget()

QListWidget(QWidget *parent = nullptr)

e pode ou deve ser declarado como nullptr

 

De volta ao programa, não custa nada deixar um teste inteiro

#include <iostream>
#include <stdio.h>


void teste(int* a[])
{
    printf("%d", (*a)[0]);
    return;
}    // end teste()


int main(void) {
    int* a[1];

    std::cout << ":) testando teste()" << std::endl;
    a[0] = new(int);
    *a[0] = 12345678;
    teste(a);
    std::cout << std::endl << "deve ter mostrado... " << *a[0] << std::endl;
    free(a[0]);
    return 0;
}    // end main()

 

  • Obrigado 1
  • Amei 1
Postado

@arfneto Muito obrigado como sempre pelas ótimas respostas. 

 

Sobre o objeto QListWidget do QT Creator eu queria saber o seguinte:

 

Citação

É possível habilitar multi-seleção de itens  neste objeto?

 

 

To criando o seguinte programa:

 

Citação

image.png.4b4d22fdc8909f1620e92f2e0ac7310c.png

 

É um programa referente a um trabalho da faculdade que eu fiz com C e agora to aproveitando ele para aprender QTCreator e C++.

 A ideia é:

A pessoa seleciona a posição (JANELA ou CORREDOR) e depois a quantidade de assentos e no final tem que selecionar os assentos para efetivar a comprar.

E nisso tem algumas condições a serem satisfeitas, mas a principal é essa:

  • A qtd de assentos selecionados deve satisfazer a quantidade de  assentos definidos.

Da maneira atual, só é possível selecionar um item de cada vez na lista de itens (QListWidget) e eu queria habilitar uma seleção multipla de itens.

image.png.66bad2ae5db81b55d751a3a6b99c93b4.png

 

 

Enquanto isso eu vou pesquisando na documentação do qt.io, dar uma treinada no inglês haha

 

 

EDITT:

 

Encontrei o seguinte método que eu posso colocar no Constructor :

 

ui->QListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

image.png.287d6b8dfff053bc95eaee9ed22e6652.png

 

 

Agora consigo selecionar mais de um item. Mas só apertando CTRL... 🤔🤔

  • Curtir 1
Postado

Olá

 

Control e Shift são os modificadores comuns no Windows e no Linux para seleção. Veja numa pasta de arquivos no Windows Explorer por exemplo: ao selecionar um elemento e depois ao selecionar um segundo apertando shift seleciona o intervalo todo entre eles. E com Control seleciona um a um. é muito comum ao selecionar fotos por exemplo nas pastas de imagens.

 

No seu caso deve ser possível manipular a seleção no evento que trata o click nas células da lista... Talvez deva abrir outro tópico pra ver se alguém já fez isso...

 

De volta ao tópico, só duas notas:

Em declarações como

  • int *a[]

    Você começa a ler da direita para a esquerda na hora de preparar os parâmetros. Eu sempre acho mais claro declarar 

int* a[];

Para deixar claro de a[] é do tipo int* e nunca misturo declarações de ponteiros com variáveis normais.

Nesse caso você lê, da direita para a esquerda

  • colchetes: então tem um vetor a esquerda --- tem uma exceção aqui, como no caso do new(type[]) mas não é assunto para esse tópico: trata-se da sobrecarga do operador [] .
  • depois vem a variável a, que então é o vetor
  • depois vem o asterisco, então a é um vetor de ponteiros
  • depois vem int, e aí se vê que é um vetor de ponteiros para int

Note a versão abaixo do mesmo programa de teste que postei, desta vez sem usar a notação [ ]

#include <iostream>
#include <stdio.h>

void teste(int**    a)
{
    printf("%d", **a);
    return;
}    // end teste()


int main(void)
{
    int** a;

    std::cout << ":) testando teste()" << std::endl;

    a = new(int*[1]);     // um vetor, mas de um so
    *a = new(int);        // aloca o primeiro
    **a = 12345678;       // usa o primeiro

    teste(a);

    std::cout << std::endl << "deve ter mostrado... " << *a[0] << std::endl;

    free(*a);    // libera o primeiro
    free(a);     // libera o vetor

    return 0;
}    // end main()

Esta é a maneira mais comum de usar isso, ou de ler isso, quando se usa esses frameworks tipo SDL ou Qt ou GTK+ e coisas assim. Em geral não se vê colchetes misturados com *. O resultado, claro, é o mesmo.

 

  • Curtir 2
Postado
Em 07/10/2019 às 01:33, arfneto disse:

Olá

 

Control e Shift são os modificadores comuns no Windows e no Linux para seleção. Veja numa pasta de arquivos no Windows Explorer por exemplo: ao selecionar um elemento e depois ao selecionar um segundo apertando shift seleciona o intervalo todo entre eles. E com Control seleciona um a um. é muito comum ao selecionar fotos por exemplo nas pastas de imagens.

 

No seu caso deve ser possível manipular a seleção no evento que trata o click nas células da lista... Talvez deva abrir outro tópico pra ver se alguém já fez isso...

 

De volta ao tópico, só duas notas:

Em declarações como

  • 
    int *a[]

    Você começa a ler da direita para a esquerda na hora de preparar os parâmetros. Eu sempre acho mais claro declarar 


int* a[];

Para deixar claro de a[] é do tipo int* e nunca misturo declarações de ponteiros com variáveis normais.

Nesse caso você lê, da direita para a esquerda

  • colchetes: então tem um vetor a esquerda --- tem uma exceção aqui, como no caso do new(type[]) mas não é assunto para esse tópico: trata-se da sobrecarga do operador [] .
  • depois vem a variável a, que então é o vetor
  • depois vem o asterisco, então a é um vetor de ponteiros
  • depois vem int, e aí se vê que é um vetor de ponteiros para int

Note a versão abaixo do mesmo programa de teste que postei, desta vez sem usar a notação [ ]


#include <iostream>
#include <stdio.h>

void teste(int**    a)
{
    printf("%d", **a);
    return;
}    // end teste()


int main(void)
{
    int** a;

    std::cout << ":) testando teste()" << std::endl;

    a = new(int*[1]);     // um vetor, mas de um so
    *a = new(int);        // aloca o primeiro
    **a = 12345678;       // usa o primeiro

    teste(a);

    std::cout << std::endl << "deve ter mostrado... " << *a[0] << std::endl;

    free(*a);    // libera o primeiro
    free(a);     // libera o vetor

    return 0;
}    // end main()

Esta é a maneira mais comum de usar isso, ou de ler isso, quando se usa esses frameworks tipo SDL ou Qt ou GTK+ e coisas assim. Em geral não se vê colchetes misturados com *. O resultado, claro, é o mesmo.

 

O mesmo nao acontece com matriz?

 

image.png.065b26159cddc9565711ee10b0e69ddc.png

  • Curtir 1
Postado

A resposta curta é sim. Mas o que é uma matriz? Como eu disse, você deve ler a declaração da direita para a esquerda. E como eu sugeri, em muitos casos ou se usa * ou se usa [] mas não os dois.

 

Não que seja errado. Mas em código de produçào --- como código de frameworks, bibliotecas famosas e tal --- é mais comum ver apenas os asteriscos

 

Na tela que mostrou está um protótipo, mas onde está o código de teste()?

  • Curtir 2
Postado
Em 12/10/2019 às 14:16, arfneto disse:

A resposta curta é sim. Mas o que é uma matriz? Como eu disse, você deve ler a declaração da direita para a esquerda. E como eu sugeri, em muitos casos ou se usa * ou se usa [] mas não os dois.

 

Não que seja errado. Mas em código de produçào --- como código de frameworks, bibliotecas famosas e tal --- é mais comum ver apenas os asteriscos

 

Na tela que mostrou está um protótipo, mas onde está o código de teste()?

 

Ainda ficou abstrato pra mim, tentei fazer de uma maneira que eu entedesse e cheguei nisso: 


#include <stdio.h>
#include <string.h>


void teste(int* t){

int cont = 0;

    for(int i = 0 ; i < 25 ; i++){
        if(cont == 4){
            cont = 0;
            printf("%i\n", *(t+i));
        }else{
            printf("%i", *(t+i));
        cont++;
        }
    }
}
int main(){

    int a[5][5];

    for(int i = 0 ; i < 5; i++){
        for(int j = 0 ; j < 5 ; j++){
            a[i][j] = 1;
        }
    }

    teste(a);

    return 0;

}

 

Postado
2 horas atrás, Reberth Siqueira disse:

 

Ainda ficou abstrato pra mim, tentei fazer de uma maneira que eu entedesse e cheguei nisso: 



#include <stdio.h>
#include <string.h>


void teste(int* t){

int cont = 0;

    for(int i = 0 ; i < 25 ; i++){
        if(cont == 4){
            cont = 0;
            printf("%i\n", *(t+i));
        }else{
            printf("%i", *(t+i));
        cont++;
        }
    }
}
int main(){

    int a[5][5];

    for(int i = 0 ; i < 5; i++){
        for(int j = 0 ; j < 5 ; j++){
            a[i][j] = 1;
        }
    }

    teste(a);

    return 0;

}

 

 

:)  Agora está meio abstrato pra mim.... Podia explicar o que pretende fazer comentando seu próprio código. Mas agora tem o código de teste() também e imagino que queira imprimir a, 5x5 linha a linha.

Vou insistir sobre o que falei de ler da direita para a esquerda. Veja aquele teste que te mostrei do programa que imprime 12345678 e o que escrevi e me diga se entende aquilo e tento explicar de outro  modo se preciso.

 

Em relação a esse código aqui: sua rotina teste() não retorna nada --- void --- e recebe um único argumento t, um ponteiro para int.

Quando você chama teste() em seu programa usa teste(a) então seria razoável achar que a é do tipo int*. Só que não é: Declarou 

int a[5][5];

Pense nisso. Depois te mostro as alternativas.

 

  • Amei 1
Postado
17 horas atrás, arfneto disse:

 

:)  Agora está meio abstrato pra mim.... Podia explicar o que pretende fazer comentando seu próprio código. Mas agora tem o código de teste() também e imagino que queira imprimir a, 5x5 linha a linha.

Vou insistir sobre o que falei de ler da direita para a esquerda. Veja aquele teste que te mostrei do programa que imprime 12345678 e o que escrevi e me diga se entende aquilo e tento explicar de outro  modo se preciso.

 

Em relação a esse código aqui: sua rotina teste() não retorna nada --- void --- e recebe um único argumento t, um ponteiro para int.

Quando você chama teste() em seu programa usa teste(a) então seria razoável achar que a é do tipo int*. Só que não é: Declarou 


int a[5][5];

Pense nisso. Depois te mostro as alternativas.

 

Cara, muito obrigado!!! Deu tudo certo agora, eu não estava entendendo o que você tinha explicado sobre vetor de ponteiros, que tinha que usar um new(type{float,int, etc}). Agora tudo faz sentido e deu tudo certo! Eu achava que o método de new(int) só funcionava com c++...

 

 

adicionado 0 minutos depois

Prometo que nas próximas eu vou comentar o código!!!!

adicionado 0 minutos depois

mt obrigado pela paciencia @arfneto

Postado
46 minutos atrás, Reberth Siqueira disse:

Deu tudo certo agora, eu não estava entendendo o que você tinha explicado sobre vetor de ponteiros, que tinha que usar um new(type{float,int, etc}). Agora tudo faz sentido e deu tudo certo! Eu achava que o método de new(int) só funcionava com c++

 

Muito bom que funcionou! Parabéns.

 

Não entendi o que disse sobre new(type) e tal. De fato em C não se usa isso mas sim malloc() e free(). E isso não ia ajudar em seu teste de todo modo porque lá está usando alocação estática. Em C++ se usa new() delete e delete[]

 

Note que esses vetores multidimensionais em C são mesmo um pesadelo. E quase isso em outras linguagens também. Na declaração se vai usar mesmo [] deve deixar o primeiro em branco como 

int func( int vetor2D [][5] );

Note que os valores são alocados em sequencia na memória, uma coluna por vez, e  C e C++ tem aritmética de ponteiros então em geral é muito mais tranquilo esquecer tudo isso e usar ponteiros

 

  • Curtir 1
Postado

Olá!

 

De uma olhada no programa C abaixo, que mostra isso


imprime vetor na ordem de endereco. Tam 12

(int [12])

 0  1  2  3  4  5  6  7  8  9 10 11

imprime vetor na ordem de endereco. Tam 12

(int [2][6])

12 13 14 15 16 17
18 19 20 21 22 23

imprime vetor na ordem de endereco. Tam 12

(int [3][4])

24 25 26 27
28 29 30 31
32 33 34 35

imprime vetor na ordem de endereco. Tam 25

(int [5][5])

36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
51 52 53 54 55
56 57 58 59 60

********** ********** ********** **********
Usando os enderecos como parametro


imprime vetor na ordem de endereco. Tam 12

(int [12])

 0  1  2  3  4  5  6  7  8  9 10 11

imprime vetor na ordem de endereco. Tam 12

(int [2][6])

12 13 14 15 16 17
18 19 20 21 22 23

imprime vetor na ordem de endereco. Tam 12

(int [3][4])

24 25 26 27
28 29 30 31
32 33 34 35

imprime vetor na ordem de endereco. Tam 25

(int [5][5])

36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
51 52 53 54 55
56 57 58 59 60

Ele imprime duas vezes a mesma coisa usando essas duas rotinas

void mostra(int v[], int t, int col, char* mensagem)
{
    printf("\nimprime vetor na ordem de endereco. Tam %d\n", t);
    printf("\n(%s)\n\n", mensagem);
    for (int i = 0; i < t; i++)
    {
        printf("%2d ", v[i]);
        if (i % col == col - 1)
            printf("\n");
    }    // end for
}    // end mostra

E essa

void mostra_e(int* v, int t, int col, char* mensagem)
{
    printf("\nimprime vetor na ordem de endereco. Tam %d\n", t);
    printf("\n(%s)\n\n", mensagem);
    for (int i = 0; i < t; i++)
    {
        printf("%2d ", *(i+v) );
        if (i % col == col - 1)
            printf("\n");
    }    // end for
}    // end mostra_e()

Para vetores de 12 posições declarados como [12] ou [2][6] ou [3][4]. Para a primeira rotina o compilador reclama de tudo mas funciona. Para a segunda não há problema graças a  um cast na chamada. Veja:

    mostra(v12, 12, 12, "int [12]");
    mostra(v_2_6, 12, 6, "int [2][6]");
    mostra(v_3_4, 12, 4, "int [3][4]");
    mostra(a, 25, 5, "int [5][5]");

    mostra_e((int*) v12, 12, 12, "int [12]");
    mostra_e((int*)v_2_6, 12, 6, "int [2][6]");
    mostra_e((int*)v_3_4, 12, 4, "int [3][4]");
    mostra_e((int*)a, 25, 5, "int [5][5]");

Eis o programa

#define _CRT_SECURE_NO_WARNINGS

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


void mostra(int v[], int t, int col, char* mensagem)
{
    printf("\nimprime vetor na ordem de endereco. Tam %d\n", t);
    printf("\n(%s)\n\n", mensagem);
    for (int i = 0; i < t; i++)
    {
        printf("%2d ", v[i]);
        if (i % col == col - 1)
            printf("\n");
    }    // end for
}    // end mostra


void mostra_e(int* v, int t, int col, char* mensagem)
{
    printf("\nimprime vetor na ordem de endereco. Tam %d\n", t);
    printf("\n(%s)\n\n", mensagem);
    for (int i = 0; i < t; i++)
    {
        printf("%2d ", *(i+v) );
        if (i % col == col - 1)
            printf("\n");
    }    // end for
}    // end mostra_e()


int main() {


    int v12[12];

    for (int i = 0; i < 12; i++)
    {
        v12[i] = i;
    };


    int v_2_6[2][6];

    for (int i = 0, k = 12; i < 2; i++)
    {
        for (int j = 0; j < 6; j += 1)
        {
            v_2_6[i][j] = k++;
        }
    };


    int v_3_4[3][4];

    for (int i = 0, k = 24; i < 3; i++)
    {
        for (int j = 0; j < 4; j += 1)
        {
            v_3_4[i][j] = k++;
        }
    };

    // agora a matriz a[5][5]

    int        a[5][5];

    for (int i = 0, k = 36; i < 5; i++)
    {
        for (int j = 0; j < 5; j += 1)
        {
            a[i][j] = k++;
        }
    };

    mostra(v12, 12, 12, "int [12]");
    mostra(v_2_6, 12, 6, "int [2][6]");
    mostra(v_3_4, 12, 4, "int [3][4]");
    mostra(a, 25, 5, "int [5][5]");

    printf("\n********** ********** ********** ********** \n");
    printf("Usando os enderecos como parametro\n\n");

    mostra_e((int*) v12, 12, 12, "int [12]");
    mostra_e((int*)v_2_6, 12, 6, "int [2][6]");
    mostra_e((int*)v_3_4, 12, 4, "int [3][4]");
    mostra_e((int*)a, 25, 5, "int [5][5]");

    return 0;
}

Pense nisso e escreva de novo

Postado
17 horas atrás, arfneto disse:

Não entendi o que disse sobre new(type) e tal

Eu quis dizer que eu entendi que eu tenho que dizer pro compilador que a[0]  vai ser um ponteiro para int (a[0] = new(int)). é isto né?

 

17 horas atrás, arfneto disse:

De fato em C não se usa isso mas sim malloc() e free()

Atualmente a função malloc() tem me causado um medo, ainda não parei pra estudar ela, mas os códigos de exemplo que eu vi eu não entendi nada kk Alias eu teria que usar o malloc()  se eu não quiser que a prof zere meu trabalho kk

 

17 horas atrás, arfneto disse:

C e C++ tem aritmética de ponteiros então em geral é muito mais tranquilo esquecer tudo isso e usar ponteiros

Por isso que eu não estava entendendo kk

adicionado 20 minutos depois
16 horas atrás, arfneto disse:

 mostra_e((int*) v12, 12, 12, "int [12]");

Então essa é a forma correta de enviar vetores em forma de ponteiros para uma função?

 

@@@@@@@@@@@@@@@@@

Então cara, tentei fazer o mesmo método do código acima para matriz e não foi. Quando se trata de matriz teria que usar malloc() mesmo né?!

 

Postado
12 horas atrás, Reberth Siqueira disse:

Eu quis dizer que eu entendi que eu tenho que dizer pro compilador que a[0]  vai ser um ponteiro para int (a[0] = new(int)). é isto né?

Não

E aquilo que eu sempre falo de ler a partir da direita?

 

Se declarou int a[4] por exemplo então... Tem os colchetes a direita indicando que é um vetor depois vem a o nome e int o tipo então a[4] é claro um int como esta escrito

 

E não pode usar new

 

Mesmo porque em C não existe new() nem delete () que são os operadores de alocação e memória em c++

 

Em c se usa como eu disse malloc() e free()

adicionado 7 minutos depois
12 horas atrás, Reberth Siqueira disse:

Então essa é a forma correta de enviar vetores em forma de ponteiros para uma função?

Não. Não é.  Tudo depende de como foi declarado.

Instalou o programa que escrevi na sua máquina? Rodou aquilo? É importante pra ajudar a entender

 

Uma coisa é você declarar int* a[4] outra coisa é declarar int a[4]

Quando você declara int a[4] quer dizer que vai reservar 4 int a partir do endereço de a

Quando você declara int* a[4] quer dizer que você vai reservar 4 ponteiros para int, todos y enfileirados a partir do endereço do primeiro, a

 

Deve ler da direita para a esquerda para entender

adicionado 12 minutos depois
12 horas atrás, Reberth Siqueira disse:

Então cara, tentei fazer o mesmo método do código acima para matriz e não foi. Quando se trata de matriz teria que usar malloc() mesmo né?!

O que eu tentei te mostrar naquele código é que uma mesma área de 12 int pode ser acessada como vetor [12] ou vetor[2][6] ou vetor [3][4] ou qualquer coisa

 

Entenda que os valores são simplesmente enfileirados a partir do endereço inicial. E o que eu tentava mostrar com o programa

adicionado 46 minutos depois

Quando você declara algo como coisa* matriz [4] está indicando que matriz é um vetor de 4 posições e em cada posição vai ter um ponteiro, um endereço para coisa. Claro, todos os ponteiros tem o mesmo tamanho então você pode fazer com que ele aponte para outras "coisas" :D usando o que se chama cast. Exemplo : int* p = (int*) matriz [3] é perfeitamente legal em C ou C++

 

Mas você não está alocando nada aí. Apenas manipulando os endereços.

 

Vamos chamar de matriz então um vetor de duas dimensões. Quando você declara um trem desses, por exemplo int matriz [3][5] está declarando int não ponteiros. Leia da direita para a esquerda

 

São quinze int e eles vão estar lá na memória, um depois do outro. Primeiro os cinco da linha zero depois os cinco da linha um depois os cinco da linha dois IMPORTANTE isso.

 

Então matriz[1][2] vai ser o oitavo cidadão a partir do início. A memória só tem uma dimensão. É o início é o endereço do primeiro. no geral

(X, Y) = (X*largura) + Y é a fórmula que converte o endereço 2D tipo [1][2] no deslocamento linear X a partir do início do vetor na memória. Veja no exemplo matriz [1][2] para matriz declarada como int matriz [3][5] vai estar na posição 1*5 + 2 = 7 a oitava posição a partir do início...

 

Só que todos os quinze  são INT e o endereço do primeiro é o matriz [0][0] ou simplesmente matriz  e C entende essas operações

 

Então se você tiver o endereço do primeiro pode percorrer a matriz usando... Aritmética.

 

Ex:

 int* p = matriz;

*(p+7) = 345;

 

Isso faz com que matriz [1][2] = 345;

 

Entendeu? Não desista. É absolutamente essencial entender isso se quer ser produtivo nessas linguagens. Coisas como Qt, SQL, estruturas como listas e árvores, tudo isso só faz sentido se entender esse paradigma

  • Curtir 1
Postado
Em 15/10/2019 às 14:07, arfneto disse:

Não

E aquilo que eu sempre falo de ler a partir da direita?

 

Se declarou int a[4] por exemplo então... Tem os colchetes a direita indicando que é um vetor depois vem a o nome e int o tipo então a[4] é claro um int como esta escrito

 

E não pode usar new

 

Mesmo porque em C não existe new() nem delete () que são os operadores de alocação e memória em c++

 

Em c se usa como eu disse malloc() e free()

adicionado 7 minutos depois

Não. Não é.  Tudo depende de como foi declarado.

Instalou o programa que escrevi na sua máquina? Rodou aquilo? É importante pra ajudar a entender

 

Uma coisa é você declarar int* a[4] outra coisa é declarar int a[4]

Quando você declara int a[4] quer dizer que vai reservar 4 int a partir do endereço de a

Quando você declara int* a[4] quer dizer que você vai reservar 4 ponteiros para int, todos y enfileirados a partir do endereço do primeiro, a

 

Deve ler da direita para a esquerda para entender

adicionado 12 minutos depois

O que eu tentei te mostrar naquele código é que uma mesma área de 12 int pode ser acessada como vetor [12] ou vetor[2][6] ou vetor [3][4] ou qualquer coisa

 

Entenda que os valores são simplesmente enfileirados a partir do endereço inicial. E o que eu tentava mostrar com o programa

adicionado 46 minutos depois

Quando você declara algo como coisa* matriz [4] está indicando que matriz é um vetor de 4 posições e em cada posição vai ter um ponteiro, um endereço para coisa. Claro, todos os ponteiros tem o mesmo tamanho então você pode fazer com que ele aponte para outras "coisas" :D usando o que se chama cast. Exemplo : int* p = (int*) matriz [3] é perfeitamente legal em C ou C++

 

Mas você não está alocando nada aí. Apenas manipulando os endereços.

 

Vamos chamar de matriz então um vetor de duas dimensões. Quando você declara um trem desses, por exemplo int matriz [3][5] está declarando int não ponteiros. Leia da direita para a esquerda

 

São quinze int e eles vão estar lá na memória, um depois do outro. Primeiro os cinco da linha zero depois os cinco da linha um depois os cinco da linha dois IMPORTANTE isso.

 

Então matriz[1][2] vai ser o oitavo cidadão a partir do início. A memória só tem uma dimensão. É o início é o endereço do primeiro. no geral

(X, Y) = (X*largura) + Y é a fórmula que converte o endereço 2D tipo [1][2] no deslocamento linear X a partir do início do vetor na memória. Veja no exemplo matriz [1][2] para matriz declarada como int matriz [3][5] vai estar na posição 1*5 + 2 = 7 a oitava posição a partir do início...

 

Só que todos os quinze  são INT e o endereço do primeiro é o matriz [0][0] ou simplesmente matriz  e C entende essas operações

 

Então se você tiver o endereço do primeiro pode percorrer a matriz usando... Aritmética.

 

Ex:

 int* p = matriz;

*(p+7) = 345;

 

Isso faz com que matriz [1][2] = 345;

 

Entendeu? Não desista. É absolutamente essencial entender isso se quer ser produtivo nessas linguagens. Coisas como Qt, SQL, estruturas como listas e árvores, tudo isso só faz sentido se entender esse paradigma

Acho que não entendi 100%, mas no que eu estava errando eu entendi. Tirei o resto dos dias da semana para refletir e ir testando. Eu fazia muita confusão, agora está tudo mais claro. Quaisquer outras dúvidas eu mando uma msg.

 

Obrigado

Postado

Rodou o programa que te mostrei?

Entendeu porque a rotina funciona igual para várias configurações dos doze int na memória? tipo 2x6 1x12, 3x4?

Entendeu a diferença entre as duas versões mostra() e mostra_e() naquele programa?

Se não entendeu 100% então deve ter alguma pergunta...

Arrumou seu código para a tal matriz?

  • Curtir 1
Postado
22 horas atrás, arfneto disse:

Rodou o programa que te mostrei?

Entendeu porque a rotina funciona igual para várias configurações dos doze int na memória? tipo 2x6 1x12, 3x4?

Entendeu a diferença entre as duas versões mostra() e mostra_e() naquele programa?

Se não entendeu 100% então deve ter alguma pergunta...

Arrumou seu código para a tal matriz?

Entendi sim. No final, eu percebi que no meu caso, eu não preciso utilizar ponteiro para trabalhar com matriz fora da função main. E então eu coloquei:

 

void teste(int mat[10][10]){

      for(int i = 0; i < 10 ; i++){
         for(int j = 0 ; j < 10 ; j++){
              printf("%i",mat[i][j]);
					}
                          }
}

int main(){
 
  int mat[10][10];
    
  for(int i = 0 ; i < 10 ; i++){
  	for(int j = 0 ; j < 10 ; j++){
    	mat[i][j] = i;
    }
  }
  
  teste(mat);
  return 0;
}

 

Postado
23 horas atrás, Reberth Siqueira disse:

No final, eu percebi que no meu caso, eu não preciso utilizar ponteiro para trabalhar com matriz fora da função main

 

Muito bem.

 

Note que não é que você não precise: você não tem alternativa. É isso que passa de todo modo: o endereço de início da estrutura. Se declarar igual dos dois lados então vai funcionar. Só que nem sempre você pode fazer isso. Pensou mesmo no programa que te mostrei? Rodou aquilo? Lá você pode ver que a mesma área de 12 int pode ser vista como matriz[12] ou matriz[2][6] ou matriz[3][4] e tal...

Postado
2 horas atrás, arfneto disse:

 

Muito bem.

 

Note que não é que você não precise: você não tem alternativa. É isso que passa de todo modo: o endereço de início da estrutura. Se declarar igual dos dois lados então vai funcionar. Só que nem sempre você pode fazer isso. Pensou mesmo no programa que te mostrei? Rodou aquilo? Lá você pode ver que a mesma área de 12 int pode ser vista como matriz[12] ou matriz[2][6] ou matriz[3][4] e tal...

entendi sim.

 

Eu tinha notado isso no começo, até montei um teste pra mostrar pra você e ver se estava certo. Só que eu achava que tava errado kkk

 

vide:

 

Em 13/10/2019 às 22:23, Reberth Siqueira disse:

Ainda ficou abstrato pra mim, tentei fazer de uma maneira que eu entedesse e cheguei nisso: 



#include <stdio.h>
#include <string.h>


void teste(int* t){

int cont = 0;

    for(int i = 0 ; i < 25 ; i++){
        if(cont == 4){
            cont = 0;
            printf("%i\n", *(t+i));
        }else{
            printf("%i", *(t+i));
        cont++;
        }
    }
}
int main(){

    int a[5][5];

    for(int i = 0 ; i < 5; i++){
        for(int j = 0 ; j < 5 ; j++){
            a[i][j] = 1;
        }
    }

    teste(a);

    return 0;

}

 

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!