Leandro Fróes Postado Fevereiro 15, 2018 em 16:46 Compartilhar Postado Fevereiro 15, 2018 em 16:46 Boa tarde galera, um tempo atrás fiquei com uma dúvida e tanto sobre ponteiros, principalmente com um uso em específico. Tendo isso em mente decidi jogar aqui pra vocês testarem e pensarem, acho que vai ser legal pra geral aprender. P.S Não usem o google, testem - Qual a diferença entre (*p) e *p? Só será validada a resposta daquele que mostrar o código e o pq, sem compromisso galera, apenas pra descontrair Abraços! Link para o comentário Compartilhar em outros sites More sharing options...
kassane Postado Fevereiro 17, 2018 em 15:09 Compartilhar Postado Fevereiro 17, 2018 em 15:09 *p = valor da posição de memoria; (*p) = valor da posição da posição de memória neste caso usando um array/vetor void f() { int v[] = {1, 2, 3}, x=24; int * p= NULL; p = &x; std::cout << *p << "!\n"; //output o valor de x = 24 std::cout << (*v)+1 << "!\n"; //output 2 } PS: Caso eu tenha dito besteira favor me corrija! Link para o comentário Compartilhar em outros sites More sharing options...
Leandro Fróes Postado Fevereiro 17, 2018 em 16:30 Autor Compartilhar Postado Fevereiro 17, 2018 em 16:30 1 hora atrás, kassane disse: *p = valor da posição de memoria; (*p) = valor da posição da posição de memória neste caso usando um array/vetor void f() { int v[] = {1, 2, 3}, x=24; int * p= NULL; p = &x; std::cout << *p << "!\n"; //output o valor de x = 24 std::cout << (*v)+1 << "!\n"; //output 2 } PS: Caso eu tenha dito besteira favor me corrija! Opa, na verdade *p aponta para o conteúdo do endereço que tem dentro de p, como ai foi um vetor ele aponta para o endereço do primeiro elemento do vetor. Se você fizer (*v)+1 ele vai pegar o primeiro elemento e somar 1 e não andar uma posição. Ai deu certo porque 1+1 da 2 . Exemplo: #include <stdio.h> int main(){ int v[] = {10,20,30}; int *p = v; printf("Segunda posicao do vetor: %d\n", (*p)+2); return 0; } user@user:/home# ./test Segunda posicao do vetor: 12 Mas o caminho pra achar a resposta é esse mesmo: arrays. Vou esperar mais um tempo antes de postar a resposta. Abraço! Link para o comentário Compartilhar em outros sites More sharing options...
Leandro Fróes Postado Fevereiro 25, 2018 em 04:40 Autor Compartilhar Postado Fevereiro 25, 2018 em 04:40 Queria deixar uma pergunta interessante para se pensar antes de resolver o desafio. Considerando o ponteiro p: O que acontece se usarmos p++? E quando se usa (*p)++? Tente aplicar em um array e veja seus elementos =D Abraço! Link para o comentário Compartilhar em outros sites More sharing options...
Pimptech Postado Fevereiro 25, 2018 em 07:42 Compartilhar Postado Fevereiro 25, 2018 em 07:42 Falai, Leandro! Bele ? Legal essa questão, trabalhar com pointeiro é tenso. Nada melhor que treinar ;p Nesse caso, se printarmos o "p++" direito no printf o valor não irá mudar. Pois o operador ++ usado após a variável só incrementado depois de valor de p ser mostrado no print. Ou seja, no print ele n muda. Porém se você usar o operador antes da variável ++p ele primeiro soma o valor de p para então usá-lo. No caso de p++ ele irá acrescentar o tamanho do ponteiro p. Se for int em 32bit endereço de p + 4. No caso do (*p)++ é o mesmo lance do operador, mas nesse caso ele soma o valor contido no primeiro elemento do array. Vale ressaltar que o parentes são opcionais, não muda em nada. Abraço! ;]] Link para o comentário Compartilhar em outros sites More sharing options...
gzn Postado Fevereiro 25, 2018 em 13:31 Compartilhar Postado Fevereiro 25, 2018 em 13:31 #include <stdio.h> int main(void){ int a[] = {10,20}; int *p = a; // De primeira a gente acha que a ordem de interpretação dos parâmetros é da // esquerda para direita, mas não. // 2º 1º a ser interpretado printf("*(++p): %d\t++(*p): %d\n", *(++p), ++(*p)); //volta o valor original de p (endereço de a) p--; // 2º 1º (p agora é a[1] que é 20) printf("++(*p): %d\t*(++p): %d\n", ++(*p), *(++p)); return 0; } Saída: *(++p): 20 ++(*p): 11 ++(*p): 21 *(++p): 20 Se eu escrevi alguma bobeira por favor me corrijam rs Explicando melhor! Se no primeiro printf o primeiro parâmetro (da esquerda para direita) fosse avaliado primeiro teríamos que ter 20 e 21, não 20 e 11. O que parece acontecer é: Pega-se o valor de *p e soma 1 (isso da 11) e guarda esse valor (2º parâmetro da esquerda para direita) Incrementa-se o valor do endereço de p e pega seu valor (isso dá 20) (1º parâmetro da esquerda para direita) A impressão desses valores segue a ordem "normal" da esquerda para direita, aí dá 20 e 11. Fiz isso para mostrar a diferença nos usos do parêntesis e também o que acontece quando passamos parâmetros para funções (melhor dizendo, como elas são avaliadas, em que ordem). Link para o comentário Compartilhar em outros sites More sharing options...
Pimptech Postado Fevereiro 25, 2018 em 17:22 Compartilhar Postado Fevereiro 25, 2018 em 17:22 3 horas atrás, gzn disse: #include <stdio.h> int main(void){ int a[] = {10,20}; int *p = a; // De primeira a gente acha que a ordem de interpretação dos parâmetros é da // esquerda para direita, mas não. // 2º 1º a ser interpretado printf("*(++p): %d\t++(*p): %d\n", *(++p), ++(*p)); //volta o valor original de p (endereço de a) p--; // 2º 1º (p agora é a[1] que é 20) printf("++(*p): %d\t*(++p): %d\n", ++(*p), *(++p)); return 0; } Saída: *(++p): 20 ++(*p): 11 ++(*p): 21 *(++p): 20 Se eu escrevi alguma bobeira por favor me corrijam rs Explicando melhor! Se no primeiro printf o primeiro parâmetro (da esquerda para direita) fosse avaliado primeiro teríamos que ter 20 e 21, não 20 e 11. O que parece acontecer é: Pega-se o valor de *p e soma 1 (isso da 11) e guarda esse valor (2º parâmetro da esquerda para direita) Incrementa-se o valor do endereço de p e pega seu valor (isso dá 20) (1º parâmetro da esquerda para direita) A impressão desses valores segue a ordem "normal" da esquerda para direita, aí dá 20 e 11. Fiz isso para mostrar a diferença nos usos do parêntesis e também o que acontece quando passamos parâmetros para funções (melhor dizendo, como elas são avaliadas, em que ordem). Falai, @gzn. Bele ? Bacana o exemplo! =) Porém só queria acrescentar que os parenteses não fazem diferença. Se você remove-los o resultado será o mesmo. O que importa é a ordem de incremento. Se incrementar diretamente o ponteiro ++p, o endereço será incrementado no tamanho do ponteiro. Então podemos usar *++p para incrementar primeiro o endereço(ponteiro) e depois "castar" para pegar o valor que o endereço de p aponta. Parenteses em ponteiros são ilustrativos, dão uma sensação de separação, são usados mais para deixar o código mais "legível". É nois! Abraço! Link para o comentário Compartilhar em outros sites More sharing options...
gzn Postado Fevereiro 25, 2018 em 17:45 Compartilhar Postado Fevereiro 25, 2018 em 17:45 Sr. @Pimptech obrigado pelos esclarecimentos. E ai @Leandro Fróes , vc tem algum comentário para ajudar a gente a entender melhor isso? comenta aí! rs Se o @fredericopissarra puder vir aqui e dar um comentário extra também seria uma boa, pq esse sr. entende bastante (esses dias quando fiz o curso do merces de prog moderna em c li muitos comentários dele lá) Link para o comentário Compartilhar em outros sites More sharing options...
Felipe.Silva Postado Fevereiro 27, 2018 em 00:27 Compartilhar Postado Fevereiro 27, 2018 em 00:27 Bom, a diferença entre *p e (*p), puramente, é nenhuma. Agora, você falou sobre usar incrementos... Ai sim os parênteses fazem diferença... Já que se nós escrevemos *p++ irá resultar em: 1) É usado o valor que p está apontando no momento. 2) DEPOIS da operação é incrementado o valor do ponteiro p. Agora, ao fazer (*p)++ o resultado é: 1) É usado o valor que p está apontando. 2) DEPOIS da operação é incrementado o valor ONDE o ponteiro aponta... Isto é, sem os parênteses é incrementado o endereço para onde p aponta. E com os parênteses é incrementado o VALOR que p está apontando na memória. Como você pediu, deixo um código exemplificando:https://ghostbin.com/paste/8gpjw Link para o comentário Compartilhar em outros sites More sharing options...
gzn Postado Fevereiro 27, 2018 em 01:14 Compartilhar Postado Fevereiro 27, 2018 em 01:14 1 /** 2 * Hehe, esse negócio confunde mesmo. 3 * O parenteses parece fazer diferença conforme o uso. 4 */ 5 #include <stdio.h> 6 int main(void){ 7 int a[] = {10, 20}, *p = a; 8 9 (*p)++; 10 printf("%d\n", *p); // saída é 11 11 12 *p++; 13 printf("%d\n", *p); // saída é 20 14 15 return 0; 16 } E aí, faz ou não faz diferença? Link para o comentário Compartilhar em outros sites More sharing options...
Pimptech Postado Fevereiro 27, 2018 em 16:07 Compartilhar Postado Fevereiro 27, 2018 em 16:07 14 horas atrás, gzn disse: 1 /** 2 * Hehe, esse negócio confunde mesmo. 3 * O parenteses parece fazer diferença conforme o uso. 4 */ 5 #include <stdio.h> 6 int main(void){ 7 int a[] = {10, 20}, *p = a; 8 9 (*p)++; 10 printf("%d\n", *p); // saída é 11 11 12 *p++; 13 printf("%d\n", *p); // saída é 20 14 15 return 0; 16 } E aí, faz ou não faz diferença? É, faz hehe.. Se quiser isolar primeiro o valor que p aponta e depois usar o incremento. Caso específico. Muito bom, n tinha pensado nesse ponto. Vivendo e aprendo Link para o comentário Compartilhar em outros sites More sharing options...
Leandro Fróes Postado Março 3, 2018 em 15:30 Autor Compartilhar Postado Março 3, 2018 em 15:30 Boa tarde pessoal! Muito foda que vocês tentaram, deixaram o post muito completo. Bom, mas eai? Qual a diferença? Depende kkkkkkk Até onde eu sei (e se alguém souber mais por favor, compartilhe) o parênteses serve para dar ênfase. Na prática eu vejo algumas situações que fazem diferença e duas já foram citadas aqui. São elas: Incremento (ou decremento): aqui *p++ anda de acordo com o tipo de dado que o ponteiro aponta e (*p)++ da ênfase ao elemento apontado. Percorrendo um array: #include <stdio.h> int main(){ int v[] = {10,20,30}; int *p = v; int i; for(i=0;i<3;i++){ printf("Com parenteses: %d\n", *(p+i)); printf("Sem parenteses: %d\n", *p+i); } } Saída: Com parenteses: 10 Sem parenteses: 10 Com parenteses: 20 Sem parenteses: 11 Com parenteses: 30 Sem parenteses: 12 E um outro caso que não foi comentado aqui é para declaração de arrays. Quando usamos int *v[] estamos criando um array de ponteiros do tipo intero. Agora quando usamos int (*v)[] estamos criando um ponteiro para um array de inteiros. Mas é isso ai galera, desafio concluído e já achamos 3 coisas interessantes, alguém tem algo mais para mostrar para nós? Abraços!! Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Março 8, 2018 em 00:34 Compartilhar Postado Março 8, 2018 em 00:34 Meus dois dedinhos de prosa, se é que já não explicaram isso exaustivamente ai em cima... "Ponteiro" é apenas uma variável, como qualquer outra, que contém um ENDEREÇO de memória ao invés de um valor do tipo especificado. Existe diferença entre a DECLARAÇÃO de algo e seu USO, especialmente quando se lida com "ponteiros". Abaixo, temos uma declaração de uma variável p que é um ponteiro que aponta para um char, na memória. Obviamente a variável não está inicializada (assim como você pode fazer com declarações como "int x;"): char *p; E, abaixo, temos a declaração de um array s contendo uma string e a inicialização do ponteiro p que passa a apontar para o 3º byte da string: char s[] = "Fred"; char *p; p = &s[2]; // & é o OPERADOR "endereço de"... Assim como com outros tipos de variáveis, OPERAÇÕES são efetuadas usando OPERADORES como +, -, *, /, =, etc. Só que, com ponteiros, o símbolo * é também usado como OPERADOR DE INDIREÇÃO, ou seja, ele pega o endereço no interior da variável e usa para localizar o dado referenciado por esse endereço. Quando fazemos: *p = 'a'; // usando o ponteiro inicializado acima A variável p (ponteiro p) contém o endereço (aponta para) do 3º item do array s. O * antes de p é o OPERADOR DE INDIREÇÃO que usa o endereço contido em p e pega (ou escreve, neste caso, porque temos o operador = e a expressão está do lado esquerdo) o caracter apontado. A expressão *p pega/escreve 1 caracter porque este é o tipo APONTADO pela variável p. Quando usamos operadores como +, -, ++ e -- com ponteiros trabalhamos com aritmética (duh!), mas o endereço será incrementado ou decrementado de acordo com o tamanho do tipo... Por exemplo, se fizermos: int x[] = { 1, 2, 3, 4}; int *p = &x[1]; printf("%d\n", *++p); Assumindo que p tem um endereço 0x400020 depois de inicializado, ao fazer ++p ele conterá 0x400024, ou seja, incrementamos o endereço em 4 unidades porque o tamanho de um "int" é de 4 bytes. mas note que a expressão que usei no printf() foi *++p. Isso quer dizer que fazemos um pré-incremento de p (p apontará para a posição do array x que contém o 3) e depois usamos o operador de indireção para ler o valor 3 no endereço dado por p. Neste ponto podemos responder qual é a diferença entre *p e (*p)... NENHUMA! Note que se tivéssemos uma expressão como: a = b; Faz alguma diferença se escrevessemos isso como "a = (b)"? Os parênteses ai é um operador, mas é usado apenas para forçar a ordem de precedência da expressão como um todo. Isso não significa que parensteses não possam ser usados para DECLARAR tipos diferentes de ponteiros... Por exemplo: int *a[]; // a é um array de ponteiros para int. int (*a)[]; // a é um ponteiro de arrays para int. E, às vezes, os parenteses ajudam a garantir que uma expressão faça o que queremos que ela faça... Por exemplo: c = *p++; // mesma coisa que c=*p; p=p+1; c = (*p)++; // mesma coisa que c = *p; t = *p; t = t + 1; *p = t; Aliás... não é obvio, mas ao obtermos um N-ésino item de um array a, por exemplo, via a[N], na verdade o símbolo 'a' é o ponteiro para o primeiro elemento do array que é somado ao valor N e depois "derreferenciado" (via um operador de indireção implícito)... Ou seja: a[N] == *(a + N) Isso gera um "macete" interessante, mas perigoso: a[N] também pode ser escrito como N[a] (tente, o compilador não reclamará!). Isso porque *(a + N) é a mesma coisa que *(N + a) - propriedade comutativa da adição! Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados
Arquivado
Este tópico foi arquivado e está fechado para novas respostas.