|
|
|
|
Strumenti |
04-07-2014, 17:52 | #1 |
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
[C++] int, array byte
Codice:
INT32 a = 0x00401600; char c[] = { 0x00, 0x40, 0x16, 0x00 }; |
04-07-2014, 18:22 | #2 |
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Quale sprintf ?
|
04-07-2014, 18:28 | #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); |
04-07-2014, 18:41 | #4 |
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Codice:
printf("%s\n", c == &c[0] ? "y" : "n" ); |
04-07-2014, 18:48 | #5 |
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Codice:
y |
04-07-2014, 19:00 | #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 }; |
04-07-2014, 19:16 | #7 | ||
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
Quote:
Quote:
|
||
04-07-2014, 19:29 | #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 )
|
04-07-2014, 21:12 | #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; } |
05-07-2014, 08:42 | #10 |
Member
Iscritto dal: Jan 2008
Messaggi: 103
|
|
05-07-2014, 13:36 | #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 . |
05-07-2014, 14:42 | #12 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12646
|
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) |
06-07-2014, 08:24 | #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:
|
|
07-07-2014, 15:18 | #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.
|
07-07-2014, 15:37 | #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. |
07-07-2014, 16:10 | #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 |
07-07-2014, 16:53 | #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 17:27. |
||||||
07-07-2014, 17:50 | #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 17:55. |
07-07-2014, 19:39 | #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; |
07-07-2014, 20:16 | #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: 21:28.