Dimensioni

di il
21 risposte

Dimensioni

Salve a tutti
volevo sapere se durante l'esecuzione di un programma dal suo interno e possibile cambiare la dimensione di una variabile?
esempio:
int InsRightParola(char *cptr,char *dptr,)
   {
	int indy,errore,k;
	    indy = 0; k = 0;
         int maxa,maxb,maxstr;
         maxa=LenStringa(cptr);
         maxb=LenStringa(cptr)
         maxstr=maxa+maxb;
	    errore = 0;
	char e; e = ' ';
		k = maxa + maxb +1;
		if ( k > maxstr )
		  { 
			errore = -1;  
		  }
		else {
	           cptr += maxa;
	           for (indy = 0;indy <= maxb; indy++)
	              {
					e = *dptr; *cptr = e;
		            *cptr++; *dptr++;
					maxa++;
	              }
	           errore = 0;
		     }
		*cptr = '\0';
		return errore;
   }
siccome la stringa viene inmessa in cptr ed essendo una funzione esterna non so la dimensione
cosi vorrei evitare che la stringa venisse sfondata e non perdesse i dati.
quindi la dovrei ridefinire come posso fare?

21 Risposte

  • Re: Dimensioni

    Non è possibile fare niente del genere.
    Anche perché cptr potrebbe essere benissimo un array di char stack based e come tale invariabile.
  • Re: Dimensioni

    Ciao shodan
    tutto bene ?
    quindi se ho capito bene l'unica soluzione per poter fare questa funzione sarebbe quella di passargli un parametro che sia la lunghezza definita della stringa e poi vedere tramite un template se la dimensione del parametro passato corrisponda a quello della stringa.
    ma se i template dentro le funzioni non possono stare come faccio a fare quanto detto su?
  • Re: Dimensioni

    Non c'è male, grazie.

    La soluzione è a meta di quel che hai scritto. Devi passare almeno la lunghezza della string destinazione, ma il template è inutile.

    In pratica basta scrivere:
    
    int InsRightParola(char *cptr,std::size_t cptrlen, const char *dptr,)
       {
           std::size_t cremains = 0; // caratteri che cptr può tenere senza problemi
           // lunghezza dptr
           std::size_t dptrlen = strlen(dptr);
           if (cptrlen <= dptrlen) // non c'è spazio
           else  
               cremains = cptrlen - dptrlen;
       
           for (indy = 0;indy < cremains; indy++) {
               *cptr++ = *dptr++;
           }
    
       }
    
    Più o meno lo schema è questo. Comunque per il C una funzione simile c'è già:
    strcat http://www.cplusplus.com/reference/clibrary/cstring/strcat/
    e strncat http://www.cplusplus.com/reference/clibrary/cstring/strncat/

    In C++ si usa std::string e questi problemi te li scordi proprio.
  • Re: Dimensioni

    Purtroppo il template servirebbe per evitare che uno per sbaglio immetta un numero che possa far sfondare la stringa.
    esempio:
    str char[20]="walt disney"
    str2 char[20]="pippo e topolino";
    myfunzione (str,str2,40) // questo e un errore
    
    ecco a cosa mi servirebbe il template
    e siccome la funzione starebbe esternamente non saprei mai quanto e grande la variabile cosi correrei il rischio o di sfondarla o di troncare l'operazione.
  • Re: Dimensioni

    Non potrai mai avere nessuna garanzia di questo tipo. E men che meno la puoi avere da un template che lavora a compile time, non a runtime.
    L'unica cosa che puoi fare è assicurarti che str (presumo la destinazione) sia grande quanto basta per contenere str2 (la sorgente). Ma è una cosa che devi fare prima di invocare la funzione.
    Nella funzione il massimo che puoi fare e assicurarti di operare su un intervallo valido. Magari avrai la stringa troncata, ma non avrai errori di buffer overflow (ogni volta che leggi qualcosa a proposito è proprio a questo che ci si riferisce).

    Una opinione puramente personale.
    Ho letto in un altro thread che vuoi farti una tua libreria per evitare il casino degli include.
    Se lo fai per prendere mano con il linguaggio ben venga, ma tieni presente che le funzioni della libreria standard sono documentate e testate da anni e praticamente non hanno bug (parlo di quelle base del C). Molti compilatori poi le convertono in automatico in codice ASM appena ne trovano una e sono proprio quelle per la manipolazione di stringhe (strcpy, strcat etc...) e memoria (le varie memcpy memcmp etc...).
    Inoltre dovrai ogni volta inserire la tua libreria nel progetto, mentre la libc è compresa in automatico. Insomma non so quanto ci guadagni nel cambio.
    Tra l'altro il delirio degli include te lo ritrovi appena inizi a usare qualche libreria non tua e non escludo che un giorno te lo ritrovi anche con librerie fatte da te.
  • Re: Dimensioni

    Grazie per le informazioni.
    ma posso scrivere anche le funzioni in assembler?
    conosci qualche procedura standard per il passaggio dei parametri da c++ ad assembler e vice versa?
    sarà uno spasso riconvertire tutta la libreria in assembler peccato che abbiano soppresso a livello di programmazione gli interrupt!
    comunque le librerie di sistema non sono poi un granchè documentate visto che molto spesso trovo funzionalità nascoste nella cout nella cin etc etc.
    hai pultroppo ragione sul casino degli include che incontrerò quando utilizzerò funzioni non mie ma su questo pultroppo non posso farci nulla.
    nelle mie non credo incontrerò problemi perchè fin quando utilizzerò solo funzioni staranno in un unica libreria,ben documentata, chiamata babele.
    sulle mie funzioni che stò creando la documentazione sta crescendo funzione per funzione.
    poi farsi una propria libreria ha parecchi sostanziali vantaggi quali ad esempio:
    1) ogni funzione fa soltanto una cosa mentre le funzioni standard molto spesso fanno un sacco di cose con sintassi molto spesso astruse.
    2) conoscendo approfonditamente le funzioni la comprensione del sorgente e più facile.
    3) sapendo quali comandi/funzioni si ha a disposizione e più facile fare i programmi.
    4) possibilità di un miglior controllo degli errori (ecco perchè sto cercando un sistema per includere i template nelle funzioni al momento non lo so ancora fare!)
    i sostanziali svantaggi sono:
    1) sono un recettacolo di bug! ma questo può essere uno stimolo per diventare più bravi!
    2) optimizzazione di solito resta un optional cosa che con le funzioni di sistema non succede
    3) il programma lo capisce solo chi lo scrive (in fase di sorgente).

    una curiosità ma posso fare una unica libreria anche per le classi o mi toccherà fare una libreria per ogni classe che voglio creare?
  • Re: Dimensioni

    Devo dividerlo in due altrimenti non ci stà.

    smalldragon ha scritto:


    grazie per le informazioni.
    ma posso scrivere anche le funzioni in assembler?
    conosci qualche procedura standard per il passaggio dei parametri da c++ ad assembler e vice versa?
    Il passaggio può valere solo da C ad ASM, non C++ ad ASM. Comunque quel che poco che so l'avevo letto qui:
    http://www.nasm.us/xdoc/2.10.05/html/nasmdoc9.html#section-9.1
    sarà uno spasso riconvertire tutta la libreria in assembler peccato che abbiano soppresso a livello di programmazione gli interrupt!
    Dipende dai punti di vista. Se lavori a 32bit, poi dovrai riscrivere la libreria per i 64 o viceversa. Magari poi decidi di usare i registri SSE, MMX etc. Può valerne la pena come no. Vedi se ti torna utile questo sito: http://www.agner.org che contiene parecchio materiale su ottimizzazioni in ASM.
    comunque le librerie di sistema non sono poi un granchè documentate visto che molto spesso trovo funzionalità nascoste nella cout nella cin etc etc.
    Non ho mai avuto problemi a trovare documentazione sulla più minima funzione di libreria.
    A quali funzioni ti riferisci di preciso per cin e cout?
    Un paio di link di documentazione.
    http://en.cppreference.com/w
    http://www.cplusplus.com/reference
    poi farsi una propria libreria ha parecchi sostanziali vantaggi quali ad esempio:
    1) ogni funzione fa soltanto una cosa mentre le funzioni standard molto spesso fanno un sacco di cose con sintassi molto spesso astruse.
    Ad esempio? Dato che conosco bene il linguaggio a me potrebbero sembrare ovvie cose che non lo sono per altri.

    2) conoscendo approfonditamente le funzioni la comprensione del sorgente e più facile.
    La teoria vuole che le funzioni siano black box per l'utilizzatore. Pertanto a me deve interessare cosa fa una funzione, non come lo fa. Poi se si ha il sorgente per spulciare il codice tanto meglio. E ormai ogni compilatore decente si porta dietro i sorgenti della libreria.
  • Re: Dimensioni

    3) sapendo quali comandi/funzioni si ha a disposizione e più facile fare i programmi.
    Scusa, ma hai scoperto l'acqua calda. Ovvio che senza documentazione una libreria non è usabile,
    ma come ho detto la libreria standard è documentata da anni e le funzioni base sono di serie su ogni compilatore aderente allo standard (possono fare eccezione dei compilatori per microcontrollori, DSP etc...)

    4) possibilità di un miglior controllo degli errori (ecco perchè sto cercando un sistema per includere i template nelle funzioni al momento non lo so ancora fare!)
    Il miglior controllo peggiorebbe solo le prestazioni del linguaggio, per cui si fa solo se indispensabile. Il C da per scontato che si sappia quello che si sta facendo. Se sfori un array non è compito del C avvertirti: sei tu che lo devi sapere. Ed è anche questo che rende il C un linguaggio ottimizzato e veloce.
    In quanto ai template non capisco che intendi con: "ecco perchè sto cercando un sistema per includere i template nelle funzioni". Puoi usare i template nelle funzioni, ma la loro definizione è obbligatorio che stia in un file header.
    i sostanziali svantaggi sono:
    1) sono un recettacolo di bug! ma questo può essere uno stimolo per diventare più bravi!
    Giusto. E ricorda che c'è sempre un altro bug!
    2) optimizzazione di solito resta un optional cosa che con le funzioni di sistema non succede
    Frase ambigua. Per come l'ho capita io: "le funzioni di sistema sono sempre ottimizzate".
    Se intendi il contrario ti invito a leggere questo:
    http://www.flounder.com/optimization.ht
    3) il programma lo capisce solo chi lo scrive (in fase di sorgente).
    Se fosse vero non esisterebbero i progetti open source, i codici di esempio e tu non riceveresti nessun aiuto nel forum. Come ti si potrebbe aiutare se nessuno capisce il tuo sorgente?
    una curiosità ma posso fare una unica libreria anche per le classi o mi toccherà fare una libreria per ogni classe che voglio creare?
    La teoria vorrebbe una classe - una libreria per non aggiungere codice inutile al programma, ma non è indispensabile.
  • Re: Dimensioni

    Negli svantaggi ho scritto
    "optimizzazione di solito resta un optional cosa che con le funzioni di sistema non succede"
    vuol significare che quando uno fa una funzione tende più a risolvere il problema che ad ottimizzare la funzione cosi si creano funzioni che a volte,raramente, sono più ottimizzate di quelle di sistema mentre altre volte,quasi sempre, non lo sono per nulla.
    mentre quelle di sistema sono sempre ottimizzate e raramente, ma capita!, non fanno bene ciò che dovrebbero fare per esempio la cin che se non se non cancelli ogni volta il buffer ti combina casini.

    1) ogni funzione fa soltanto una cosa mentre le funzioni standard molto spesso fanno un sacco di cose con sintassi molto spesso astruse.
    quando tu scrivi una funzione di solito ha solo uno scopo,di solito, quindi fa solo una cosa.
    mentre quelle di sistema fanno non hanno un unico scopo,almeno la magior parte quali ad esempio:
    cin >> che da sola fa una cosa
    mentre se faccio cin.qualcosa fa altre 100 mila cose e ciò provoca confusione ed inizia il manicomio.
    se poi pigliamo sintassi del tipo std::qualcosa>> eccoti qui un esempio di sintassi astrusa.
    peccato che mi hanno levato gli interrupt assembler altrimenti mi sarei riscritto pure questo!
    la questione del controllo degli errori secondo me e di vitale inportanza in quanto gli errori si possono generare in 1000 modi e molto spesso non dipende dal programmatore.
    il metterli fuori alla chiamata della funzione e un processo che può causare confusione.
    mentre inserendoli all'interno della funzione ciò non causerebbe nessun tipo di confusione.
  • Re: Dimensioni

    smalldragon ha scritto:


    negli svantaggi ho scritto
    mentre quelle di sistema sono sempre ottimizzate e raramente, ma capita!, non fanno bene ciò che dovrebbero fare per esempio la cin che se non se non cancelli ogni volta il buffer ti combina casini.
    Si. ma è un problema che hanno tutte le funzioni di input. Nel caso specifico di cin, i dati prelevati dal buffer di tastiera devono essere convertiti nel tipo di dato richiesto. Quindi se chiedi un int e viene immesso un char, la conversione deve fallire. E lo stream deve restare non valido finché non viene ripulito manualmente. Nota però che questo avviene sono con gli operatori di estrazione >> che sono funzioni di manipolazione formattato dello stream.
    Difatti, io almeno, sconsiglio sempre di utilizzare tali operatori e usare invece getline(cin, std::string) e poin convertire la stringa ricevuta.
    1) ogni funzione fa soltanto una cosa mentre le funzioni standard molto spesso fanno un sacco di cose con sintassi molto spesso astruse.
    quando tu scrivi una funzione di solito ha solo uno scopo,di solito, quindi fa solo una cosa.
    mentre quelle di sistema fanno non hanno un unico scopo,almeno la magior parte quali ad esempio:
    cin >> che da sola fa una cosa
    mentre se faccio cin.qualcosa fa altre 100 mila cose e ciò provoca confusione ed inizia il manicomio.
    se poi pigliamo sintassi del tipo std::qualcosa>> eccoti qui un esempio di sintassi astrusa.
    A mio avviso è il contrario. L'overload degli operatori tende a semplificare l'operazione che si vuole fare. Per te probabilmente è più comprensibile scrivere:
    cin.extract_int();
    cin.extract_double();
    cin.extract_pchar(); // pchar = char*
    Per me invece è più semplice cin >> var; // dove var è uno dei tre tipi definiti come funzione.
    Tra l'altro cin >> lo puoi richiamare come cin.operator >> e vediamo che alla fine è solo una funzione. Per di più l'overload delle funzioni è una prassi normale in C++. Pensa alla funzione swap: è più semplice avere n funzioni specifiche per ogni tipo, swap_int, swap_double etc... o una sola funzione swap che scambi due variabili usando per tutti i tipi la stessa sintassi?
    peccato che mi hanno levato gli interrupt assembler altrimenti mi sarei riscritto pure questo!
    Sarei curiosio di sapere come (e lo dico seriamente). Mettiamo che sia ancora possibile: come faresti a dire alla parte C/C++ che quello che inserisci da tastiera lo deve considerare un int invece di un double o di una stringa? In fondo quelli che entrano sono bytes grezzi.
    Il C risolve il problema fornendo una stringa di formattazione, il C++ invalidando l'input.
    In ogni caso non puoi gestire la conversione da ASM semplicemente perché non puoi sapere a priori in cosa i bytes grezzi vanno convertiti.
    la questione del controllo degli errori secondo me e di vitale inportanza in quanto gli errori si possono generare in 1000 modi e molto spesso non dipende dal programmatore.
    Guarda che non ho detto che non è importante controllare gli errori ma che tali controlli devono essere messi solo se indispensabili. Mettere un controllo tipo:
    
    char arrchar[16] = {0};
    for (int i = 0; i < 16; i++) {
        if (i < 16) arrchar[i] = (char) i;
    }
    
    è semplicemente assurdo dato che stiamo lavorando in un intervallo certo: rallenta solo l'esecuzione. Mettere un controllo tipo:
    
    char* arrchar = (char*) malloc(16);
    if (arrchar == NULL) {
        exit(1);
    }
    
    è invece la norma.
    il metterli fuori alla chiamata della funzione e un processo che può causare confusione.
    mentre inserendoli all'interno della funzione ciò non causerebbe nessun tipo di confusione.
    Ci sono errori che puoi controllare all'interno della funzione e altri che devi controllare al di fuori. Ma gli errori che devi controllare dentro la funzione, devono appartenere alla funzione stessa non alla chiamante. La domanda con cui appartiene il thread è fallace all'origine: è perfettamente lecito che io possa aspettarmi una stringa troncata. Invece é un errore se la funzione InsEtc... va in crash perché ho omesso un controllo "dentro" la funzione sulla validità dell'intervallo disponibile.
    Come un altro errore é aspettarsi che quel cptr e quel dptr siano sempre non NULL (altro controllo da inserire subito).

    Personalmente, al tuo posto, non mi sarei orientato sul C++ come linguaggio High Level. Il C++ vive di astrazioni, di sintassi "astruse" (neanche t'immagini che inferno possono essere i template al riguardo) e dei contorsionismi di cui ti lamenti.
    Io, per me, mi sarei orientato sul C (che si può benissimo usare anche su un compilatore C++ ovviamente) che è più lineare è molto più vicino all'ASM di quanto possa sembrare a prima vista. Niente sintassi astruse, niente complicazioni inutili, 1 funzione 1 compito etc.
    Vale quanto detto qui (umoristicamente parlando).
    http://michele.sciabarra.com/page/NonUsateQuelLinguaggio
    Però se intendi continuare con il C++, non lamentarti delle sintassi "astruse": è il linguaggio. Io potrei fare lo stesso con l'ASM (tipo: perché ho un gruppo di istruzioni per gli interi con segno, uno per gli interi senza segno e uno per i float)?
  • Re: Dimensioni

    Allora per quanto riguarda la cin sinceramente la potevano fare molto meglio.
    mettendo automaticamente nella funzione sia l'autoconversione che il reset del buffer nonche il controllo di validità dei dati.
    funzioni del genere esistono in tantissimi linguaggi mi sembra starno che non ci abbiano pensato!
    comunque bastava mettere all'inizio della funzione il reset del buffer magari legandolo alla variabile avrebbero scritto qualche riga di codice in più ma avrebbero avuto una funzione migliore.
    ed avrebbero risparmiato un bel pò di casini.
    visto che eri curioso ti mostro un abbozzo di come si faceva in assembler.
    mov dx,seg stringa da accettare 
    mov ds,dx 
    mov dx,offset stringa da accettare ; ds:dx indirizzo della variabile che si vuole accettare
    mov si,0 ;reset del buffer
    lettura:
    xor ax,ax
    int 16h ; accettazione carattere
    cmp al,0 ; controllo dei vari caratteri che si vogliono utilizzare
    je beccato un comando ; controllare il tasto funzione o comando di tastiera
    se volevo un campo numerico avrei fatto :
    cmp al,0dh
    je fine_accettazione ;mi termina l'input da tastiera
    cmp al,'-'
    je vedi se primo carattere  ; avanzavo di uno si e se era primo carattere lo accettavo altrimenti lo scartavo
    cmp al,'+'
    je vedi se primo carattere  ; avanzavo di uno si e se era primo carattere lo accettavo altrimenti lo scartavo
    cmp al'.'
    je mi setto un flag per poter gestire i floating point
    cmp al,'0'
    jl lettura ; scarto il carattere
    cmp al,9' 
    jg lettura ; scarto il carattere 
    prendi: mov byte ptr dx[si],al ; mi conservo il carattere
    inc si ; vado ad accettare altro carattere
    
    come vedi da questo spezzone non è poi cosi difficile fare una cin in assembler ma avendo inibito gli interrupt, a livello di programmazione, non la si può più fare così!
    overload delle funzioni questa me la devo studiare sapevo del overload degli operatori (un gran casino!) (grazie per l'informazione)
    neanche il c scherza prendi per esempio la printf o la scanf e una bella lotta con cin e cout per chi ha la sintassi più astrusa!
    per quanto riguarda i controlli da una parte hai raggione se si conoscono le dimensioni ok. ma quando le funzioni sono esterne può capitare che le dimensioni non si conoscono così converrebbe che si controllassero per evitare gli sfondamenti.
    questo tipo di errori può capitare quando un vettore si riempie facendo dei calcoli e passare ogni volta le dimensioni sarebbe una cosa assurda non trovi?
    perché ho un gruppo di istruzioni per gli interi con segno, uno per gli interi senza segno e uno per i float
    in assembler si hanno solo 2 set di istruzioni quello per gli interi e quello per i floating poit.
    questo e dovuto al fatto che alla gestione dei floating point e adibito il coprocessore matematico mentre i numeri interi vengono gestiti direttamente dal processore.
    gli interi con segno si possono gestire anche con le istruzioni normali.
    se hai qualche istruzione assembler che non capisci chiedi pure purche sia per x86- pentium - 16 e 32 bit oppure per microprocessori pic.
    comunque provero a non lamentarmi più delle astrusità delle sintassi del c++.
  • Re: Dimensioni

    Spezzo in due anche questo.

    smalldragon ha scritto:


    allora per quanto riguarda la cin sinceramente la potevano fare molto meglio.
    mettendo automaticamente nella funzione sia l'autoconversione che il reset del buffer nonche il controllo di validità dei dati.
    La conversione c'è (altrimenti non potresti avere i bytes grezzi convertiti in int ad esempio), il controllo c'è (se inserisci un double al posto di un int, lo stream si invalida). Manca il reset del buffer ma a quello si può pensare esternamente.

    funzioni del genere esistono in tantissimi linguaggi mi sembra starno che non ci abbiano pensato!
    comunque bastava mettere all'inizio della funzione il reset del buffer magari legandolo alla variabile avrebbero scritto qualche riga di codice in più ma avrebbero avuto una funzione migliore.
    ed avrebbero risparmiato un bel pò di casini.
    Probabilmente ci hanno pensato e hanno deciso che il controllo era oneroso per le prestazioni. Se ti aspetti un int e inserisci un int, il controllo è superfluo e danneggia le prestazioni; se ti aspetti un int e inserisci un double, la colpa non è di cin ma di chi inserisce il dato.
    Comunque hai ragione su questo punto, ma se consideri cin una primitiva del linguaggio, nessuno ti impedisce di creare una funzione auto correttiva usando altri costrutti base.
    Ma anche così risolvi solo una parte del problema: se ti aspetti in input un int e io continuo a inserire double, l'unica cosa che ottieni e non invalidare l'input ma il dato resta sbagliato.
    come vedi da questo spezzone non è poi cosi difficile fare una cin in assembler ma avendo inibito gli interrupt, a livello di programmazione, non la si può più fare così!
    Lo spezzone è interessante, ma forse ti è sfuggito il senso del discorso: in base a che criterio decidi che quello che ottieni in input debba essere un float e non una stringa?
    Se io inserisco 1.23 hai informazioni sufficienti per sapere se il dato dev'essere acquisito come stringa o come float? Risposta no. Perché se tu mi dici che è un float io ti rispondo che dev'essere acquisito come "1.23"; se mi dici ok, lo acquisisco come "1.23", io ti rispondo che lo voglio float 1.23
    Semplicemente non hai informazioni su come trattare il dato fino a che non espliciti in cosa lo vuoi convertire. Ed è questa operazione che si rivela fallace a prescindere dal modo di ottenere l'input da tastiera.
    overload delle funzioni questa me la devo studiare sapevo del overload degli operatori (un gran casino!) (grazie per l'informazione)
    E' solo perché non ci hai preso la mano. Ma se ci pensi un attimo è più semplice esplicitare una somma tra entità con l'operatore + piuttosto che scrive mille mila funzioni sum_qualcosa che da un punto di vista concettuale non significa molto.
    neanche il c scherza prendi per esempio la printf o la scanf e una bella lotta con cin e cout per chi ha la sintassi più astrusa!
    Astrusa forse, ma inevitabile. Del resto il problema è sempre quello: come indicare alla funzione in esame di trattare i dati in un certo modo invece che in un altro. Del resto printf e scanf accettano una stringa di formattazione e un numero pressoché infinito di parametri, perciò in qualche modo bisogna dire sia quanti sono sia di che tipo sono.
    per quanto riguarda i controlli da una parte hai raggione se si conoscono le dimensioni ok. ma quando le funzioni sono esterne può capitare che le dimensioni non si conoscono così converrebbe che si controllassero per evitare gli sfondamenti.
    Ovvio. Quello che sto dicendo è che tali controlli non sempre possono essere fatti all'interno della funzione. Prendiamo di nuovo la tua funzione : InsRightParola (solo la parte iniziale).
    
    int InsRightParola(char *cptr,char *dptr,)
       {
       int indy,errore,k;
           indy = 0; k = 0;
             int maxa,maxb,maxstr;
             maxa=LenStringa(cptr);
             maxb=LenStringa(cptr)
    
    
    Già qui fai alcuni errori di concetto.
    Ricevi dei char* e la funzione non ha informazioni per sapere cosa siano questi char*: possono essere dei buffer, delle stringhe ASCIIZ, un puntatore a un singolo carattere, un puntatore a un buffer dinamico o un altro puntatore a char.
    In altre parole tutte queste chiamate sono valide.
    
    char a; char b;
    char c[16]; char d[16];
    char *x= NULL, *y=NULL;
    char* pc = new char[16];
    InsRightParola(&a,&b);
    InsRightParola(c,d);
    InsRightParola(x,y);
    InsRightParola(pc,&b);
    
    Al suo interno InsRightParola può solo dire: se quel che ricevo non è NULL facciamo qualcosa.
    Ma questo fare qualcosa è subordinato al fatto che chi chiama la funzione abbia informazioni su che cosa tratta la funzione. Ad esempio: InsRightParola unisce la parola destra puntata da dptr con quella a sinistra puntata da cptr se, e solo se, sia cptr e dptr rappresentano delle ASCIIZ string. Se cptr o dptr sono NULL non viene effettuata nessuna operazione. Se cptr o dptr non sono ASCIIZ string (puntatori a un singolo carattere) la funzione ha comportamento indefinito.
    Se cptr e dptr sono due ASCIIZ, cptr deve poter contenere la stringa unita altrimenti il comportamento è indefinito.
    questo tipo di errori può capitare quando un vettore si riempie facendo dei calcoli e passare ogni volta le dimensioni sarebbe una cosa assurda non trovi?
    Per niente: anzi è l'unico modo per evitare sfondamenti indesiderati. Funzioni come la strcpy o la gets sono di fatto deprecate proprio perché non hanno in input l'intervallo di validità su cui operare. Di fatto quello che chiedi è provvisto di serie sotto forma di std::string.
    
    std::string a = "Questa è ";
    std::string b = "una stringa unita";
    a+=b;
    std::cout << a << std::endl;
    
  • Re: Dimensioni

    in assembler si hanno solo 2 set di istruzioni quello per gli interi e quello per i floating poit.
    questo e dovuto al fatto che alla gestione dei floating point e adibito il coprocessore matematico mentre i numeri interi vengono gestiti direttamente dal processore.
    gli interi con segno si possono gestire anche con le istruzioni normali.
    Mi risulta che ad esempio MUL e DIV sono per interi senza segno; IMUL e IDIV sono per interi senza segno. Corretto?
    se hai qualche istruzione assembler che non capisci chiedi pure purche sia per x86- pentium - 16 e 32 bit oppure per microprocessori pic.
    Tnx. Prima o poi dovrò decidermi a impararlo sto ASM.
    comunque provero a non lamentarmi più delle astrusità delle sintassi del c++.
    Non fa mai male dibattere su aspetti controversi di un linguaggio. Per esempio a me la sintassi del basic fa rizzare i capelli in testa, ma il linguaggio è quello: prendere o lasciare.
    Ti lascio un altro link riguardo il passaggio di parametri da C e ASM.
    http://www.drpaulcarter.com/pcasm
    in fondo alla pagina c'è la versione italiana. Nel punto 4.7 è spiegato come intefacciare C e ASM.
    Buona lettura.
  • Re: Dimensioni

    Ci avevo già pensato a riscrivere la cin e la cout ma pultroppo non ho le conoscenze sufficienti per poterlo fare!
    quindi finchè non le acquisisco ahime me le dovrò tenere cosi come sono.
    nella mia povera funzione InsRightParola
    char *cptr e char *dptr ; sono dei puntatori a stringa ma vanno bene anche per i buffer
    sinceramente non vedo la convenienza di utilizzare un puntatore ad un singolo carattere.
    la funzione non fa niente altro che aggiungere la stringa dptr alla fine della stringa cptr.
    il dover passare ogni volta le dimensioni delle stringhe sinceramente è una cosa assurda
    non tanto per questa funzione che unisce semplicemente 2 stringhe ma metti caso che ci fossero 10 stringhe da unire sarebbe assurdo ed ingestibile passargli 20 parametri.
    non che poi il fatto che normalmente le stringhe vengono sovradimensionate per evitare facili sfondamenti.
    anche per questo occorrerebbe un sistema per controllare le dimensioni all'interno delle funzioni.
    per quanto riguarda l'assembler ti consiglio vivamente di impararlo e un linguaggio bellissimo ed anche semplicissimo.
Devi accedere o registrarti per scrivere nel forum
21 risposte