home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
MAGAZINE
/
DDJMAG
/
DDJ8908.ZIP
/
FLOYD.LST
< prev
next >
Wrap
File List
|
1989-07-06
|
9KB
|
344 lines
THE C-TO-FORTRAN CONNECTION
by Michael Floyd
[LISTIN╟ ONE]
/* DOT.C - uses Lahey FORTRAN's random number generator to randomly
place pixels on the screen.
This example demonstrates how to call F77L functions and
subroutines from a C program.
Uses Initialize() from Borland's BGIDEMO example to
perform hardware detection, load the appropriate BGI
driver and initialize the system to graphics mode.
Link line using Borland's TLINK is as follows:
link bcf77l.150+c0l+frand+do_frand,frand,,emu+mathl+cl+f77l
*/
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
char *DriverNames[] = {
"Detect",
"CGA",
"EGA",
"HercMono",
"VGA"
};
struct PTS {
int x, y;
}; /* Structure to hold vertex points */
int GraphDriver; /* The Graphics device driver */
int GraphMode; /* The Graphics mode value */
double AspectRatio; /* Aspect ratio of a pixel on the screen*/
int MaxX, MaxY; /* The maximum resolution of the screen */
int MaxColors; /* The maximum # of colors available */
int ErrorCode; /* Reports any graphics errors */
struct palettetype palette; /* Used to read palette info */
/* */
/* Function prototypes */
/* */
extern void frand (int *, int *);
extern void seed_rnd (int *);
void Initialize(void);
void RandomDot(void);
/* Begin main() */
main()
{
Initialize(); /* Set system into Graphics mode */
RandomDot(); /* Place pixels at random locations */
closegraph(); /* Return the system to text mode */
} /* End main() */è
/* INITIALIZE: Initializes the graphics system and reports */
/* any errors which occured. */
void Initialize(void)
{
int xasp, yasp; /* Used to read the aspect ratio*/
GraphDriver = DETECT; /* Request auto-detection */
initgraph( &GraphDriver, &GraphMode, "" );
ErrorCode = graphresult(); /* Read result of initialization*/
if( ErrorCode != grOk ){ /* Error occured during init */
printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
exit( 1 );
}
getpalette( &palette ); /* Read the palette from board */
MaxColors = getmaxcolor() + 1; /* Read maximum number of colors*/
MaxX = getmaxx();
MaxY = getmaxy(); /* Read size of screen */
getaspectratio( &xasp, &yasp ); /* read the hardware aspect */
AspectRatio = (double)xasp / (double)yasp; /* Get correction factor */
} /* End Initialize */
void RandomDot(void)
{
int seed;
int i, x, y, height, width, rand_val, color, temp;
struct viewporttype vp;
getviewsettings( &vp );
height = vp.bottom - vp.top;
width = vp.right - vp.left;
seed_rnd( &seed ); /* Seed F77L's Random # Gen. Output discarded */
for( i=0 ; i<1000 ; ++i ){ /* Put 1000 pixels on screen */
temp = width - 1;
frand( &rand_val, &temp ); /* Call F77L's RND function */
x = rand_val + 1;
temp = height - 1;
frand( &rand_val, &temp );
y = rand_val + 1;
frand( &rand_val, &MaxColors );
color = rand_val;
putpixel( x, y, color );
} /* End for loop */
} /* End RandomDot() */
[LISTING TWO]
c
c FRAND.FOR - Calls F77L's random Number generator RND.
c Demonstrates how to call a FORTRAN function from C
c
c Inputs : None
c Outputs: RETVAL
FUNCTION FRAND(N)
BCEXTERNAL FRAND
INTEGER*2 N, FRAND
FRAND = INT(RND() * N )
RETURN
END
c
c SEED_RND - Used to seed F77L's random Number generator.
c Demonstrates how to call a FORTRAN subroutine from C
c
c Inputs : None
c Outputs: RETVAL
SUBROUTINE SEED_RND(RETVAL)
BCEXTERNAL SEED_RND
INTEGER*2 RETVAL
RETVAL = INT(RRAND())
RETURN
END
[LISTING THREE]
c
c SEARCH.FOR uses rnd() to generate a list of random values
c that are then passed to C's qsort routine for sorting in
c ascending and descending order. Once sorted, the values
c are dislayed and the user is prompted for a value to search
c for. The input value is passed to C's bsearch function and
c the results of the search are displayed
c
c To link, use the following command line:
c
c tlink f77lbc.150+search+do_srch,search,,emu+mathl+cl+f77l
c
PROGRAM SEARCH
BCEXTERNAL q_sort, bin_search
INTEGER*2 A(0:20), B(0:20), C(0:20), I, J
INTEGER*2 FOUND, bin_search, VAL, R
DO 10 I = 0, 19
A(I) = 0
B(I) = 0
C(I) = 0
10 CONTINUE
R = rrand()
PRINT *, R
DO 20 I = 0, 19
A(I) = 32767.0 * rnd()
B(I) = A(I)
C(I) = A(I)
20 CONTINUE
PRINT *, 'Input Ascending Descending'
PRINT *, '════════════════════════════════'
call q_sort(A,20,0)
call q_sort(B,20,1)
DO 30 J = 0, 19
PRINT 40, C(J), A(J), B(J)
30 CONTINUE
40 FORMAT(I6,I13,I13)
PRINT *, 'Enter value to search for: '
READ *, VAL
FOUND = bin_search(A, 20, VAL)
IF (FOUND .NE. 0) THEN
PRINT *, VAL, ' found in list!'
ELSE
PRINT *, VAL, ' NOT found!'
ENDIF
END
[LISTING FOUR]
/* do_srch.c
** q_sort()
** This function will take a one dimensional array of length n and
** integer width and will sort it in ascending or descending order.
** Nothing is returned -- status always equals zero if any checking
** is done by the FORTRAN calling program.
** inputs: array ptr to array
** length number of elements in array
** order 0 = ascending
** 1 = descending
** output: none
*/
#include <stdio.h>
#include <stdlib.h>
int q_sort (void *array,int *length,int *order);
int ascending (void *first,void *second);
int descending (void *first,void *second);
int bin_search (void *array, int *length, int *key);
int q_sort (void *array,int *length,int *order)
{
int status = 0; /* return value */
qsort (array,(size_t) *length,sizeof (int),
(int(*)(const void *,const void *)) ((*order == 0) ? ascending : descending));
return (status);
} /* end of do_sort() */
/* ascending()
** This function is used by qsort and/or bsearch to return a
** value based on the comparison of two inputs. qsort uses this
** function to perform an ascending sort.
** inputs: first ptr to first element
** second ptr to second element
** return: result of comparison
*/
int ascending (void *p1, void *p2)
{
return ((*(int *) p1 < *(int *) p2) ? (-1) : (*(int *) p1 == *(int *) p2) ? (0) : (1));
}
/* descending()
** This function is used by qsort and/or bsearch to return a
** value based on the comparison of two inputs. qsort uses this
** function to perform a descending sort.
** inputs: first ptr to first element
** second ptr to second element
** return: result of comparison
*/
int descending (void *p1, void *p2)
{
return ((*(int *) p1 < *(int *) p2) ? (1) : (*(int *) p1 == *(int *) p2) ? (0) : (-1));
}
/* bin_search()
** This function takes a sorted FORTRAN array and a key and
** attempts to locate the key value using C's bsearch(). The
** function passes back the value if found, or 0 if not found.
** inputs: array ptr to an array
** length length of the array
** key ptr to a key value
** return: result of search
*/
int bin_search (void *array, int *length, int *key)
{
int *ptr;
ptr = (int *) bsearch(key, array, (size_t) *length, sizeof(int), ascending);
return(ptr != NULL);
}
[EXAMPL┼ 1]
/* Passing a string to FORTRAN from a C main() */
typedef struct {
char *text;
int length;
} CHARACTER;
extern void f_subroutine(int *, float *, CHARCTER *);
main() {
int ival;
float fval;
CHARACTER cval;
cval.text = "contents of variable";
cval.length = strlen(cval.text);
f_subroutine(&ival, &fval, &cval);
} /* End of C example */
c
c FORTRAN subroutine to accept and print a string
c
SUBROUTINE F_SUBROUTINE(I, F, C)
BCEXTERNAL F_SUBROUTINE
INTEGER*2 I
REAL F
CHARACTER*(*) C
PRINT I, F, C
END
[EXAMPL┼ 2]
/* C module to get FORTRAN function return value */
extern void f_function(double *, double *);
c_module_main() {
double, dval, return_val;
f_function(&return_val, &dval);
}
c
c FORTRAN function to calculate the cube of the input number
c
function f_function(x)
MSCEXTERNAL f_function
double precision x, f_function
f_function = x * x * x
return
end