Newsgroup: it.comp.lang.c
Titolo: Primi Passi Difficili - VETTORI

Ciao a Tutti,
    ancora alla prese con il testo Linguaggio C - Kernighan - Ritchie
    Purtroppo procedo lentamente, il tempo è tiranno, ma non vorrei
procedere, lasciando dei dubbi...
Estraggo una parte di codice:
#include <stdio.h>
int main(void)                    /* non ho ancora ben capito il significato
di "int e void"  il libro propone semplicemnte "main( )" ed in effetti il
risultato non cambia.*/
{
    int c, i, , nc;
    int nc[10];
    nc=0;
    for (i=0; i<10; ++i)
        nc[i]=0;
    while((c=getchar())!='\n')
     {
          if(c>='0' && c<='9')
           ++nc[c-'0'];     /* ********non riesco a cpaire perché come
contatore devo mettere c-'0' ********* */
 }
........
Visto che l'istruzione "if" verifica che si tratta di una cifra tra 0 e 9,
mi incrementa il rispettivo contatore dell'array con indice corrispondente
alla cifra:
*** ma se c è un numero, perché devo mettero "c-'0'" e non semplicemente c
??? ****
Come faccio ad inizializzare un Vettore, senza sapere a priori quanti
elementi conterrà?
Devo per forza inizializzarlo con un valore "potenziale massimo" di elementi
????
**Grazie per la disponibilità**

????
In C99 puoi indicare la dimensione massima di un array usando una
variabile, quindi il tuo problema si risolve facilmente.
In C89 tu non puoi, ma devi passargli una dimensione a priori.
Le soluzioni che ti si presentano sono 2:
1) gli passi una dimensione sufficientemente grande da contenere anche
il caso peggiore
2) usi la malloc() che ti verra' spiegata piu' avanti nel K&R... se
non ci sei ancora arrivato non e' il caso che te lo spieghi adesso. Ti
dico solo che cerca una locazione di memoria di N byte (dove N e' il
parametro che gli passi) e te ne ritorna l'indirizzo, tutto questo a
runtime ovviamente. Per usarla pero' devi aver capito bene la
differenza cha array e puntatore.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 massimo" di elementi ????
Puoi anche inizializzare il vettore con un valore massimo se questo non
comporta un dispendio eccessivo di memoria.
Altrimenti puoi usare l'allocazione dinamica. In pratica definisci non un
vettore ma un puntatore al tipo che ti interessa e lo allochi con malloc() e
lo riallochi con realloc().
Ad esempio:
    // invece di:
    // int v[10];
    int *v;
    v = malloc(sizeof(int) * 10);        // allochi lo spazio per 10 interi
    v[0] = 18;
    ...
    // ora devi far posto a 50 elementi:
    v = realloc(v, sizeof(int) * 50);
Maurizio.

 variabile, quindi il tuo problema si risolve facilmente.
Anche nel C99  valgono le stesse considerazioni che fai  per il C89. Non
si puo` magicamente cambiare la  dimensione dell'array all'interno di un
blocco  di codice. La  dimensione  viene definita  alla dichiarazione  e
rimane fissa. La possibilita` di usare  array di dimensione variabile e`
apprezzabile soprattuto nelle funzioni:
void foo(int size) {
	int bar[size];
	...
}
In questo caso  la dimensione di bar viene determinata  a runtime e puo`
variare da  chiamata a  chiamata. Un altro caso  in cui  possono tornare
utili  e` se  i dati  che  devono essere  memorizzati sono  strettamente
locali ad un blocco:
int main() {
	int n;
	printf("Quanti elementi vuoi inserire? ");
	scanf("%d", &n);
	{
		int c;
		int data[n];
		for (c = 0; c < n; c++) {
			....
		}
	}
	return 0;
}
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Se alla sera, dopo una strepitosa vittoria, guardandoti allo
specchio dovessi notare un secondo paio di palle, che il tuo 
cuore non si riempia d'orgoglio, perche` vuol dire che ti 
stanno inculando -- Saggio Cinese

Provo a chiarire i tuoi dubbi:
- "main" č una funzione molto particolare (da lě parte l'esecuzione del
programma), ma č pur sempre una funzione. Ogni funzione č caratterizzata da:
1) un tipo di ritorno (se non specificato il tipo di default č "int", cioč
un numero intero);
2) un nome;
3) una lista di parametri.
Il tipo "void" č un tipo strano, perché puň rappresentare sia la variabile
"nulla" che la variabile "generica", ma questo č meglio vederlo quando sarai
un pň piů pratico. Per ora ti basta sapere che "main()" e "int main(void)"
hanno lo stesso effetto, ma il secondo č un pň piů elegante.
- nel contatore del vettore devi mettere c - '0' e non semplicemente c
perché nella variabile c viene messo il codice ASCII del carattere cifra
letto, non la cifra medesima. Dato che nella tabella ASCII le cifre da 0 a 9
sono consecutive ('0' --> 48, '1' --> 49... '9' --> 57) facendo l'operazione
c - '0' ottieni il valore proprio della cifra immessa da tastiera.
- si possono definire vettori di dimensione non fissa a priori, occorre
usare l'istruzione "malloc", che perň coinvolge la conoscenza del tipo
"void", quindi forse per il momento č un pň presto.
Spero di averti chiarito i dubbi.

apprezzabile soprattuto nelle funzioni:
Colpa mia: lo sapevo, ma nella spiegazione l'ho data per scontato.


hanno lo stesso effetto, ma il secondo è un pò più elegante.
Una precisazione. Il void di per se rappresenta solo il "NULLA". Il
void in effeti lo puoi usare per dichiarare che una funzione non
accetta parametri o che non ritorna nessun valore (un po' come le
procedure nel pascal).
Non puoi pero' avere variabili di tipo void (mi pare anche ovvio).
Molto diverso dal void e' il void *, conosciuto anche come generic
pointer (quello che Stefano ha indicato come "variabile generica").
Questo e' quello che Stefano ha indicato come variabile generica,
anche se forse e' piu' chiaro se lo vedi come un puntatore che puo'
riferirsi a qualunque cosa.
Pero' non e' il caso di parlarne ora.


> int main() /* equivalente a int main(void) */
Scusate, magari č ignoranza mia, ma credevo che un prototipo tipo
int pinco();
equivalesse a
int pinco(...)
e non a
int pinco(void) (come al contrario avviene in C++).
Quale delle 2 č giusta?
Saluti,
Lanugo

 int pinco(void) 
int  pinco(...) e`  undefined (deve  esserci almeno  un argomento).   La
forma:
int foo();
e`  la  cosidetta  not  prototype-format parameter  type  declarators  e
differisce da un normale prototipo in quando non permette al compilatore
di fare alcun controllo sul numero  e sul tipo di parametri passati. Nel
C99  questa  feature  e`  considerata   obsoleta  ma  e`  mantenuta  per
compatibilita`.
int foo() non equivale a int foo(void) (quest'ultimo e` un prototipo).
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Io mi ricordo sempre il compleanno della mia ragazza:
cade il giorno dopo di quando lei me lo ricorda