Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Abbiamo provato per molti giorni il nuovo Z Fold7 di Samsung, un prodotto davvero interessante e costruito nei minimi dettagli. Rispetto al predecessore, cambiano parecchie cose, facendo un salto generazionale importante. Sarà lui il pieghevole di riferimento? Ecco la nostra recensione completa.
The Edge of Fate è Destiny 2.5. E questo è un problema
The Edge of Fate è Destiny 2.5. E questo è un problema
Bungie riesce a costruire una delle campagne più coinvolgenti della serie e introduce cambiamenti profondi al sistema di gioco, tra nuove stat e tier dell’equipaggiamento. Ma con risorse limitate e scelte discutibili, il vero salto evolutivo resta solo un’occasione mancata
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
AMD ha aggiornato l'offerta di CPU HEDT con i Ryzen Threadripper 9000 basati su architettura Zen 5. In questo articolo vediamo come si comportano i modelli con 64 e 32 core 9980X e 9970X. Venduti allo stesso prezzo dei predecessori e compatibili con il medesimo socket, le nuove proposte si candidano a essere ottimi compagni per chi è in cerca di potenza dei calcolo e tante linee PCI Express per workstation grafiche e destinate all'AI.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 04-07-2014, 17:52   #1
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
[C++] int, array byte

Codice:
INT32 a = 0x00401600;
char c[] = { 0x00, 0x40, 0x16, 0x00 };
perchè sprintf c dà 0x0028fec4
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 18:22   #2
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Quale sprintf ?
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 18:28   #3
Q_Q
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);
M'è scappata una s di troppo
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 18:41   #4
van9
Member
 
Iscritto dal: Nov 2012
Messaggi: 126
Codice:
printf("%s\n", c == &c[0] ? "y" : "n" );
van9 è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 18:48   #5
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
Codice:
y
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 19:00   #6
lorenzo001
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 };
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 19:16   #7
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
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));
d'oh mi confondo sempre con i puntatori

Quote:
Originariamente inviato da lorenzo001
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 };
Quindi i byte di a e c in memoria sono invertiti ?
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 19:29   #8
lorenzo001
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 )
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 04-07-2014, 21:12   #9
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
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;
}
il punto chiave è che se hai un array arr e vuoi l'indirizzo dell'elemento che trovi con un indice di valore 3, per avere l'indirizzo di quell'elemento usi la sintassi &arr[3] .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 05-07-2014, 08:42   #10
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
Quote:
Originariamente inviato da Freaxxx Guarda i messaggi
è possibile trattare array con l'aritmetica dei puntatori ma un array non è un puntatore
non è un puntatore costante che punta al primo elemento
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 05-07-2014, 13:36   #11
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
non è un puntatore costante che punta al primo elemento
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
nel mondo della programmazione, specialmente in C e C++, esiste il fenomeno dell'aliasing, e specialmente in C++ l'aliasing è una brutta bestia che può nascondere perdite di performance, https://it.wikipedia.org/wiki/Aliasi...grammazione%29

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 .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 05-07-2014, 14:42   #12
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12819
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)
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 06-07-2014, 08:24   #13
vbextreme
Member
 
L'Avatar di vbextreme
 
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;
}
Ho poi bloccato lo standard c99 quindi non l'ho nemmeno compilato il tuo codice.
Quote:
||=== Build: Debug in iop (compiler: GNU GCC Compiler) ===|
main.c||In function ‘old_printAddr’:|
main.c|71|error: ‘for’ loop initial declarations are only allowed in C99 mode|
main.c|71|note: use option -std=c99 or -std=gnu99 to compile your code|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Niente flame però! solo questione di gusti personali.
__________________
Easy framework per il linguaggio C.
vbextreme hack your life
vbextreme è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 15:18   #14
van9
Member
 
Iscritto dal: Nov 2012
Messaggi: 126
Quote:
Originariamente inviato da Antonio23 Guarda i messaggi
in soldoni, si. la principale differenza è che è un puntatore costante e la memoria è sempre allocata al momento della definizione dell'arra stesso.
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.
van9 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 15:37   #15
van9
Member
 
Iscritto dal: Nov 2012
Messaggi: 126
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
non è un puntatore costante che punta al primo elemento
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.
van9 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 16:10   #16
Q_Q
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
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 16:53   #17
van9
Member
 
Iscritto dal: Nov 2012
Messaggi: 126
Quote:
Originariamente inviato da Freaxxx Guarda i messaggi
in realtà tutti gli esempi riportati sino ad ora sono più "scorciatoie" che altro.
Ma se non hai nemmeno centrato la richiesta dell'OP! (vedi sotto)

Quote:
è 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.
A vole essere precisi semmai dovevamo informare noi l'OP che aveva un overflow in atto. Noia e pigrizia da parte mia l'altro giorno.

Quote:
Inoltre questo codice è puro C, non esiste nulla che sia C++, non confondete i due linguaggi.
Io non confondo proprio nulla e nemmeno Lorenzo mi pare - quanto scritto è per definizione codice C++ e quindi non si capisce di che ti lamenti. Tra l'altro come qualunque esperto di C++ dotato di senso pratico e gusto, uso sempre stdio al posto di quella schifezza stateful di iostream e proprio in questo esempio non c'è discussione al riguardo.

Quote:
Se dato un array sei interessato ad estrarre o visualizzare gli indirizzi dei suoi elementi ( mi sembra di capire che il problema sia questo )
No, l'OP si chiedeva perché due chiamate a printf non producessero lo stesso risultato - il problema è il classico di chi pensa che attraverso il solo nome di una struttura dati possa avere accesso unitario/completo ad essa.

Quote:
questo piccolo programma in C ( C99 ) con relativa funzione dovrebbe fare al caso tuo
Ma non era taggato "C++" il thread? In C++ valido, e molto più chiaramente:

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:
il punto chiave è che se hai un array arr e vuoi l'indirizzo dell'elemento che trovi con un indice di valore 3, per avere l'indirizzo di quell'elemento usi la sintassi &arr[3] .
Più che altro restava da chiarirgli la questione dello storage, con cui può divertirsi tramite qualcosa tipo

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" : "");
e/o

Codice:
printf("0x%02x%02x%02x%02x\n",
     *((int *)c) & 0xff,
    (*((int *)c) >> 8) & 0xff,
    (*((int *)c) >> 16) & 0xff,
    (*((int *)c) >> 24) & 0xff);
Tutto rigorosamente scritto al volo e non testato. Il problema dell'overflow è lasciato come esercizio per l'OP.

Ultima modifica di van9 : 07-07-2014 alle 17:27.
van9 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 17:50   #18
van9
Member
 
Iscritto dal: Nov 2012
Messaggi: 126
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Tralasciando le questioni di performance (premature optimization is the root of all evil), la cosa è un pelo delicata.
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.
van9 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 19:39   #19
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
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;
}
listato 2
Codice:
#include <stdlib.h>
int main()
{
  ...
  return EXIT_SUCCESS;
}
e la domanda in questo caso è: quale dei due prototipi scegliereste come modello per creare esempi in codice C per un novizio ?

Adesso fate mente locale a quante volte avete visto persone scrivere
Codice:
return 0;
anziché
Codice:
return EXIT_SUCCESS;
, oppure quante volte persone che fanno questo lavoro hanno usato
Codice:
return EXIT_SUCCESS;
senza usare la giusta inclusione, il giusto header. Questo genere di cose viene prima della teoria sulla memoria e le allocazioni e deallocazioni, se non conosci la sintassi da usare per dichiarare un puntatore ad un array o come si può dedurre l'indirizzo di un elemento di un array dato il suo indice, della teoria sulla memoria non te ne fai nulla; anche perché poi inizi a prendere questa sintassi come abitudine e finirai per scrivere sempre
Codice:
return 0;
anche sapendo che è un approccio non standard e meno portabile.
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2014, 20:16   #20
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
Mi hanno passato questo:
Deitel & Deitel - C, Corso completo di programmazione
va bene se (re)inizio con quello
si, i Deitel credo che vadano bene per un novizio.

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.
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy Z Fold7: un grande salto generazionale Recensione Samsung Galaxy Z Fold7: un grande sal...
The Edge of Fate è Destiny 2.5. E questo è un problema The Edge of Fate è Destiny 2.5. E questo ...
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello Ryzen Threadripper 9980X e 9970X alla prova: AMD...
Acer TravelMate P4 14: tanta sostanza per l'utente aziendale Acer TravelMate P4 14: tanta sostanza per l'uten...
Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque Hisense M2 Pro: dove lo metti, sta. Mini proiett...
Identikit della scheda video perfetta, p...
SUV, 100% elettrico e costa meno di un b...
Hai mai caricato un referto su ChatGPT? ...
Apple vuole un nuovo campus nella Silico...
DJI Osmo 360, la nuova action cam a 360&...
Lo strumento anti-requisiti per Windows ...
Utenti di Claude in rivolta: 'I bei vecc...
Rocket Lab Mars Telecommunications Orbit...
NVIDIA GeForce RTX: supporto driver su W...
iliad ha iniziato a vendere smartphone d...
La cinese SatNet ha lanciato un nuovo gr...
Cloud sovrano europeo: a che punto siamo...
The Medium arriverà al cinema gra...
Addio alle faccende domestiche? Il robot...
Fallito il primo lancio del razzo spazia...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 20:50.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v