① c語言結構體 編譯出錯
b b1={a1,a2,0};
改成:
b b1={{0,0}, {1,1} , 0};
編譯器不支持用結構體變數來初始化結構體變數成員
② 如何調試android NDK 交叉編譯的cpp文件
主要講一下具體的步驟,具體的ndk指令我就不說了,貼的文章都有:
首先是寫一個.java文件,本例中是HprofDumper.java
具體如下:
public class HprofDumper {
public native boolean hprofDumper(String filename, String outname);
}
然後用命令javac HprofDumper.java 生成.class文件
再用javah HprofDumper 生成相應的.h文件
生成的.h文件如下
#include
#ifndef _Included_HprofDumper
#define _Included_HprofDumper
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jboolean JNICALL Java_HprofDumper_hprofDumper
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
然後只需要在對應的.cpp文件完成相應函數即可,核心代碼如下:
#include "HprofDumper.h"
#include "hprof.h"
JNIEXPORT jboolean JNICALL Java_HprofDumper_hprofDumper
(JNIEnv *env, jobject obj, jstring in_file, jstring out_file)
{
const char *filename = env->GetStringUTFChars(in_file, 0);
const char *outname = env->GetStringUTFChars(out_file, 0);
return hprof_mp(filename, outname);
}
其中hprof_mp是純c++代碼,引入即可。
有一點需要注意,標紅了已經,就是生成的.h文件函數並沒具體形參名字,只有形參類型,在.cpp文件中要加入相應的形參名字,本例為env、 obj、 in_file和out_file。
還有一點c和c++的區別,就是env的使用。
本例中C++為env->GetStringUTFChars(in_file, 0);
如果是C就應該改為(env)->GetStringUTFChars(env,in_file, 0);
調用Java類型 : C中調用Java中的String類型為 jstring;
C語言方法名規則 : Java_完整包名類名_方法名(JNIEnv *env, jobject thiz), 注意完整的類名包名中包名的點要用 _ 代替;
參數介紹 : C語言方法中有兩個重要的參數, JNIEnv *env, jobject thiz ;
-- JNIEnv參數 : 該參數代表Java環境, 通過這個環境可以調用Java中的方法;
-- jobject參數 : 該參數代表調用jni方法的類,;
調用jni.h中的NewStringUTF方法 : 該方法的作用是在C語言中創建一個Java語言中的String類型對象, jni.h中是這樣定義的 jstring (*NewStringUTF)(JNIEnv*, const char*), JNIEnv 結構體中包含了 NewStringUTF 函數指針, 通過 JNIEnv 就可以調用這個方法;
完成代碼編寫後,在當前目錄下完成Android.mk和Application.mk的編寫
首先是Android.mk
本例中為:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hprof-mper
LOCAL_C_INCLUDES += external/stlport/stlport
LOCAL_C_INCLUDES += bionic
LOCAL_C_INCLUDES += bionic/libstdc++/include
LOCAL_SRC_FILES := HprofDumper.cpp \
xx.cpp \
xx.cpp \
xx.cpp \
xx.cpp \
xx.cpp \
xx.cpp \
xxx.cpp
LOCAL_SHARED_LIBRARIES := libstlport
include $(BUILD_SHARED_LIBRARY)
注意標紅的是最關鍵的,LOCAL_C_INCLUDES 顧名思義是需要的頭文件的所在的目錄,那三個參數主要為了引入STL,最重要!!LOCAL_SHARED_LIBRARIES 我一直生成失敗就是沒加這個參數,不光要引入頭文件,還要引入具體的lib,這就是這個欄位的作用。
具體欄位的作用:
-- LOCAL_PATH : 代表mk文件所在的目錄;
-- include $(CLEAR_VARS) : 編譯工具函數, 通過該函數可以進行一些初始化操作;
-- LOCAL_MODULE : 編譯後的 .so 後綴文件叫什麼名字;
-- LOCAL_SRC_FILES: 指定編譯的源文件名稱;
-- include $(BUILD_SHARED_LIBRARY) : 告訴編譯器需要生成動態庫;
Applicaion.mk中就一行
APP_STL = stlport_static
表示使用stl靜態庫。
注意:我用了STL,大家沒有用STL的當然不用引入這些啦~
③ 怎樣使用c++編譯器
對於初學c/c++的人,我建議最好在使用dos 環境下的編譯器,這樣不至於在GUI的環境(比如vc、bcb)里給弄糊塗了。那麼在dos環境下如何使用c/c++的編譯器了,其實很簡單,下面用vc為例;
首先你告訴LIB和INCLUDE在什麼地方,在就告訴編譯的程序在什麼地方,這樣我們可以在任何目錄下都可以使用編譯器,要作到上面的,就理所當然要設定path了!設定如下:
vc:假定你的vc安裝在如下目錄:
C:\Program Files\Microsoft Visual Studio\VC98\Include
C:\Program Files\Microsoft Visual Studio\VC98\MFC\Include
C:\Program Files\Microsoft Visual Studio\VC98\Lib
C:\Program Files\Microsoft Visual Studio\VC98\MFC\Lib
C:\Program Files\Microsoft Visual Studio\VC98\Bin
C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin
那麼寫一個批處理文件(autoexec.bat),內容如下:
set path=C:\Program Files\Microsoft Visual Studio\VC98\Bin;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin (找到vc的編譯器cl.exe位置,同時也可以調用MSPDB60.DLL文件)
set Include=C:\Program Files\Microsoft Visual Studio\VC98\Include;C:\Program Files\Microsoft Visual Studio\VC98\MFC\Include
set Lib=C:\Program Files\Microsoft Visual Studio\VC98\Lib;
C:\Program Files\Microsoft Visual Studio\VC98\MFC\Lib
當然如果你不用mfc也可以這樣:
set path=C:\Program Files\Microsoft Visual Studio\VC98\Bin;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin
set Include=C:\Program Files\Microsoft Visual Studio\VC98\Include
set Lib=C:\Program Files\Microsoft Visual Studio\VC98\Lib
如果你是使用的bcb的編譯器,設置方法與上面類似!
那麼如何在dos 用c/c++的編譯器編譯程序呢?
那就更簡單了!如下:
C:\> CL test.cpp <回車>(呵呵,當然你可以在其他目錄下去執行,只要是你編譯的cpp文件的目錄就行)
至於執行cl.exe有些什麼參數實現條件編譯,就要自己去查了!:)
當然,上面的方法不適合開發大型的項目,因為很明顯文檔、程序管理不方便!
④ C語言中 變數作用域的區別
作用域和生存周期是完全不同的兩個概念。作用域可以看作是變數的一個有效范圍,就像網游中的攻擊范圍一樣;生存周期可以看成是一個變數能存在多久,能在那些時段存在,就像網游中的魔法持續時間……
簡單的以一個局部變數來舉個例子:
在main函數中聲明了變數a,那麼a的作用域就是main函數內部,脫離了main函數,a就無法使用了,main函數之外的函數或者方法,都無法去使用a。那麼a的生存周期是指a在那些時候存在,具體到這個例子,a什麼時候存在,要取決於main函數,或者說,main函數只要被調用,且調用沒有完成,那麼a就將存在。除此以外的情況,a都將被釋放。
生存周期也可以理解為從聲明到釋放的之間的時間。
變數具體可以分為全局變數、靜態全局變數、靜態局部變數和局部變數。
按存儲區域分:全局變數、靜態全局變數和靜態局部變數都存放在內存的全局數據區,局部變數存放在內存的棧區
按作用域分:全局變數在整個工程文件內都有效;靜態全局變數只在定義它的文件內有效;靜態局部變數只在定義它的函數內有效,只是程序僅分配一次內存,函數返回後,該變數不會消失;局部變數在定義它的函數內有效,但是函數返回後失效。
全局變數和靜態變數如果沒有手工初始化,則由編譯器初始化為0。局部變數的值不可知。