天天看點

C與Fortran混合程式設計

混合程式設計

    • 1、C調Fortran:判斷兩個數的最大值,C輸入,Fortran判斷
    • 2、Fortran調C:二維數組運算,Fortran進行相關定義,C運算
    • 3、遇到的問題

1、C調Fortran:判斷兩個數的最大值,C輸入,Fortran判斷

fortran.f90

subroutine maxnum(x,y)
      integer :: x,y
      if(x > y) then
        print *, x
      else
        print *, y
      end if
end subroutine maxnum
           

c.c

#include<stdio.h>
void maxnum_(int*, int*);
int main(){
   int a,b;
   printf("請輸入要比較的兩個數\n");
   scanf("%d%d",&a,&b);
   maxnum_(&a, &b);
}

           
test: fortran.f90 c.c
	gcc -c c.c -o c.o
	gfortran -c fortran.f90 -o fortran.o
	gfortran -o test fortran.o c.o
	#gcc -o test c.o fortran.o
           

2、Fortran調C:二維數組運算,Fortran進行相關定義,C運算

fortranCallC.f90

program callC
      implicit none
      external :: sum_c       !調用C的函數 
      integer(kind=8),dimension(3,3) :: arr
      integer :: i,j
      i=0
      j=0
      print *,'輸入3x3的矩陣,回車隔開:'
      !一個二維矩陣
      do i = 1, 3
         do j =1, 3
            read *, arr(i,j)
         end do 
      end do 
      !調用c函數進行計算
      ! do i = 1, 3
      !   do j =1, 3
      !       print *,arr(i,j)
      !   end do
      !end do

      call sum_c(arr)
end program callc  
           

CCallFortran.c

#include<stdio.h>

void sum_c_(int arr[][3]){
    int sum = 0;
    //printf("sizeof(arr) is %ld\n",sizeof(*arr)); 檢視數組所占記憶體,輸出是12,但我輸出15個數才得到全部的arr的值
    //相關文檔沒有發現,但是多次運作發現傳過來的二維數組索引需要+2
    for(int i=0; i<=4; i+=2){
       for(int j=0 ;j<=4; j+=2){
         // printf("222222");用來檢驗非編譯錯誤,上面把j++寫成i++
          sum += *(arr[j]+i);
	  printf("傳過來的數組值:%d\n",arr[j][i]);
       }
    }
    printf("the sum is %d\n",sum);
}
           

makefile

test: CCallFortran.c fortranCallC.f90
	gfortran -c fortranCallC.f90 -o fortranCallC.o
	gcc -c CCallFortran.c -o CCallFortran.o
	gfortran -o test CCallFortran.o fortranCallC.o
           

3、遇到的問題

1、逗号寫成中文狀态,使用vim編輯不利于排錯,也是我對這件事的反映不夠,加強表征印象

2、Fortran調用c語言,二維數組運算

參考1

參考2

互相調用參考

3、C語言中 指針做函數參數傳遞二維數組 ,Fortran調用c的函數,需要指針作為參數,是以有了下面這些問題:

關于參數是二維數組指針的操作

我疑惑傳入參數後,為什麼不用*來表示變量值 參考

#include <stdio.h>
void fun(int (*p1)[3],int (*p2)[3]);
int main()
{
int p1[3][3]={{7,8,9},{4,5,6},{1,2,3}} ;
int p2[3][3] = {0};
int i = 0, j = 0;
fun(p1,p2);
for(i = 0;i < 3;i++){
for(j = 0;j < 3;j++){
printf("%d ",*(*(p2+i)+j));    
}
printf("\n");
}        
return 0;
}
void fun(int (*p1)[3],int (*p2)[3])
{
int i = 0,j = 0;
for(i = 0;i < 3;i++){
for(j = 0;j < 3;j++){
*(p2[j]+i) = *(p1[i]+j);
}
}
}
           

https://blog.csdn.net/hsajas/article/details/83586774

一個c語言程式中沒有或一個main函數

f.f90:(.text+0x11): multiple definition of `main’

不知對錯的一種寫法

program main
        end

subroutine maxnum(x,y) bind(c)
use,intrinsic :: iso_c_binding
      integer(kind=4) :: x,y
      read(*,*) x, y
      if(x > y) then
        print *, x
      else
        print *, y
      end if
end subroutine maxnum
           

記錄一下,以上

4、在連結時c和frotran時出現的問題

fortran.f90:(.text+0x66): undefined reference to

_gfortran_st_write' fortran.f90:(.text+0x84): undefined reference to

_gfortran_transfer_integer_write’

fortran.f90:(.text+0x93): undefined reference to

_gfortran_st_write_done' fortran.f90:(.text+0xd0): undefined reference to

_gfortran_st_write’

fortran.f90:(.text+0xee): undefined reference to

_gfortran_transfer_integer_write' fortran.f90:(.text+0xfd): undefined reference to

_gfortran_st_write_done

以上使用gcc編譯時出現的問題,可能是我将兩個檔案(c和fortran的編譯檔案連結時使用gcc方的順序不對)

gcc -c c.c -o c.o

gfortran -c fortran.f90 -o fortran.o

#gfortran -o test fortran.o c.o

gcc -o test c.o fortran.o

fortran.o: In function

maxnum_': fortran.f90:(.text+0x66): undefined reference to

_gfortran_st_write’

fortran.f90:(.text+0x84): undefined reference to

_gfortran_transfer_integer_write' fortran.f90:(.text+0x93): undefined reference to

_gfortran_st_write_done’

fortran.f90:(.text+0xd0): undefined reference to

_gfortran_st_write' fortran.f90:(.text+0xee): undefined reference to

_gfortran_transfer_integer_write’

fortran.f90:(.text+0xfd): undefined reference to `_gfortran_st_write_done’

collect2: error: ld returned 1 exit status

makefile:2: recipe for target ‘test’ failed

make: *** [test] Error 1

使用gcc先編譯c的也不行

就是要用gfortran嗎?總之fortran是可以的

5、Makefile的使用記得一定要tab

混程式設計的最後連結最好使用gfortran别用gcc(鄙見),不然會出現一堆難以了解的錯誤參考

6、在fortran調用c的時候出現的錯誤

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

無效的記憶體引用

感謝

@Alex_the_Dawn

@0_382

@詹坤林

無私分享

繼續閱讀