Pagina 1 di 3
[Risolto][C] keyword static
Inviato: mercoledì 29 aprile 2015, 19:19
da gila75
Ciao a tutti

Sto studiando la suddivisione di un programma in più programmi: main.c i vari moduli.c e le interfacce per i moduli .h
Mi sto avvicinando al concetto di stack adt e queste cose sono un po' alla base.
Un passo indietro viene il concetto di "information hilding" cioè il fatto di nascondere alcune informazioni, per non essere corrotte.
Chiedo scusa se sono inesatto, ma sono agli inizi.
ho scritto un semplice programma, il famoso cerca occorrenze con strstr(), ma l'ho diviso in 3 parti:
main.c:
Codice: Seleziona tutto
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "search_str.h"
int main(void)
{
char str [500]="oggi vado a casa mia dolce casa";
char word[500]="casa";
int n=0;
printf ("in main:trovati %d\n",search (str,n,word));
return 0;
}
searc.c :
Codice: Seleziona tutto
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "search_str.h"
void static prova(int n)
{
printf ("in funzione static: trovate n %d occorrenze\n ",n);
}
int search(char copy_str[],int n,char copy_word[] )
{
char *found;
char *p=copy_str;
int len;
len=strlen(copy_word);
while (*p!='\0')
{
found=strstr(p, copy_word);
if (found==NULL)
return 0;
p=found+len;
n++;
printf ("trovato in pos %d\n", found-copy_str);
}
if (n==2)
prova(n);
return n;
}
e serach_str.h
Codice: Seleziona tutto
#ifndef SEARCH_H
#define SEARCH_H
int search(char copy_str[],int n,char copy_word[] );
#endif
nel file .h sono definiti i prototipi delle funzioni mentre in search.c sono implementate.
Ora da quello che ho capito per nascondere informazioni si usa la keyword static.
Per esempio potrei implementare una funzione in search .c che deve essere svolta solo in quel modulo e non essere corrotta.
Quello che non mi è chiaro è che anche senza static non mi cambia nulla, tanto se nel file header non la dichiaro il main non la potrà chiamare giusto?
Guardate qua:
search.c
Codice: Seleziona tutto
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "search_str.h"
void static prova(int n)
{
printf ("in funzione static: trovate n %d occorrenze\n ",n);
}
int search(char copy_str[],int n,char copy_word[] )
{
char *found;
char *p=copy_str;
int len;
len=strlen(copy_word);
while (*p!='\0')
{
found=strstr(p, copy_word);
if (found==NULL)
return 0;
p=found+len;
n++;
printf ("trovato in pos %d\n", found-copy_str);
}
if (n==2)
prova(n);
return n;
}
come vedete ho aggiunto la funzione:
Codice: Seleziona tutto
void static prova(int n)
{
printf ("in funzione static: trovate n %d occorrenze\n ",n);
}
che non è presente nel file.h ma anche senza la keyword static funziona lo stesso.
Ok, quella è solo una banalissima stampa. Ma non capisco.
Riassumo:
Se non dichiaro la funzione nel file.h, il main non la potrà chiamare, di conseguenza come posso correre il rischio di corromperla?
Re: [C] keyword static
Inviato: mercoledì 29 aprile 2015, 19:34
da vbextreme
static a livello globale significa 'privato' e quindi nessuno può accedervi.
capita spesso che certe funzioni o variabili globali debbano risultare 'invisibili' al di fuori del modulo.
Serve per ragioni di sicurezza, se guardi alla easyconsole vedrai parecchie variabili globali statiche, ad esempio una serve per sapere se si sta lavorando in maniera asincrona oppure no, ma se venisse manipolata all esterno senza la corretta procedura sarebbe un bel guaio e perciò è stata dichiarata come statica.
Dentro ad una funzione invece assume la forma di una variabile globale ma con visibilità solo interna ad essa.
Re: [C] keyword static
Inviato: mercoledì 29 aprile 2015, 19:55
da gila75
Dentro ad una funzione invece assume la forma di una variabile globale ma con visibilità solo interna ad essa.
Ok, qui ci sono
Serve per ragioni di sicurezza, se guardi alla easyconsole vedrai parecchie variabili globali statiche, ad esempio una serve per sapere se si sta lavorando in maniera asincrona oppure no, ma se venisse manipolata all esterno senza la corretta procedura sarebbe un bel guaio e perciò è stata dichiarata come statica.
Qui invece no
Non capisco, se tanto nel file. h non è dichirata, come fa il main o altro a corromperla. In quel dato modulo eseguirà ciò che deve fare e stop, no?
Devo capire un po'
Intanto grazie
Re: [C] keyword static
Inviato: mercoledì 29 aprile 2015, 20:16
da vbextreme
allora metti il caso tu scriva:
ora in qualsiasi modulo potresti scrivere
e avresti cosi l'accesso alla variabile, se invece la dichiari static la "confini" all'interno del modulo stesso.
Stesso discorso per le funzioni, che non è detto che siano state pre dichiarate in qualche header, ma se la prototipi potrai usarla almeno che lei non sia stata dichiarata come static.
Questo permette diversi livelli di sicurezza, ad esempio le funzioni più sicure potresti metterle nell'header, altre potresti deliberatamente non metterle, obbligando la lettura del manuale prima di venirne a conoscenza aumentando cosi la sicurezza, altre ancora non vuoi che siano chiamate al di fuori del modulo ed allora le dichiari come static.
Re: [C] keyword static
Inviato: mercoledì 29 aprile 2015, 21:07
da gila75
Grazie Vb. Per qualche giorno non potrò smanettare col C, poi ci studio su e al massimo chiedo se ho dubbi

Re: [C] keyword static
Inviato: sabato 2 maggio 2015, 16:25
da rpadovani
Oltre alla visibilità, come spiegato da vbextreme, static modifica il tipo di allocamento della variabile - una variabile statica mantiene lo stesso valore per tutta la durata del programma, mentre una variabile dinamica viene allocata ad ogni chiamata di funzione.
Facciamo un semplice esempio:
Codice: Seleziona tutto
#include <stdio.h>
void static_allocation(void)
{
int static x = 0;
x++;
printf("Static: %i\n", x);
}
void dynamic_allocation(void)
{
int x = 0;
x++;
printf("Dynamic: %i\n", x);
}
int main(int argc, char const *argv[])
{
static_allocation();
static_allocation();
static_allocation();
static_allocation();
dynamic_allocation();
dynamic_allocation();
dynamic_allocation();
dynamic_allocation();
return 0;
}
L'output è:
Codice: Seleziona tutto
Static: 1
Static: 2
Static: 3
Static: 4
Dynamic: 1
Dynamic: 1
Dynamic: 1
Dynamic: 1
In questo esempio la visibilità delle due variabili è la stessa: la funzione.
Re: [C] keyword static
Inviato: sabato 2 maggio 2015, 20:21
da SuperStep
Tanto per aggiungere qualcosa anche io:
La keyword static utilizzata in un contesto di OOP (programmazione orientata agli oggetti) in una classe,
esempio:
Codice: Seleziona tutto
class A { <modificatore d'accesso> static <tipo> variabile; }
fa si che l'attributo "variabile" sia condiviso con tutte le instanze della stessa classe
esempio
Codice: Seleziona tutto
class A {
public static int x = 0;
}
A a1 = new A();
A a2 = new A();
a1.x = 10;
funzione_print(a2.x);
il metodo "funzione_print" stampera' il valore di a2.x che e' il medesimo di a1.x (quindi 10).
Re: [C] keyword static
Inviato: sabato 2 maggio 2015, 21:23
da vbextreme
oltre alla visibilità, come spiegato da vbextreme, static modifica il tipo di allocamento della variabile - una variabile statica mantiene lo stesso valore per tutta la durata del programma, mentre una variabile dinamica viene allocata ad ogni chiamata di funzione
Questa affermazione è abbastanza ambigua e può portare confusione.
Come ho detto sopra una variabile static è una variabile globale al quale si cambia lo scope.
Se la si dichiara a livello di modulo tutti(i componenti del modulo stesso) ne avranno accesso e se si dichiara a livello di funzione solo i propri 'derivati' potranno accedervi, ma sempre di variabile globale parliamo, ma con scope diverso.
E non è detto che mantenga sempre lo stesso valore almeno che non si sia aggiunta la clausula 'const' essa potra essere modificata a proprio piacimento.
Forse la dichiarazione static è la piu ambigua di tutte, o forse no....
Forse un
x = x**x+++x;
potrebbe batterla, ma il c è bello proprio per quello
Re: [C] keyword static
Inviato: sabato 2 maggio 2015, 23:01
da gila75
Grazie ragazzi. Vi sto leggendo ma non sono a casa. Appena torno provo tutto e arrivo con le domande.
Static se non erro ha scope di file e collegamento interno se fuori da una funzione.
In un funzione invece cambiano alcune regole.
In definitiva potrebbe essere intesa come una variabile globale in un programma, ma non globale per altri moduli.
Per ora mi fermo perché sono in gita a Roma e non sto studiando.
Comunque grazie a tutti per ora

Re: [C] keyword static
Inviato: domenica 3 maggio 2015, 13:04
da rpadovani
vbextreme [url=http://forum.ubuntu-it.org/viewtopic.php?p=4753171#p4753171][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
oltre alla visibilità, come spiegato da vbextreme, static modifica il tipo di allocamento della variabile - una variabile statica mantiene lo stesso valore per tutta la durata del programma, mentre una variabile dinamica viene allocata ad ogni chiamata di funzione
Come ho detto sopra una variabile static è una variabile globale al quale si cambia lo scope.
Se la si dichiara a livello di modulo tutti(i componenti del modulo stesso) ne avranno accesso e se si dichiara a livello di funzione solo i propri 'derivati' potranno accedervi, ma sempre di variabile globale parliamo, ma con scope diverso.
No, le variabili static dichiarate dentro una funzione non sono globali, sono locali. Il K&R è abbastanza chiaro su questo (4.6):
La dichiarazione static è applicabile anche alle variabii interne. Il campo di visiblità delle variabili interne static è limitato a una particolare funzione, proprio come le variabili automatiche
Giusto volevo dire che hanno un ciclo di vita unico per tutto il programma, non certo che non cambiano valore

Re: [C] keyword static
Inviato: domenica 3 maggio 2015, 14:36
da M_A_W_ 1968
Brevemente, perché i forum non possono e non devono sostituirsi ad un buon manuale (definizione che, come già reiteratamente specificato, non è applicabile a quel mezzo kg di carta rilegata che il buon gila si ritrova per le mani): le classi di memorizzazione specificate dagli standard del linguaggio sono quattro e includono auto (il default per qualsiasi variabile dichiarata entro un blocco sintattico, i.e. una coppia bilanciata di parentesi graffe, che ne delimita anche lo scope), static, extern e register.
Quando si affronta questo tema, gli aspetti assolutamente fondamentali da considerare sono due: lo scope (determinato a livello logico dal solo compilatore) e la effettiva collocazione in memoria (un fattore molto più strettamente architetturale).
Trascurando la keyword register, che qui non è rilevante, sullo scope delle variabili auto, static ed extern non devono sussistere dubbi. Le variabili auto sono "visibili" da un punto di vista logico unicamente entro la coppia di parentesi graffe più vicine (blocco sintattico di massimo nesting).
Le variabili static, per contro, hanno uno scope che dipende dalla posizione della dichiarazione: locale e cioé identico a quelle auto se dichiarate entro un blocco sintattico, o esteso all'intero modulo (unità sintattica) se dichiarate fuori da qualsiasi blocco sintattico.
Infine, la keyword extern è destinata unicamente all'estensione della visibilità logica (scope) tra diverse unità di compilazione, una sola delle quali contiene la effettiva dichiarazione della variabile.
Riguardo invece alla effettiva collocazione in memoria, limitando lo sguardo al piccolo e noioso mondo dei PC mainstream, le variabili auto finiscono invariabilmente nello stack, mentre le static sono normalmente allocate nello heap. Il che consente loro, peraltro, di conservare il valore assunto tra due chiamate di funzione, nel caso di static "locali", mentre il contenuto dello stack frame è notoriamente "a perdere" al termine della chiamata di funzione.
Il tutto senza peraltro dimenticare, come già richiamato più volte, che l'uso del qualificatore const può tranquillamente spostare tale allocazione in un segmento di memoria strettamente di sola lettura.
Ancora diverso è il caso del qualificatore static anteposto alla dichiarazione di una funzione: ciò ne limita semplicemente lo scope all'unità sintattica (sorgente) corrente.
Re: [C] keyword static
Inviato: domenica 3 maggio 2015, 16:37
da vbextreme
No, le variabili static dichiarate dentro una funzione non sono globali, sono locali. Il K&R è abbastanza chiaro su questo (4.6):
Veramente dice che IL CAMPO DI VISIBILITÀ e dunque lo scope è relegato all'interno della funzione.
static può essere paragonato(in alcuni aspetti) al private dei più blasonati linguaggi oop.
Del resto maw è stato come sempre molto chiaro.
Re: [C] keyword static
Inviato: domenica 3 maggio 2015, 22:48
da gila75
OK MAW il manuale non sarà dei migliori,ma non è forse corretto ciò che ho detto nel mio ultimo post ?
Fuori da una funzione una variabile static ha scope di file e collegamento interno no ?
Rispondimi a questo se è corretto.... Una cosa alla volta

Re: [C] keyword static
Inviato: martedì 5 maggio 2015, 18:03
da gila75
Brevemente, perché i forum non possono e non devono sostituirsi ad un buon manuale (definizione che, come già reiteratamente specificato, non è applicabile a quel mezzo kg di carta rilegata che il buon gila si ritrova per le mani):
Piccola divagazione, ma che può essere di aiuto a tutti.
@M_A_W: non mi risulta che
come testo di base "Programmare in C" di Kim n.King sia proprio fuffa.
Domanda lo hai sfogliato, o lo scarti solo perchè non è tra l'olimpo dei libri che hai elencato più volte?
Facilmente non risponderai, ma io scrivo lo stesso.
Ora riprendo con lo studio sul mezzo kg di carta straccia....e altri libri pattume

Re: [C] keyword static
Inviato: martedì 5 maggio 2015, 19:55
da vbextreme
La bibbia stessa k&r in questo stesso thread è stata fraintesa.
Un libro non basta certo, e non basta leggerlo una volta.
Ogni libro ha poi i suoi pro e i suoi contro, bisogna solo imparare a leggere e rileggere.
Ovvio poi che MAW possa solo incentivarci a migliorare.
Re: [C] keyword static
Inviato: martedì 5 maggio 2015, 20:06
da gila75
Ovvio poi che MAW possa solo incentivarci a migliorare.
Certo che si Vb.
ma a sto punto dico riferito a M_A_W e certo senza polemica:
Il libro da me proposto lo conosce e quindi con certezza è una schifezza o solo perchè non presente tra i superblasonati non è degno di nota ?
Il mio ultimo intervento nel post è corretto?
Credo vadano date risposte in base alle domande e non giri molto larghi che poi l'utente in questione (io) non può capire.
per ora io chiedo solo questo :
Fuori da una funzione una variabile static ha scope di file e collegamento interno no ?
Rispondimi a questo se è corretto.... Una cosa alla volta

Tutto qui. Sono molto prolisso a volte ma qui chiedo conferma solo di poche cose alla volta

Re: [C] keyword static
Inviato: martedì 5 maggio 2015, 23:23
da M_A_W_ 1968
Credo di essermi già spiegato a sufficienza in
questo post. Per ovvi obblighi professionali, ho valutato a suo tempo tra i tanti anche codesto manuale, scartandolo per la sua pessima qualità. Le bibliografie serie, mie o altrui (colgo anzi l'occasione per ringraziare i numerosi entusiasti
evangelist che ripropongono pedissequamente i miei post bibliografici un po' ovunque sul web, sovente - come vogliamo dirlo? -
dimenticandosi distrattamente di citarne la fonte e l'autore), non sono scolpite nella pietra sotto dettatura di un cespuglio infuocato
in coppa al monte Sinai, ma costruite gradualmente includendo i testi rivelatisi maggiormente efficaci dal punto di vista didattico, in anni e anni di insegnamento del linguaggio C e dei suoi innumerevoli utilizzi, con relative norme, coding standards, eccetera. Dunque la logica è esattamente invertita rispetto alla frase riportata: codesto capolavoro letterario non fa parte delle bibliografie consigliate perché è generalmente considerato (non solo dal sottoscritto, ma da ben più vaste e qualificate platee) un testo scarso, approssimativo, farraginoso ed incompleto. Il fatto che la tipica anarchia di Internet e una serie di leggi inerenti la sfiga universale (vedi Murhpy, Crane e dintorni) facciano in modo che sul web si trovino anche irrilevanti recensioni positive di libri-immondizia, scritte da incompetenti e homines unium libri (nel senso ovviamente peggiore), non è certo affar mio, né può essere addotto a "prova" della bontà di veri e propri obbrobbri come i Deitel o il Malik o che so io. Il mondo della conoscenza non funziona per alzata di mano, nonostante alcuni pessimi esempi a tutti ben noti.
Peraltro, leggendo i tuoi interventi, la strutturale incompletezza di codesto libro si deduce facilmente anche dal fatto che chi ha studiato su altri testi non pone domande basilari come quelle che spesso ti trovi costretto a fare, e anzi di norma ne conosce anche le risposte, seppure magari parziali.
Come già spiegato, una variabile static dichiarata al di fuori di un qualsiasi
blocco sintattico (quindi a maggior ragione anche di una qualsiasi funzione) ha scope di modulo sorgente e costituisce, a tutti gli effetti, una variabile condivisa da tutte le funzioni presenti nel sorgente medesimo. Cosa è un blocco sintattico in linguaggio C? Repetita juvant. E' una qualsiasi coppia corrispondente di parentesi graffe, aperta e chiusa. E cosa delimita la definizione di una funzione? Un blocco sintattico, per l'appunto.
Re: [C] keyword static
Inviato: mercoledì 6 maggio 2015, 7:30
da gila75
Ok. ora sono soddisfatto. Peccato, a me sembrava buono come testo base.
Peraltro, leggendo i tuoi interventi, la strutturale incompletezza di codesto libro si deduce facilmente anche dal fatto che chi ha studiato su altri testi non pone domande basilari come quelle che spesso ti trovi costretto a fare, e anzi di norma ne conosce anche le risposte, seppure magari parziali.
Magari quello è un limite mio e non colpa del libro. Può essere che io sia un po' zuccone

e anche che il C non è così facile come linguaggio.
Calcolando poi che iniziare a 40 anni da zero è un pò dura
Ok M_A_W ti ringrazio
Re: [C] keyword static
Inviato: mercoledì 6 maggio 2015, 10:41
da vbextreme
veramente il c in se stesso è uno dei linguaggi più 'semplici', lo si deduce anche dalle dimensioni dei libri che spesso non superano le 200 pagine, pochissime, considerando che certi linguaggi hanno libri che superano le 600 pagine per parlare solo sommariamente del linguaggio, veri e propri mattoni...
Questa sua 'semplicita' però permette di fare cose complicatissime e qui nascono i guai...
Ribadisco anche che non tutto si può capire subito, ad esempio sul k&r viene illustrato il funzionamento della malloc(), subito ho pensato di aver ben capito ma una mia vera implementaziome di tale funzione sono riuscita a costruirla solo dopo anni.
Non ti dico nemmeno quante volte ho letto e riletto quel capitolo...
Re: [C] keyword static
Inviato: mercoledì 6 maggio 2015, 14:04
da M_A_W_ 1968
Considerazione sicuramente sensata. Il linguaggio C è semplicemente l'astrazione più elementare di un macroassemblatore, reso il più possibile portabile: dai DEC PdP7 e 11 sui quali è nato alle miriadi di piattaforme che oggi offrono null'altro che il proprio assembler e un (cross-)compilatore C quasi-C'89, la strada è stata molto lunga ma le tendenze di "universalità" del linguaggio sono emerse chiaramente fin da subito. La libreria standard è limitatissima, anche se gli standard successivi al C'89 (ampissimamente disattesi, in realtà, ed implementati appieno solo da una manciatina di compilatori mainstream) hanno tentato di estenderla in varie direzioni, e molte delle funzioni di base offerte sono anche deprecate.
Il linguaggio in sè è decisamente primitivo, grezzo e implementa unicamente i concetti più elementari dei classici linguaggi imperativi di terza generazione, essendo in questo pienamente figlio del tempo in cui venne concepito. Perfino le banali stringhe ASCII-Z sono un lusso in C, gli array multidimensionali sono mera prestidigitazione sintattica, e così via. Dunque il manuale non deve neppure affannarsi a spiegare concetti un po' più elaborati, come currying, lambda functions, traits, mixin, tipi dinamici, strutture dati avanzate e programmazione generica con ADT (anche se tutto ciò è ampiamente possibile sia in C che in Assembly, come pure le implementazioni pseudo-OOP, ma ovviamente con supporto
nullo da parte del compilatore!). Allo stesso modo, anche il supporto alla segregazione degli scope e l'enforcement del criterio di Parnas sono decisamente ridottissimi, come appena visto nel presente thread, e non vanno molto oltre le implementazioni dei macroassembler più sofisticati che supportano label con scope variamente localizzato, tramite notazioni particolari (tipicamente prefissi come @, @@ o sequenze di underscore).
In realtà un vero manuale sul linguaggio C dovrebbe avere non meno di 1.200 pagine, e non sono mancate proposte in tal senso. Perché un manuale del genere dovrebbe descrivere, ad esempio, la "Programmazione in linguaggio C in ambiente Linux" e dovrebbe contenere non solo la banalissima sintassi del linguaggio e una descrizione delle varie funzioni nella standard library, ma anche approfondire tutti gli aspetti di interazione col sistema e l'architettura, le funzioni Posix, le peculiarità delle varie implementazioni, le idiosincrasie di GCC, e molto altro ancora, inclusi capitoli sull'engineering e le norme di stile, sulla stesura di demoni e kernel device drivers, le tecniche di gestione della memoria...
Perché questo, alla fine, significa padroneggiare un linguaggio come il C: conoscere decine di librerie, valutare e misurare le
prestazioni, saper rispettare uno stringente standard di codifica, strutturare il codice per applicazioni specifiche (i.e. driver, modulo per plug-in, etc.), in sostanza saper usare appieno il linguaggio in un contesto fortemente verticale. Che sia un SO mainstream come Linux o Windows, uno dei mille cloni DOS ancora diffusissimi nel mondo dell'automazione su PC industriali, o piuttosto una piattaforma embedded systemless, o magari nel contesto di un RTOS certificato, indifferentemente un full Posix 1003.13 PSE54 o un "semplice" realtime executive.