|
Appunti informatica |
|
Visite: 1651 | Gradito: | [ Medio appunti ] |
Leggi anche appunti:Operatori logici su bitOperatori logici su bit Gli operatori logici su bit consentono di porre in relazione Contenuto del floppy diskContenuto del floppy disk Il floppy disk allegato costituisce una raccolta di Cast e conversioni di tipoCast e conversioni di tipo In una espressione è sempre possibile avere operandi |
Clipper è un linguaggio compilato, sintatticamente compatibile in larga misura con l'interprete del dBase III, orientato al database management. Sin dalle prime versioni, Clipper ha implementato gli strumenti necessari all'interfacciamento con il C per la realizzazione di funzioni non presenti nelle sue librerie standard (soprattutto per la gestione della macchina a basso livello).
A tal fine è raccomandato l'utilizzo del Microsoft C (del resto le librerie Clipper sono scritte in Microsoft C); in realtà tutti i compilatori C in grado di generare, per il large memory model, moduli oggetto compatibili con l'architettura DOSSEG definita da Microsoft possono essere validamente impiegati in molti casi . Il Microsoft C è indispensabile, per motivi di compatibilità, solo nel caso in cui si vogliano realizzare funzioni implementanti matematica in virgola mobile o routine grafiche
Le funzioni scritte in C devono quindi essere compilate per il modello di memoria large (pag. e seguenti) e, se si utilizza il compilatore Microsoft, deve essere richiesta l'opzione 'Floating Point Alternate Library' (/FP); è inoltre molto comodo includere nel sorgente il file EXTEND.H , fornito con il pacchetto Clipper, che definisce alcune macro e costanti manifeste e contiene i prototipi di tutte le funzioni, facenti parte nella libreria Clipper, che consentono lo scambio di parametri e valori restituiti tra le funzioni Clipper e quelle C. Il modulo oggetto risultante dalla compilazione può essere collegato all'object file prodotto da Clipper, oppure può essere inserito in una libreria.
Nello scrivere funzioni C richiamabili da programmi Clipper va tenuto sempre presente che non ha senso, per esigenze di compatibilità tra i due linguaggi, parlare di parametri formali (pag. e seguenti). Le funzioni C possono accedere a tutti i parametri attuali della chiamata Clipper invocando le funzioni _par() (facenti parte della libreria Clipper e dichiarate in EXTEND.H) e devono pertanto essere dichiarate prive di parametri formali (void). Vi sono numerose funzioni _par(), ciascuna dedicata ad un particolare tipo di parametro.
Anche l'eventuale restituzione di un valore alla routine Clipper deve avvenire mediante le funzioni _ret(), facenti parte della libreria Clipper e tra loro diversificate in base al tipo del valore da restituire. Le funzioni _ret() non restituiscono il controllo alla routine Clipper, ma si limitano a predisporre la restituzione del valore; la funzione C cede il controllo solo al termine del proprio codice o eseguendo un'istruzione return). Ne segue che le funzioni C devono essere dichiarate void; inoltre le specifiche Clipper impongono che esse siano dichiarate anche pascal (pag. ). Il file EXTEND.H definisce la macro CLIPPER , che può essere usata per dichiarare le funzioni C ed equivale proprio a void pascal
Il prototipo di una funzione C richiamabile da Clipper è perciò analogo a
#include <EXTEND.H>
CLIPPER funzPerClipper(void);
Nell'ipotesi che funzPerClipper() accetti 4 parametri, la chiamata in Clipper è:
RETVAL = FUNZPERCLIPPER(PAR_1,PAR_2,PAR_3,PAR_4)
Si tratta ora di analizzare brevemente le funzioni _par() e _ret(), per scoprire come funzPerClipper() può accedere a PAR_1 PAR_2 PAR_3 e PAR_4 e restituire RETVAL
La funzione
int _parinfo(int order);
restituisce il tipo del parametro che occupa la posizione order nella lista dei parametri attuali; _parinfo(0) restituisce il numero di parametri passati alla funzione. Il tipo è identificato dalle seguenti costanti manifeste, definite in EXTEND.H
#define UNDEF 0
#define CHARACTER 1
#define NUMERIC 2
#define LOGICAL 4
#define DATE 8
#define MPTR 32 /* sommato al tipo effettivo se passato per reference */
#define MEMO 65
#define ARRAY 512
La costante MPTR ha un significato particolare: essa è sommata al tipo del parametro per indicare che esso è stato passato come reference (preceduto, secondo la sintassi Clipper, da una ): perciò, se _parinfo(1) restituisce , significa che il primo parametro attuale è una stringa passata per reference.
La funzione
int _parinfa(int order,int index);
restituisce il tipo dell'elemento in posizione index nell'array che a sua volta è parametro attuale di posizione order. Così, se _parinfa(2,5) restituisce , significa che il quinto elemento dell'array ricevuto come secondo parametro attuale è una stringa . La chiamata
_parinfa(order,0);
restituisce il numero di elementi dell'array che occupa la posizione order tra i parametri attuali. Il secondo parametro (index) può essere omesso: in tal caso _parinfa() equivale a _parinfo()
Vediamo ora una rapida rassegna delle altre principali funzioni _par(). Per i dettagli sintattici si rimanda alla documentazione del linguaggio Clipper; va detto, tuttavia, che nell'uso di tali funzioni il secondo parametro, index, può essere omesso: in particolare, esso deve essere utilizzato solo quando il parametro attuale la cui posizione è espressa dal primo parametro order sia un array. In tal caso, index individua uno specifico elemento all'interno dell'array medesimo.
La funzione
int _parni(int order,int index);
'recupera' il parametro attuale di posizione order (se esso è un array è possibile specificarne un singolo elemento con index; in caso contrario index può essere omesso) e lo restituisce sotto forma di intero: ad esempio, la chiamata
#include <extend.h>
.
int parm_1;
.
parm_1 = _parni(1);
.
consente di accedere al primo parametro, un integer, passato dalla routine Clipper alla funzione C. Del tutto analoghe alla _parni() sono le funzioni
long _parnl(int order,int index);
double _parnd(int order,int index);
int _parl(int order,int index);
char *_pards(int order,int index);
char *_parc(int order,int index);
Tutte, infatti, restituiscono il parametro attuale di posizione order (con la possibilità, se esso è un array, di individuarne un elemento mediante index). La _parnl() restituisce un long e la _parnd() un double, mentre la _parl() restituisce un intero che rappresenta un campo logico Clipper ( equivale a .F. e a .T.
La _pards() restituisce una stringa derivata da un campo Clipper di tipo date; la data è espressa nella forma 'AAAAMMGG'. E' opportuno copiare la stringa restituita in un buffer appositamente allocato, in quanto il buffer gestito dalla funzione _pards() è statico e viene sovrascritto ad ogni chiamata alla stessa. Ad esempio, nel codice
#include <stdio.h>
#include <extend.h>
.
char *date_1, date_2;
.
date_1 = _pards(1);
date_2 = _pards(2);
printf('data 1 = %sndata 2 = %sn',date_1,date_2);
la printf() visualizza due volte la data passata come secondo parametro, perché la seconda chiamata a _pards() sovrascrive il buffer statico che essa utilizza internamente. Per ottenere un funzionamento corretto è sufficiente apportare la modifica seguente:
#include <string.h>
.
strcpy(date_1,_pards(1));
strcpy(date_2,_pards(2));
.
La funzione _parc() restituisce un puntatore a carattere. Va però ricordato che la gestione delle stringhe in Clipper è differente da quella implementata in C: in particolare, le stringhe possono contenere anche caratteri nulli (lo zero binario). Per conoscere la lunghezza effettiva di una stringa Clipper può essere utilizzata la funzione
int _parclen(int order,int index);
che non include nel computo il NULL che chiude la stringa stessa, mentre la
int _parcsiz(int order,int index);
restituisce il numero di byte effettivamente allocati per contenere la stringa (o, più in generale, l'array di caratteri), incluso l'eventuale NULL che la chiude. Se il parametro è una costante stringa, _parcsiz() restituisce
Passiamo ora ad un rapido esame delle funzioni _ret(), che consentono alla funzione C di restituire un valore alla routine Clipper, con la precisazione che, essendo possibile restituire un unico valore, la funzione C può chiamare una sola volta una funzione _ret() prima di terminare.
E' il caso di citare per prima una funzione leggermente particolare: si tratta della
void _ret(void);
che non restituisce a Clipper alcun valore (esattamente come se la funzione C terminasse con una semplice return), ma gestisce lo stack in modo tale che la routine Clipper possa chiamare la funzione C con un'istruzione DO (come se fosse, cioè, una procedure e non una function).
Vi è poi una _ret() per ogni tipo di dato, analogamente a quanto visto per le funzioni _par()
void _retni(int ival);
void _retnl(long lval);
void _retnd(double dval);
void _retl(int bval);
void _retds(char *datestr);
void _retc(char *string);
La _retni() restituisce alla routine Clipper, sotto forma di campo numerico, l'intero che le è passato come parametro. Del tutto analoghe sono la _retnl() e la _retnd(), che devono essere utilizzate per restituire, rispettivamente, un long e un double
La _retl() restituisce a Clipper, sotto forma di campo logico, l'intero che riceve come parametro. Questo deve rappresentare un valore booleano, cioè deve essere o , convertiti rispettivamente in .T. e .F.
La _retds() restituisce sotto forma di campo date la stringa passatale come parametro, che deve essere nella forma 'AAAAMMGG'
La _retc() restituisce a Clipper il puntatore a carattere (stringa) che le è passato come parametro. Alla _retc() si affianca la
void _retclen(char *buffer,int len);
che restituisce al Clipper, oltre all'indirizzo della stringa, anche la lunghezza della medesima. La _retclen() si rivela utile nei casi in cui il puntatore a carattere indirizza un buffer contenente anche byte nulli (zeri binari).
Con Clipper Summer '87 non esiste modo per passare ad una funzione C l'indirizzo di una variabile Clipper (cioè il puntatore ad essa): ciò avviene, ma implicitamente, solo nel caso delle stringhe. La libreria Clipper 5 include invece alcune funzioni, le _stor(), che consentono al codice C di accedere alle variabili ricevute per reference, cioè passate come parametri attuali anteponendo al nome il carattere , in modo analogo a quello realizzabile (in C puro) mediante il passaggio di puntatori. La documentazione Clipper sottolinea che passare per reference una variabile ad una funzione C non significa comunque passarne l'indirizzo: in realtà la gestione del passaggio di parametri è, in Clipper, piuttosto complessa; tuttavia l'utilizzo dei reference comporta l'inserimento nello stack di informazioni relative all'indirizzo della variabile, ed è proprio grazie a tali informazioni che le nuove funzioni cui si è accennato consentono di 'simulare' l'impiego di veri e propri puntatori.
La funzione
int _storni(int n,int order,int index);
memorizza l'intero n nella variabile Clipper passata via reference alla funzione C come parametro di posto order; il terzo parametro è facoltativo e deve essere utilizzato solo nel caso in cui il parametro ricevuto in posizione order sia un array: in tal caso index individua un preciso elemento al suo interno. La funzione restituisce in caso di errore, altrimenti.
Analoghe alla _storni() sono le funzioni
int _stornd(double n,int order,int index);
int _stornl(long n,int order,int index);
int _storl(int logical,int order,int index);
int _stords(char *string,int order,int index);
int _storc(char *string,int order,int index);
La _stornd() è utilizzabile per memorizzare un valore come double, mentre la _stornl() memorizza un long integer. La _storl() accetta come primo parametro un intero e lo memorizza come valore logico ( equivale a .F.; un valore diverso da equivale a .T.); la _stords() memorizza come data la stringa string, che deve avere formato 'AAAAMMGG'. La _storc() memorizza una stringa; in alternativa può essere utilizzata la
int _storclen(char *buffer,int length,int order,int index);
che consente di memorizzare un array di caratteri indicandone la lunghezza
Le funzioni C destinate ad interfacciarsi con Clipper non possono gestire l'allocazione dinamica della memoria mediante malloc() e le altre funzioni della libreria C allo scopo predisposte (pag. ): per esigenze di compatibilità è necessario utilizzare due funzioni che la libreria Clipper Summer '87 rende disponibili, ancora una volta, tramite i prototipi dichiarati in EXTEND.H. In particolare, la funzione
unsigned char *_exmgrab(unsigned int size);
alloca in modo compatibile con Clipper un buffer ampio size byte e ne restituisce l'indirizzo sotto forma di puntatore a unsigned char . In caso di errore viene restituito NULL. L'analogia con malloc() è evidente. La memoria allocata da _exmgrab() può essere gestita con le comuni tecniche C (puntatori, indirezioni, etc.); tuttavia essa deve essere disallocata con l'apposita funzione Clipper:
void _exmback(unsigned char *pointer,unsigned int size);
che svolge un ruolo analogo a quello della funzione C free(); a differenza di questa, però, _exmback() richiede che, oltre all'indirizzo dell'area di memoria da disallocare, le sia passato anche il numero di byte da liberare. Se si intende disallocare l'intera area di RAM, il parametro size passato a _exmback() deve essere identico a quello omologo passato a _exmgrab(). Vediamo un semplice esempio:
#include <extend.h>
unsigned size = 1000;
unsigned char *buffer;
.
if(!(buffer = _exmgrab(size)))
. // utilizzo del buffer
_exmback(buffer,size);
.
L'indirizzo di un buffer allocato da _exmgrab() può essere restituito a Clipper tramite la _retclen(); con riferimento all'esempio precedente la chimata potrebbe essere
_retclen(buffer,size);
E' palese che il buffer non deve essere disallocato né prima né dopo la chiamata a _retclen()
La libreria del più recente Clipper 5 comprende invece 3 funzioni per l'allocazione dinamica della RAM, due delle quali sostituiscono quelle appena descritte. La
void *_xalloc(unsigned int size);
rimpiazza la _exmgrab(). Anche la _xalloc() restituisce NULL in caso di errore. Alla _xalloc() si affianca una funzione di nuova concezione, la
void *_xgrab(unsigned int size);
alloca anch'essa size byte nello heap di Clipper ma, a differenza della _xalloc() genera un run‑time error in caso di errore. La _exmback() è stata sostituita dalla
void _xfree(void *mem);
Come si vede, la _xfree() accetta un unico parametro, rappresentante l'indirizzo dell'area di memoria da liberare: non è più possibile, quindi, richiedere la disallocazione di una parte soltanto della memoria in precedenza allocata.
Presentiamo di seguito alcuni esempi di funzioni C richiamabili da programmi Clipper. La prima permette di utilizzare alcuni servizi DOS da procedure Clipper.
BARNINGA_Z! - 1993
CL_BDOS.C - cl_bdos()
void pascal cl_bdos(void);
Sintassi per Clipper:
int cl_bdos(int dosfn,int dosdx,int dosal);
int dosfn numerico intero rappresentante il numero di servizio dell'int 21h
int dosdx numerico intero rappresentante il registro DX
int dosal numerico intero rappresentante il registro AL
Restituisce: il valore restituito dall'int 21h nel regsitro AX
COMPILABILE CON MICROSOFT C 5.1
CL /c /AL /Oalt /FPa /Gs /Zl cl_bdos.c
#include <extend.h>
#include <dos.h>
#define PNUM 3
#define ERROR -1
CLIPPER cl_bdos(void)
for(i = 1; i <= PNUM; i++)
if(_parinfo(i) != NUMERIC)
_retni(bdos(_parni(1),_parni(2),_parni(3)));
return;
Ed ecco un esempio di chiamata alla cl_bdos() in una routine Clipper:
DOS_FN = 12 && servizio 0Ch int 21h (vuota buffer tastiera e invoca altro servizio)
REG_AL = 7 && servizio da invocare in servizio 0Ch (7 = attende tasto)
RET_VAL = CL_BDOS(DOS_FN,0,REG_AL) // chiama interrupt 21h
IF RET_VAL = -1
@ 10,12 SAY 'Errore!'
ELSE
RET_VAL = RET_VAL % 256 // calcola AL
. // utilizza il valore restituito (tasto premuto)
ENDIF
Il frammento di codice Clipper presentato utilizza la cl_bdos() per invocare l'int 21h, servizio 0Ch, con AL : l'operazione che il servizio esegue consiste nel vuotare il buffer di tastiera e interrompere l'esecuzione del programma in attesa della pressione di un tasto. La cl_bdos() restituisce il valore di AX a sua volta restituito dall'int 21h: da questo viene poi 'estratto' il valore di AL, cioè il codice ASCII del tasto premuto . La formule per ricavare il valore di un registro a 16 bit a partire dai due sottoregistri a 8 bit che lo compongono è molto semplice:
RX = (RH * 256) + RL
dove RX indica un generico registro a 16 bit, mentre RH e RL rappresentano, rispettivamente, il sottoregistro 'alto' (gli 8 bit più significativi ) e quello 'basso' (gli 8 bit meno significativi). Inoltre sono valide le seguenti:
RH = RX / 256
RL = RX % 256
Si può cioè affermare che gli 8 bit più significativi sono ottenibili dividendo il valore a 16 bit per , senza considerare resto o decimali, mentre gli 8 bit meno significativi sono il resto della precedente divisione.
Ed ora il secondo esempio. E' noto che in ogni programma C main() può essere dichiarata con alcuni parametri formali (vedere pag. ): il secondo di questi, solitamente chiamato argv, è un array di puntatori a stringa (o, meglio, a carattere: char **argv), la prima delle quali (argv[0]) rappresenta il nome del programma eseguibile, completo di pathname. In Clipper è possibile accedere ai parametri della command line , ma non si ha modo di conoscere, in modo quasi 'automatico', come nei programmi C, nome e pathname del programma stesso. L'ostacolo può essere aggirato con una funzione C, il cui modulo oggetto deve essere collegato all'object file prodotto dal compilatore Clipper.
BARNINGA_Z! - 1991
CL_EXENM.C - cl_exename()
void pascal cl_exename(void);
char *cl_exename();
Restituisce: il puntatore ad una stringa che rappresenta il nome del
programma eseguibile completo di pathname
COMPILABILE CON BORLAND C++ 3.1
tcc -O -d -c -ml cl_exenm.c
#include <extend.h>
#include <dir.h>
#include <dos.h>
CLIPPER cl_exename(void)
for(; *ENVptr != 1;)
ENVptr++;
for(ENVptr += 2; *ENVptr; )
exeName[i++] = *ENVptr++;
exeName[i] = 0;
_retc(exeName);
La cl_exename() utilizza il servizio 62h dell'int 21h per conoscere l'indirizzo di segmento del Program Segment Prefix del programma (vedere pag. ) e lo utilizza per costruire un puntatore all'environment, cioè alla prima delle variabili d'ambiente. Infatti, la word ad offset 2Ch nel PSP rappresenta l'indirizzo di segmento dell'area allocata dal DOS all'environment. L'espressione
*(unsigned far *)MK_FP(PSPseg,0x2C)
restituisce detta word, pertanto l'espressione
MK_FP(*(unsigned far *)MK_FP(PSPseg,0x2C),0)
restituisce il puntatore (far) alla prima stringa dell'environment . Le stringhe rappresentanti variabili d'ambiente sono memorizzate l'una di seguito all'altra; ogni stringa è terminata da un byte nullo, che in questo caso funge anche da 'separatore'. L'ultima stringa nell'environment è conclusa da due byte nulli: la sequenza 00h 00h, che indica anche la fine dell'environment, è ricercata dal primo ciclo for. Il secondo ciclo cerca il byte 01h, che segnala la presenza della stringa contenente nome e path dell'eseguibile: il byte 01h è seguito da un byte nullo, dopo il quale inizia la stringa; la clausola di inizializzazione
ENVptr += 2;
del terzo ciclo for 'scavalca' la sequenza 01h 00h; l'istruzione che costituisce il corpo del ciclo stesso può così copiare la stringa, un byte ad ogni iterazione, nel buffer statico exeName. La scelta dell'allocazione statica evita il ricorso a _exmgrab(); del resto non sarebbe possibile dichiarare il buffer come semplice variabile automatica in quanto l'area di memoria da esso occupata verrebbe rilasciata in uscita dalla funzione.
La stringa è esplicitamente terminata da un byte nullo e il suo indirizzo è restituito a Clipper mediante _retc()
La chiamata a cl_exename() in Clipper può essere effettuata come segue:
EXEPATH = ''
EXEPATH = CL_EXENAME()
@ 10,12 say 'Questo programma è ' + EXEPATH
Qualora il programma Clipper deallochi il proprio environment (eventualmente utilizzando una funzione scritta in C), è indispensabile che la chiamata a cl_exename() avvenga prima di detta operazione.
Va ancora sottolineato che il sorgente di cl_exename() può essere compilato con il compilatore Borland: d'altra parte non referenzia alcuna funzione di libreria C.
Vediamo un ultimo esempio: una funzione in grado di suddividere un numero in virgola mobile in parte intera e parte frazionaria, basata sulla funzione di libreria C modf()
BARNINGA_Z! - 1994
CL_MODF.C - cl_modf()
void pascal cl_modf(void);
Sintassi per Clipper:
double cl_modf(double n,double @ipart);
double n numerico in virgola mobile che si vuole suddividere in parte
intera e parte frazionaria
double @ipart reference a numerico in virgola mobile destinato a contenere
la parte intera
Restituisce: la parte frazionaria di n
COMPILABILE CON MICROSOFT C 5.1
CL /c /AL /Oalt /FPa /Gs /Zl cl_modf.c
#include <extend.h>
#include <math.h>
#define PNUM 2
#define ERROR 0.0
CLIPPER cl_modf(void)
if(! ISNUM(1))
if(!(ISNUM(2) && ISBYREF(2)))
fp = modf(_parnd(1),&ip);
if(!_storni(ip,2))
_retnd(fp);
return;
Segue esempio di chiamata alla cl_modf() in una routine Clipper:
DOUBLE_NUM = 12.5647
INT_PART = 0.0
FRAC_PART = CL_MODF(DOUBLE_NUM,@INT_PART)
@ 10,12 SAY 'PARTE INTERA: '+STR(INT_PART)+' PARTE FRAZIONARIA: '+STR(FRAC_PART)
Il programma Clipper visualizza il numero come parte intera e il numero come parte frazionaria. La restituzione di due valori (parte intera e parte frazionaria di DOUBLE_NUM) alla routine chiamante è resa possibile dal passaggio per reference della variabile INT_PART alla CL_MODF(): questa, mediante la _stornd() è in grado di memorizzare all'indirizzo della INT_PART, cioè nella INT_PART stessa, il valore che, a sua volta, la modf() ha scritto all'indirizzo di ip, cioè nella ip medesima.
E' evidente che l'utilizzo delle macro PCOUNT ISNUM() e ISBYREF(), nonché della funzione _storni(), rende la CL_MODF() utilizzabile esclusivamente da programmi compilati da Clipper 5.
I compilatori Borland e Zortech, ad esempio, soddisfano detto requisito, ma, in alcune situazioni, la struttura delle librerie, ove differente da quella implementata da Microsoft, può essere causa di problemi.
Come al solito, occorre fare attenzione. E' vero che le librerie Clipper sono scritte in Microsoft C, ma va precisato che si tratta della versione 5.1. Non è un particolare irrilevante, perché, pur utilizzando il compilatore Microsoft per scrivere funzioni C da interfacciare a Clipper, possono sorgere strani problemi se la versione usata non è, anch'essa, la 5.1. In alcuni casi è possibile utilizzare la GRAPHICS.LIB del Microsoft C 6.0 con la LLIBCA.LIB del Microsoft C 5.1, ma si tratta comunque di un pasticcio pericoloso.
Con il Microsoft C viene perciò impiegata la libreria LLIBCA.LIB, mentre con il Borland la libreria usata è la CL.LIB
Si presti però attenzione al fatto che Clipper è un linguaggio case‑insensitive: ciò non pone problemi, a patto di non differenziare mai nomi nei sorgenti C solamente in base alle maiuscole/minuscole.
In Clipper gli elementi dell'array sono numerati a partire da e non da come in C. Inoltre, ogni elemento di un array può appartenere ad un tipo differente da quello degli altri.
L'extend system implementato dal Clipper 5 include alcune macro, dichiarate in EXTEND.H, utilizzabili, in luogo di _parinfo() e _parinfa(), per il controllo dei parametri passati alla funzione: la macro
PCOUNT
restituisce il numero di parametri che la funzione C ha ricevuto. La macro
ALENGTH(int parmno)
accetta il numero d'ordine del parametro ricevuto dalla funzione C e, se questo è un array, restituisce il numero di elementi che lo costituiscono. Infine, le macro elencate di seguito sono concepite per controllare il tipo del parametro la cui posizione è loro passata in input:
ISARRAY(int parmno); // restituisce non-zero se il parametro parmno e' un array
ISBYREF(int parmno); // restit. non-zero se parametro parmno e' passato per reference
ISCHAR(int parmno); // restituisce non-zero se il parametro parmno e' una stringa
ISDATE(int parmno); // restituisce non-zero se il parametro parmno e' una data
ISLOG(int parmno); // restituisce non-zero se il parametro parmno e' un campo logico
ISMEMO(int parmno); // restituisce non-zero se il parametro parmno e' un campo memo
ISNUM(int parmno); // restituisce non-zero se il parametro parmno e' un numerico
Il valore minimo che il parametro parmno può assumere è e indica il primo parametro passato alla funzione C.
Utile quando non si tratti di una vera e propria stringa (terminata da NULL), ma di una sequenza di caratteri qualsiasi, da gestire in modo binario.
Appunti su: |
|