c和java相互調用,c++類內函數互相調用

本文目錄一覽:

如何從C中調用Java函數使用JNI

1. 編寫並編譯J2C.java

import java.lang.management.ManagementFactory;

import java.lang.management.RuntimeMXBean;

public class J2C

{

static

{

try{

// 此處即為本地方法所在鏈接庫名

System.loadLibrary(“j2c”);

} catch(UnsatisfiedLinkError e)

{

System.err.println( “Cannot load J2C library:\n ” +

e.toString() );

}

}

//聲明的本地方法

public static native int write2proc(int pid);

public static void main(String[] args){

//獲取本進程(即主線程)的pid

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();

final String info = runtime.getName();

final int index = info.indexOf(“@”);

if (index != -1) {

final int pid = Integer.parseInt(info.substring(0, index));

System.out.println(info);

System.out.println(pid);

write2proc(pid);

}

try{

Thread.sleep(8000);

} catch(InterruptedException e){

e.printStackTrace();

}

}

}

note:Java程序中System.loadLibrary參數名表示要載入的C/C++共享庫,第6步生成的共享庫名必須與該參數一致,即System.loadLibrary(Name) 對應共享庫名libName.so (共享庫名必須以lib開頭)

2. 生成C頭文件J2C.h:javah J2C

/* DO NOT EDIT THIS FILE – it is machine generated */

#include jni.h

/* Header for class J2C */

#ifndef _Included_J2C

#define _Included_J2C

#ifdef __cplusplus

extern “C” {

#endif

/*

* Class: J2C

* Method: write2proc

* Signature: (I)I

*/

JNIEXPORT jint JNICALL Java_J2C_write2proc

(JNIEnv *, jclass, jint);

#ifdef __cplusplus

}

#endif

#endif

note:1. 頭文件自動生成,不要修改它;

2. 函數JNIEXPORT jint JNICALL Java_J2C_write2proc(JNIEnv *, jclass, jint);

按照注釋的說明是在J2C.java文件的類J2C的方法write2proc處定義,故C程序的實現函數必須與該處簽名一致;

3. 編寫C程序J2C.c

#include stdio.h

#include “J2C.h”

JNIEXPORT int JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid)

{

printf(“current pid is %d\n”, pid);

return 0;

}

4. 編譯C程序

因為C程序里#include “J2C.h”而J2C.h又#include jni.h, 而gcc裡面默認環境並不知道jni.h是什麼東西,故編譯時需要告訴編譯器jni.h的位置( jni.h在jdk 的$JAVA_HOME/include下面),所以才有了上面的編譯參數;

因為使用gcc編譯得到動態庫,在jni調用的時候,某些情況會有異常, 可嘗試改用g++。

總結

1. Java中方法的原型聲明與C/C++對應的實現文件定義必須一致(可以通過自動生成的C/C++頭文件來比較),尤其是類名和方法名;

2. Java中System.loadLibrary()載入的共享庫名必須與後面C/C++生成的共享庫名一致。

C/C++如何調用JAVA

JAVA 可以調用 native method,可以調用 C 語言在本地編譯後的方法。

如果想讓 C++ 調用 JAVA 程序,可以用 socket 通信,建立連接後,通過 socket 來傳遞命令和參數,在 JAVA 程序里根據命令調用不同的方法,並且把調用後的結果通過 socket 傳回調用方界面。

在 JAVA 程序里不要用 char(兩個字節) 類型傳遞信息,需要用 byte 類型與 C++ 程序通信。

如果用了 Visual C++ 開發工具,可以上網搜索:winsock,尋找相關資料

如何在C/C++中調用Java

 

環境搭建

為了讓本文以下部分的代碼能夠正常工作,必須建立一個完整的開發環境。首先需要下載並安裝JDK 1.3.1,其下載地址為“”。假設安裝路徑為C:JDK。

下一步就是設置集成開發環境,通過Visual C++ 6的菜單Tools→Options打開選項對話框

將目錄C:JDKinclude和C:JDKincludewin32加入到開發環境的Include Files目錄中,同時將C:JDKlib目錄添加到開發環境的Library Files目錄中。這三個目錄是JNI定義的一些常量、結構及方法的頭文件和庫文件。集成開發環境已經設置完畢,同時為了執行程序需要把Java虛擬機所 用到的動態鏈接庫所在的目錄C:JDK jreinclassic設置到系統的Path環境變量中。這裡需要提出的是,某些開發人員為了方便直接將JRE所用到的DLL文件直接拷貝到系統目錄 下。這樣做是不行的,將導致初始化Java虛擬機環境失敗(返回值-1),原因是Java虛擬機是以相對路徑來尋找所用到的庫文件和其它一些相關文件的。 至此整個JNI的開發環境設置完畢,為了讓此次JNI旅程能夠順利進行,還必須先預備一個Java類。在這個類中將用到Java中幾乎所有有代表性的屬性 及方法,如靜態方法與屬性、數組、異常拋出與捕捉等。我們定義的Java程序(Demo.java)如下,本文中所有的代碼演示都將基於該Java程序, 代碼如下:

package jni.test; /** * 該類是為了演示JNI如何訪問各種對象屬性等 * @author liudong */ public class Demo { //用於演示如何訪問靜態的基本類型屬性 public static int COUNT = 8; //演示對象型屬性 public String msg; PRivate int[] counts; public Demo() { this(“缺省構造函數”); } /** * 演示如何訪問構造器 */ public Demo(String msg) { System.out.println(“:” + msg); this.msg = msg; this.counts = null; } /** * 該方法演示如何訪問一個訪問以及中文字符的處理 */ public String getMessage() { return msg; } /** * 演示數組對象的訪問 */ public int[] getCounts() { return counts; } /** * 演示如何構造一個數組對象 */ public void setCounts(int[] counts) { this.counts = counts; } /** * 演示異常的捕捉 */ public void throwExcp() throws IllegalaccessException { throw new IllegalAccessException(“exception occur.”); } }

初始化虛擬機

本地代碼在調用Java方法之前必須先加載Java虛擬機,而後所有的Java程序都在虛擬機中執行。為了初始化Java虛擬機,JNI提供了一系列的接 口函數Invocation API。通過這些API可以很方便地將虛擬機加載到內存中。創建虛擬機可以用函數 jint JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args)。對於這個函數有一點需要注重的是,在JDK 1.1中第三個參數總是指向一個結構JDK1_ 1InitArgs, 這個結構無法完全在所有版本的虛擬機中進行無縫移植。在JDK 1.2中已經使用了一個標準的初始化結構JavaVMInitArgs來替代JDK1_1InitArgs。下面我們分別給出兩種不同版本的示例代碼。

在JDK 1.1初始化虛擬機:

#include int main() { JNIEnv *env; JavaVM *jvm; JDK1_1InitArgs vm_args; jint res; /* IMPORTANT: 版本號設置一定不能漏 */ vm_args.version = 0x00010001; /*獲取缺省的虛擬機初始化參數*/ JNI_GetDefaultJavaVMInitArgs(vm_args); /* 添加自定義的類路徑 */ sprintf(classpath, “%s%c%s”, vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); vm_args.classpath = classpath; /*設置一些其他的初始化參數*/ /* 創建虛擬機 */ res = JNI_CreateJavaVM(jvm,env,vm_args); if (res 0) { fprintf(stderr, “Can’t create Java VM “); exit(1); } /*釋放虛擬機資源*/ (*jvm)-DestroyJavaVM(jvm); }

JDK 1.2初始化虛擬機:

/* invoke2.c */ #include int main() { int res; JavaVM *jvm; JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption options[3]; vm_args.version=JNI_VERSION_1_2;//這個字段必須設置為該值 /*設置初始化參數*/ options[0].optionString = “-Djava.compiler=NONE”; options[1].optionString = “-Djava.class.path=.”; options[2].optionString = “-verbose:jni”;//用於跟蹤運行時的信息 /*版本號設置不能漏*/ vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 3; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_TRUE; res = JNI_CreateJavaVM(jvm, (void**)env, vm_args); if (res 0) { fprintf(stderr, “Can’t create Java VM “); exit(1); } (*jvm)-DestroyJavaVM(jvm); fprintf(stdout, “Java VM destory. “); }

為了保證JNI代碼的可移植性,建議使用JDK 1.2的方法來創建虛擬機。JNI_CreateJavaVM函數的第二個參數JNIEnv *env,就是貫穿整個JNI始末的一個參數,因為幾乎所有的函數都要求一個參數就是JNIEnv *env。

訪問類方法

初始化了Java虛擬機後,就可以開始調用Java的方法。要調用一個Java對象的方法必須經過幾個步驟:

1.獲取指定對象的類定義(jclass)

有兩種途徑來獲取對象的類定義:第一種是在已知類名的情況下使用FindClass來查找對應的類。但是要注重類名並不同於平時寫的Java代碼,例如要得到類jni.test.Demo的定義必須調用如下代碼:

jclass cls = (*env)-FindClass(env, “jni/test/Demo”);//把點號換成斜杠

然後通過對象直接得到其所對應的類定義:

jclass cls = (*env)- GetObjectClass(env, obj); //其中obj是要引用的對象,類型是jobject

2.讀取要調用方法的定義(jmethodID)

我們先來看看JNI中獲取方法定義的函數:

jmethodID (JNICALL *GetMethodID)(JNIEnv *env, jclass clazz, const char *name, const char *sig); jmethodID (JNICALL *GetStaticMethodID)(JNIEnv *env, jclass class, const char *name, const char *sig);

這兩個函數的區別在於GetStaticMethodID是用來獲取靜態方法的定義,GetMethodID則是獲取非靜態的方法定義。這兩個函數都需要 提供四個參數:env就是初始化虛擬機得到的JNI環境;第二個參數class是對象的類定義,也就是第一步得到的obj;第三個參數是方法名稱;最重要 的是第四個參數,這個參數是方法的定義。因為我們知道Java中答應方法的多態,僅僅是通過方法名並沒有辦法定位到一個具體的方法,因此需要第四個參數來 指定方法的具體定義。但是怎麼利用一個字符串來表示方法的具體定義呢?JDK中已經預備好一個反編譯工具javap,通過這個工具就可以得到類中每個屬 性、方法的定義。下面就來看看jni.test.Demo的定義:

打開命令行窗口並運行 javap -s -p jni.test.Demo 得到運行結果如下:

Compiled from Demo.java public class jni.test.Demo extends java.lang.Object { public static int COUNT; /* I */ public java.lang.String msg; /* Ljava/lang/String; */ private int counts[]; /* [I */ public jni.test.Demo(); /* ()V */ public jni.test.Demo(java.lang.String); /* (Ljava/lang/String;)V */ public java.lang.String getMessage(); /* ()Ljava/lang/String; */ public int getCounts()[]; /* ()[I */ public void setCounts(int[]); /* ([I)V */ public void throwExcp() throws java.lang.IllegalAccessException; /* ()V */ static {}; /* ()V */ }

我們看到類中每個屬性和方法下面都有一段注釋。注釋中不包含空格的內容就是第四個參數要填的內容(關於javap具體參數請查詢JDK的使用幫助)。下面這段代碼演示如何訪問jni.test.Demo的getMessage方法:

/* 假設我們已經有一個jni.test.Demo的實例obj */ jmethodID mid; jclass cls = (*env)- GetObjectClass (env, obj);//獲取實例的類定義 mid=(*env)-GetMethodID(env,cls,”getMessage”,” ()Ljava/lang/String; “); /*假如mid為0表示獲取方法定義失敗*/ jstring msg = (*env)- CallObjectMethod(env, obj, mid); /* 假如該方法是靜態的方法那隻需要將最後一句代碼改為以下寫法即可: jstring msg = (*env)- CallStaticObjectMethod(env, cls, mid); */

3.調用方法

為了調用對象的某個方法,可以使用函數CallMethod或者CallStaticMethod(訪問類的靜態方法),根據不同的返回類型而定。這些方 法都是使用可變參數的定義,假如訪問某個方法需要參數時,只需要把所有參數按照順序填寫到方法中就可以。在講到構造函數的訪問時,將演示如何訪問帶參數的 構造函數。

訪問類屬性

訪問類的屬性與訪問類的方法大體上是一致的,只不過是把方法變成屬性而已。

1.獲取指定對象的類(jclass)

這一步與訪問類方法的第一步完全相同,具體使用參看訪問類方法的第一步。

2.讀取類屬性的定義(jfieldID)

在JNI中是這樣定義獲取類屬性的方法的:

jfieldID (JNICALL *GetFieldID) (JNIEnv *env, jclass clazz, const char *name, const char *sig); jfieldID (JNICALL *GetStaticFieldID) (JNIEnv *env, jclass clazz, const char *name, const char *sig);

這兩個函數中第一個參數為JNI環境;clazz為類的定義;name為屬性名稱;第四個參數同樣是為了表達屬性的類型。前面我們使用javap工具獲取類的具體定義的時候有這樣兩行:

public java.lang.String msg; /* Ljava/lang/String; */

其中第二行注釋的內容就是第四個參數要填的信息,這跟訪問類方法時是相同的。

3.讀取和設置屬性值

有了屬性的定義要訪問屬性值就很輕易了。有幾個方法用來讀取和設置類的屬性,它們是:GetField、SetField、 GetStaticField、SetStaticField。比如讀取Demo類的msg屬性就可以用GetObjectField,而訪問COUNT 用GetStaticIntField,相關代碼如下:

jfieldID field = (*env)-GetFieldID(env,obj,”msg”,” Ljava/lang/String;”); jstring msg = (*env)- GetObjectField(env, cls, field);//msg就是對應Demo的msg jfieldID field2 = (*env)-GetStaticFieldID(env,obj,”COUNT”,”I”); jint count = (*env)-GetStaticIntField(env,cls,field2);

訪問構造函數

很多人剛剛接觸JNI的時候往往會在這一節碰到問題,查遍了整個jni.h看到這樣一個函數NewObject,它應該是可以用來訪問類的構造函數。但是 該函數需要提供構造函數的方法定義,其類型是jmethodID。從前面的內容我們知道要獲取方法的定義首先要知道方法的名稱,但是構造函數的名稱怎麼來 填寫呢?其實訪問構造函數與訪問一個普通的類方法大體上是一樣的,惟一不同的只是方法名稱不同及方法調用時不同而已。訪問類的構造函數時方法名必須填寫 “”。下面的代碼演示如何構造一個Demo類的實例:

jclass cls = (*env)-FindClass(env, “jni/test/Demo”); /** 首先通過類的名稱獲取類的定義,相當於Java中的Class.forName方法 */ if (cls == 0) jmethodID mid = (*env)-GetMethodID(env,cls,””,”(Ljava/lang/String;)V “); if(mid == 0) jobject demo = jenv-NewObject(cls,mid,0); /** 訪問構造函數必須使用NewObject的函數來調用前面獲取的構造函數的定義 上面的代碼我們構造了一個Demo的實例並傳一個空串null */

數組處理

創建一個新數組

要創建一個數組,我們首先應該知道數組元素的類型及數組長度。JNI定義了一批數組的類型jArray及數組操作的函數NewArray,其中就是數組中元素的類型。例如,要創建一個大小為10並且每個位置值分別為1-10的整數數組,編寫代碼如下:

int i = 1; jintArray array;//定義數組對象 (*env)- NewIntArray(env, 10); for(; i= 10; i++) (*env)-SetIntArrayRegion(env, array, i-1, 1, i);

訪問數組中的數據

訪問數組首先應該知道數組的長度及元素的類型。現在我們把創建的數組中的每個元素值打印出來,代碼如下:

int i; /* 獲取數組對象的元素個數 */ int len = (*env)-GetArrayLength(env, array); /* 獲取數組中的所有元素 */ jint* elems = (*env)- GetIntArrayElements(env, array, 0); for(i=0; i len; i++) printf(“ELEMENT %d IS %d “, i, elems[i]);

中文處理

中文字符的處理往往是讓人比較頭疼的事情,非凡是使用Java語言開發的軟件,在JNI這個問題更加突出。由於Java中所有的字符都是Unicode編 碼,但是在本地方法中,例如用VC編寫的程序,假如沒有非凡的定義一般都沒有使用Unicode的編碼方式。為了讓本地方法能夠訪問Java中定義的中文 字符及Java訪問本地方法產生的中文字符串,我定義了兩個方法用來做相互轉換。

· 方法一,將Java中文字符串轉為本地字符串

/** 第一個參數是虛擬機的環境指針第二個參數為待轉換的Java字符串定義第三個參數是本地存儲轉換後字符串的內存塊第三個參數是內存塊的大小 */ int JStringToChar(JNIEnv *env, jstring str, LPTSTR desc, int desc_len) { int len = 0; if(desc==NULLstr==NULL) return -1; //在VC中wchar_t是用來存儲寬字節字符(UNICODE)的數據類型 wchar_t *w_buffer = new wchar_t[1024]; ZeroMemory(w_buffer,1024*sizeof(wchar_t)); //使用GetStringChars而不是GetStringUTFChars wcscpy(w_buffer,env-GetStringChars(str,0)); env-ReleaseStringChars(str,w_buffer); ZeroMemory(desc,desc_len); //調用字符編碼轉換函數(Win32 API)將UNICODE轉為ASCII編碼格式字符串 //關於函數WideCharToMultiByte的使用請參考MSDN len = WideCharToMultiByte(CP_ACP,0,w_buffer,1024,desc,desc_len,NULL,NULL); //len = wcslen(w_buffer); if(len0 len

當然這只是其中之一方法:還有其它的方法欲了解參考資料有很多

JAVA如何調用C函數

要在java中調用c語言的庫,需要使用Java提供了JNI。

舉例說明

在c語言中定義一個 void sayHello()函數(打印Hello World);然後在Java中調用這個函數顯示Hello Word.

現在分別從Java和C語言兩部分說明:

1. Java 部分

首先定義一個HelloNative,在其中申明sayHello函數,函數要申明為Native 類型的.如下:

public class HelloNative {

public native void sayHello();

}

編譯這個類,生成class文件:

javac HelloWorld.java

利用javah生成需要的h文件

javah HelloNative

生成的 h文件大概如下:

/* DO NOT EDIT THIS FILE – it is machine generated */

#include jni.h

/* Header for class HelloNative */

#ifndef _Included_HelloNative

#define _Included_HelloNative

#ifdef __cplusplus

extern “C” {

#endif

/*

* Class: HelloNative

* Method: sayHello

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloNative_sayHello

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

可以看一下上面自動生成的程序,程序include了jni.h,這個頭文件在 $JAVA_HOME下的include文件夾下. 還可以發現生成的函數名是在之前的函數名前面加上了Java_HelloNative。

2. C語言部分

根據上面生成的h文件編寫相應的代碼實現,建立一個 HelloNative.cpp用來實現顯示Hello World的函數.如下:

#include stdio.h

#include “HelloNative.h”

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject)

{

printf(“Hello World!\n”);

}

代碼編寫完成之後,我們再用gcc編譯成庫文件,命令如下;

gcc -fPIC -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -shared -o libHelloNative.so HelloNative.cpp

這樣就會在當前目錄下生成一個libHelloNative.so的庫文件.這時需要的庫已經生成,在C語言下的工作已經完成了.

接下來需要在Java中編寫一個程序測試一下.在程序前,需要將我們的庫載入進去.載入的方法是調用Java的 System.loadLibrary(“HelloNative”);

public class TestNative

{

static {

try {

System.loadLibrary(“HelloNative”);

}

catch(UnsatisfiedLinkError e) {

System.out.println( “Cannot load hello library:\n ” + e.toString() );

}

}

public static void main(String[] args) {

HelloNative test = new HelloNative();

test.sayHello();

}

}

但是再編譯後,運行的時候,問題又出現了.

Cannot load hello library:

java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path

Exception in thread “main” java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V

at HelloNative.sayHello(Native Method)

at TestNative.main(TestNative.java:13)

載入庫失敗,但是庫明明就是放在當前文件夾下的,怎麼會載入失敗呢?

用System.getProperty(“java.library.path”)查看,發現java.library.path中並不u存在當前的目錄.主要有以下的幾個解決辦法:

1) 將生成的庫複製到java.library.path有的路徑中去,當然這樣不是很好

2) 設置環境變量export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,將當前的目錄加入到LD_LIBRARY_PATH中

3) 設置java 的選項,將當前的目錄加入到其中 .java -Djava.library.path=. $LD_LIBRARY_PATH

這樣之後程序就能夠成功的運行了.可以看見顯示的”Hello World!”了

java怎麼引用c

Java調用C語言程序時,主要是涉及到操作系統底層的事件。這種時間Java無法處理,例如用戶上傳一個視頻文件,需要後台給視頻加上水印,或者後台分離視頻流和音頻流。只能通過調用C語言處理。

使用Java如何去調用C語言的接口呢?使用Java的JNI技術。

具體調用步驟如下:

1.首先創建Java文件 HelloJni.java ,並創建native方法。

2.編譯Java文件並生成java頭文件。

3.創建C語言文件,HelloWorld.c。

4.生成動態鏈接庫文件 libhello.so。

5.設置動態鏈接庫文件的目錄。

6.把剛才生成的so文件拷貝到/home/lib下,然後執行class文件。

如何用C語言調用JAVA的類文件

Java可以通過JNI調用本地C語言方法,而本地C語言方法是以庫文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX機器上是SO文件形式),通過調用本地的庫文件的內部方法,使Java可以實現和本地機器的緊密聯繫,調用系統級的各接口方法。

原創文章,作者:OZCG,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/145328.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
OZCG的頭像OZCG
上一篇 2024-10-27 23:49
下一篇 2024-10-27 23:49

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字符串操作中,capitalize函數常常被用到,這個函數可以使字符串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • 單片機打印函數

    單片機打印是指通過串口或並口將一些數據打印到終端設備上。在單片機應用中,打印非常重要。正確的打印數據可以讓我們知道單片機運行的狀態,方便我們進行調試;錯誤的打印數據可以幫助我們快速…

    編程 2025-04-29

發表回復

登錄後才能評論