Enviado em 12/12/2018 - 09:53h
Pessoal, como eu posso percorrer uma matriz dinamicamente alocada com aritmética de ponteiros?
Desde já Obrigado
Desde já Obrigado
Enviado em 12/12/2018 - 09:53h
Enviado em 12/12/2018 - 20:47h
#include <iostream>Eu acho esquisito, porém pior do que isso, é também perigoso.
int main()
{
int** matrix = new int*[5];
for (int i = 0; i < 5; ++i)
*(matrix+i) = new int[5];
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
std::cout << *(*(matrix+i)+j) << " ";
}
std::cout << "\n";
}
for (int i = 0; i < 5; ++i)
delete[] *(matrix+i);
delete[] matrix;
return 0;
}
std::cout << *(*(matrix+i)+j) << " ";você usasse:
std::cout << *(matrix+i+j) << " ";Coisas terríveis aconteceriam...rs
Enviado em 12/12/2018 - 16:26h
Enviado em 12/12/2018 - 18:44h
id(p){ return p; }
main(){
int v[]={1, 2, 3};
int *a, *b, *c, *d;
a=v+1; /* Aritmética de ponteiro. OK. */
b=id(v)+1; /* Ponteiro se perde. Aritmética com dois inteiros. */
c=id(v+1); /* Aritmética de ponteiros antes da função. Depois o ponteiro se perde. */
d=id(v)+sizeof *v; /* Ponteiro se perde. Valor certo do endereço obtido manualmente. */
printf("%d %d %d %d %d\n", &v[1], a, b, c, d);
printf("%d %d %d %d %d\n", v[1], *a, *b, *c, *d);
} Esse código é obsoleto de várias maneiras mas, em particular, a função id(), que supostamente retorna a mesma coisa que recebe como argumento, não especifica nem o tipo de dados do argumento nem o tipo do dado retornado. Nesse caso, o que acontece é que ambos são assumidos como sendo int. E como, em muitas máquinas antigas (e ainda algumas máquinas atuais), frequentemente int e ponteiros têm a mesma representação interna (que tipicamente coincidia com o tipo dos registradores de uso comum no processador), essa coincidência era assumida como líquida e certa e até como desejável. O compilador não reclamava, e todos eram felizes.$ ./linuxpc32 ; ./linuxpc64
-3798332 -3798332 -3798335 -3798332 -3798332
2 2 33554432 2 2
-755092352 -755092352 -755092355 -755092352 -755092352
Segmentation fault (core dumped)
$ ./solaris32 ; ./solaris64
-4195232 -4195232 -4195235 -4195232 -4195232
Bus Error (core dumped)
2147482408 2147482408 2147482405 2147482408 2147482408
Bus Error (core dumped)
$ ./aix32 ; ./aix64No PC e no Power, as versões em 32 bits funcionaram de modo parecido: como inteiros e ponteiros têm o mesmo tamanho, o programa rodou até o fim, mas produziu endereços diferentes para o ponteiro b de todos os demais, e d só ficou com o valor certo porque fizemos a computação manual. Na impressão dos valores, o obtido através de b ficou diferente dos demais (no PC, cujos dados são com byte menos significativos primeiro, o valor impresso foi o equivalente a 0x02000000, onde o “02” é o primeiro byte do segundo elemento, e os três “00” são os três últimos bytes do primeiro; no AIX, em que o byte mais significativo vem primeiro, o valor impresso foi o equivalente a 0x00000100, em que “000001” corresponde aos três últimos bytes do primeiro elemento, e o “00” vem do primeiro byte do segundo elemento). No processador Sparc, dados não-alinhados provocam erro de barramento, de modo que nenhum dado foi impresso (o programa capota ao tentar fazê-lo), mas apenas os endereços (antes de capotar), com discrepâncias entre si semelhantes às vistas no PC e no Power.
804398476 804398476 804398473 804398476 804398476
2 2 256 2 2
-2972 -2972 -2975 -2972 -2972
Segmentation fault (core dumped)
Enviado em 12/12/2018 - 20:29h
#include <algorithm>Naturalmente eu poderia utilizar também assim que é a mesma coisa:
#include <iostream>
#include <functional>
#include <numeric>
int main()
{
int arr[5];
std::iota(arr, arr+5, 1);
int fatorial5 = std::accumulate(arr, arr+5, 1, std::multiplies<int>{});
std::cout << fatorial5 << std::endl;
return 0;
}
ou simplesmente - o que seria a melhor forma:
std::iota(&arr[0], &arr[5], 1);
Contudo esse &arr[5] (apesar de ser a mesma coisa que arr + 5) além de ter uma verbosidade maior, parece meio estranho ao indicar o acesso ao elemento depois do último do array. Parece que acende uma luz amarela toda vez que leio isso.
std::iota(std::begin(arr), std::end(arr), 1);
Enviado em 12/12/2018 - 21:28h
id(p){ return p; }
main(){
int v[]={1, 2, 3};
int *a, *b, *c, *d;
a=v+1; /* Aritmética de ponteiro. OK. */
b=id(v)+1; /* Ponteiro se perde. Aritmética com dois inteiros. */
c=id(v+1); /* Aritmética de ponteiros antes da função. Depois o ponteiro se perde. */
d=id(v)+sizeof *v; /* Ponteiro se perde. Valor certo do endereço obtido manualmente. */
printf("%d %d %d %d %d\n", &v[1], a, b, c, d);
printf("%d %d %d %d %d\n", v[1], *a, *b, *c, *d);
} $ ./linuxpc32 ; ./linuxpc64
-3798332 -3798332 -3798335 -3798332 -3798332
2 2 33554432 2 2
-755092352 -755092352 -755092355 -755092352 -755092352
Segmentation fault (core dumped)
$ ./solaris32 ; ./solaris64
-4195232 -4195232 -4195235 -4195232 -4195232
Bus Error (core dumped)
2147482408 2147482408 2147482405 2147482408 2147482408
Bus Error (core dumped)
$ ./aix32 ; ./aix64
804398476 804398476 804398473 804398476 804398476
2 2 256 2 2
-2972 -2972 -2975 -2972 -2972
Segmentation fault (core dumped)
Enviado em 13/12/2018 - 11:25h
// Exemplo 1: usando notação de arrays.
int strcmp(const char *s1, const char *s2){
int i, diff;
i=0;
do
diff=s2[i]-s1[i];
while(diff==0 && s1[i] && s2[i++]);
return diff;
}
// Exemplo 2: usando aritmética de ponteiros.
int strcmp(const char *s1, const char *s2){
int diff;
do
diff=*s2-*s1;
while(diff==0 && *s1++ && *s2++);
return diff;
}
Entre na sua conta para responder.