|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
[C++] int, array byte
Codice:
INT32 a = 0x00401600;
char c[] = { 0x00, 0x40, 0x16, 0x00 };
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Quale sprintf ?
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Codice:
INT32 a = 0x00401600;
INT32 b = 0x004016B0;
char c[] = { 0x00, 0x40, 0x16, 0x00 };
char d[] = { 0x00, 0x40, 0x16, 0xB0 };
printf("0x%08x\n0x%08x\n\n", a, b);
printf("0x%08x\n0x%08x\n\n", c, d);
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Codice:
printf("%s\n", c == &c[0] ? "y" : "n" );
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Codice:
y |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
c e d sono array e quindi visualizzi l'indirizzo dell'array, ovvero del suo primo elemento (che è quello che ti ha spiegato van9)
Per quello che vuoi fare tu, devi indicare che l'indirizzo in questione punta ad un intero e quindi visualizzare il valore puntato, ovvero printf("0x%08x\n0x%08x\n\n", *((int *)c), *((int *)d)); Tieni presente però che in memoria i valori sono in ordine inverso e quindi devi scrivere char c[] = { 0x00, 0x16, 0x40, 0x00 }; char d[] = { 0xB0, 0x16, 0x40, 0x00 }; |
|
|
|
|
|
#7 | ||
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Quote:
mi confondo sempre con i puntatoriQuote:
|
||
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
I byte che compongono l'intero a sono nell'ordine che ti ho indicato, dal meno significativo al più significativo ( per i processori Intel, ordine little-endian, vedi http://it.wikipedia.org/wiki/Ordine_dei_byte )
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
in realtà tutti gli esempi riportati sino ad ora sono più "scorciatoie" che altro.
è possibile trattare array con l'aritmetica dei puntatori ma un array non è un puntatore e soprattutto ci sono modi migliori di informare il tuo compilatore che stai trattando un array. Inoltre questo codice è puro C, non esiste nulla che sia C++, non confondete i due linguaggi. Se dato un array sei interessato ad estrarre o visualizzare gli indirizzi dei suoi elementi ( mi sembra di capire che il problema sia questo ) questo piccolo programma in C ( C99 ) con relativa funzione dovrebbe fare al caso tuo Codice:
#include <stdlib.h>
#include <stdio.h>
void printAddr(int (*arr)[], size_t s)
{
for (size_t i = 0; i < s; i++)
{
printf("%p %d\n", &(*arr)[i], *(&(*arr)[i]));
}
}
int main()
{
int c[] = {1, 54, 42, 44, 33};
// esempio su singola riga senza uso
// di alcuna funzione
// printf("%p %d\n", &c[2], *(&c[2]));
printAddr(&c, 5);
return EXIT_SUCCESS;
}
|
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
dipende a cosa ti riferisci e in quale contesto.
in breve non è possibile dare una risposta in un post, bisogna conoscere il linguaggio e come la macchina e il compilatore opera, comunque sia ritorno a specificare che Codice:
puntatore != array quando tratti un array come puntatore introduci dell'aliasing, e questo è il motivo per cui all'atto pratico non vedi differenze, ma concettualmente usare un array come o attraverso un puntatore è una cattiva soluzione per diversi motivi. il problema è anche teorico perché a tutti i "prof" che ho conosciuto piace semplificare e pure troppo; il concetto di puntatore è molto più facile da spiegare e assimilare di tutto il resto, e quindi ogni buon prof di informatica ti ripete che tutto può essere un puntatore e tutti son felici e contenti, stessa cosa dicasi per alcuni libri. Inutile dire che non è così. se sei interessato a studiare il linguaggio ci sono gli standard ISO ( ISO/IEC 9899:1999 per il C99 ) se sei un programmatore occasionale il tuo codice sarà orribile ma all'atto pratico non vedrai molte differenze ( "il programma funziona!" cit. ) e vivrai contento . |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12862
|
Tralasciando le questioni di performance (premature optimization is the root of all evil), la cosa è un pelo delicata.
Un esempio semplice per capire come il compilatore tratta differentemente le cose: Codice:
char mio_array[20];
printf("SizeOf: %lu\n", sizeof(mio_array)); // stampa 20
Codice:
char* mio_array = alloca(20); // alloca 20 bytes sullo stack
printf("SizeOf: %lu\n", sizeof(mio_array)); // stampa 4 o 8 (a seconda dei casi)
|
|
|
|
|
|
#13 | |
|
Member
Iscritto dal: Dec 2013
Messaggi: 90
|
@freaxx io avrei preferito altre alternative al tuo codice, quali:
Codice:
void old_printAddr(int (*arr)[], size_t s)
{
for (size_t i = 0; i < s; i++)
{
printf("%p %d\n", &(*arr)[i], *(&(*arr)[i]));
}
}
void simple_printAddr(void *arr, size_t s)
{
int* a = (int*) arr;
while(s--)
{
printf("%p %d\n", a, *a);
a++;
}
}
void versatile_printAddr(void *arr, size_t s, size_t n, const char* vw)
{
char* a = (char*) arr;
char v1[80];
char v2[80];
while (n--)
{
sprintf(v1,"%p ",a);
sprintf(v2,vw,*a);
strcat(v1,v2);
puts(v1);
a += s;
}
}
int main()
{
int c[] = {1, 54, 42, 44, 33};
char x[] = {'a','b','c'};
// esempio su singola riga senza uso
// di alcuna funzione
// printf("%p %d\n", &c[2], *(&c[2]));
puts("Simple Vector int");
simple_printAddr(&c, 5);
puts("Versatile Vector int");
versatile_printAddr(&c, sizeof(int), 5,"%d");
puts("Versatile Vector char");
versatile_printAddr(&x, sizeof(char), 3,"%c");
return 0;
}
Quote:
|
|
|
|
|
|
|
#14 |
|
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
No, e basta passare il nome di un array come parametro ad una function per dimostrarlo: il nome dell'array decade immediatamente a puntatore ed è possibile assegnare al nome stesso un nuovo valore (ovvero niente comportamento da "puntatore costante"). Per un esempio di array la cui memoria non è allocata a tempo di definizione vedi i flexible members in C99.
|
|
|
|
|
|
#15 |
|
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
No. Un array, un puntatore e un puntatore costante sono tre cose differenti.
Il nome di un array viene convertito ("decade") a puntatore quando serve, ma questo non lo rende o trasforma in un puntatore. Due sono le cose: o ha ragione Dennis Ritchie (autore del C) quando dice che, date le evidenti difficoltà dei più a capire la natura di arrays e puntatori in C, stiamo parlando di un errore di design e quindi è facile che i più trovino difficoltà. Oppure i programmatori non si applicano davvero/non vanno in fondo alle questioni. Se vuoi imparare una volta e per tutte come stanno (semplicemente) le cose, studiati attentamente http://cm.bell-labs.com/who/dmr/chist.html e dopo vedrai non ci sarà più alcuna confusione. |
|
|
|
|
|
#16 |
|
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Mi hanno passato questo:
Deitel & Deitel - C, Corso completo di programmazione va bene se (re)inizio con quello |
|
|
|
|
|
#17 | ||||||
|
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Quote:
Quote:
Quote:
Quote:
Quote:
Codice:
void _printAddr(int arr[], size_t s)
{
for (size_t i = 0; i < s; i++)
{
printf("%p %d\n", (void *) &arr[i], arr[i]);
}
}
Quote:
Codice:
size_t n = sizeof(c)/sizeof(c[0]);
for (size_t i = 0; i < n; i++)
printf("%s%02x%s", !i ? "0x" : "", c[i], i == n-1 ? "\n" : "");
Codice:
printf("0x%02x%02x%02x%02x\n",
*((int *)c) & 0xff,
(*((int *)c) >> 8) & 0xff,
(*((int *)c) >> 16) & 0xff,
(*((int *)c) >> 24) & 0xff);
Ultima modifica di van9 : 07-07-2014 alle 18:27. |
||||||
|
|
|
|
|
#18 |
|
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
E' più una questione strutturale e di linguaggio che altro - chi conosce anche Fortran (arrays "veri", restricted pointers, etc.) lo sa bene. E no, ovviamente non si risolve nulla utilizzando solo ed esclusivamente gli arrays piuttosto che i puntatori (perché questo non garantisce all'optimizer l'assenza di aliasing - vedi anche la keyword restrict in C99 per una direzione standardizzata sulla faccenda).
Ultima modifica di van9 : 07-07-2014 alle 18:55. |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
@var9 di precisazioni se ne possono fare sempre tante, il codice era chiaramente un esercizio in C a differenza di quanto scritto nel titolo ( C++ ).
Considero comunque quanto postato un passo in avanti nella giusta direzione per l'OP, è inoltre una soluzione molto più asciutta e compatta, con 1-2 novità che OP può studiare per comprendere meglio come si possa implementare quanto chiesto. Onestamente in questi frangenti gradisco più usare C++ che C, il motivo per il quale non ho offerto un esempio l'ho già menzionato, peraltro OP ha appena citato un libro sul C . La gestione della memoria in C e/o C++ è sempre un punto critico, è talmente importante che molto spesso la fonte dei problemi in termini di affidabilità e performance in software scritto usando questi due linguaggi è quasi sempre da ricercare li e raramente altrove ( considerando un codice grammaticalmente e logicamente corretto ) . Ma non mi metto certo a discutere di gestione della memoria in un post su un forum, solo per trattare gli allocatori in C++ servirebbe un libro, se ci mettiamo pure le varie differenze specifiche alle varie piattaforme, come il comportamento delle funzioni della famiglia *alloc* ci servono mesi di trattazione in C e C++ . Tutto ciò è sicuramente interessante ma inopportuno per un post di risposta ad una domanda semplice come questa che è in realtà un piccolo esercizio per inziare. Se OP vorrà si prenderà un bel compilatore, debugger e profiler, un bel manuale o libro sul C, e approfondirà da solo. Non intendo entrare in polemica con nessuno ma è la mia personale visione su come si dovrebbe insegnare un linguaggio come il C o il C++ ad un novizio; un esempio che può apparire stupido ma stupido non è listato 1 Codice:
int main()
{
...
return 0;
}
Codice:
#include <stdlib.h>
int main()
{
...
return EXIT_SUCCESS;
}
Adesso fate mente locale a quante volte avete visto persone scrivere Codice:
return 0; Codice:
return EXIT_SUCCESS; Codice:
return EXIT_SUCCESS; Codice:
return 0; |
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
Quote:
da notare anche che il libro di riferimento per il C ( http://www.amazon.com/The-Programmin...dp/0131103628/ , esiste anche l'edizione tradotta in italiano ) è più strutturato come un manuale che come un libro per i novizi che vogliono partire con il C, è un po' più formale e meno incentrato su questioni di programmazione generale, rimane tuttavia una ottima alternativa. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:21.












mi confondo sempre con i puntatori








