當前位置:首頁 » 編程軟體 » 安卓代碼可以條件編譯么

安卓代碼可以條件編譯么

發布時間: 2023-01-03 12:37:35

『壹』 新人求教,編譯一個最簡單的Android程序,提示下面的錯誤咋解決

在初學C語言時,可能會遇到有些問題理解不透,或者表達方式與以往數學學習中不同(如運算符等),這就要求不氣餒,不明白的地方多問多想,鼓足勇氣進行學習,待學完後面的章節知識,前面的問題也就迎刃而解了,這一方面我感覺是我們同學最欠缺,大多學不好的就是因為一開始遇到困難就放棄,曾經和好多同學談他的問題,回答是聽不懂、不想聽、放棄這樣三個過程,我反問,這節課你聽過課嗎?回答又是沒有,根本就沒聽過課,怎麼說自己聽不懂呢?相應的根本就沒學習,又談何學的好? 學習C語言始終要記住「曙光在前頭」和「千金難買回頭看」,「千金難買回頭看」是學習知識的重要方法,就是說,學習後面的知識,不要忘了回頭弄清遺留下的問題和加深理解前面的知識,這是我們學生最不易做到的,然而卻又是最重要的。學習C語言就是要經過幾個反復,才能前後貫穿,積累應該掌握的C知識。 那麼,我們如何學好《C程序設計》呢? 一.學好C語言的運算符和運算順序 這是學好《C程序設計》的基礎,C語言的運算非常靈活,功能十分豐富,運算種類遠多於其它程序設計語言。在表達式方面較其它程序語言更為簡潔,如自加、自減、逗號運算和三目運算使表達式更為簡單,但初學者往往會覺的這種表達式難讀,關鍵原因就是對運算符和運算順序理解不透不全。當多種不同運算組成一個運算表達式,即一個運算式中出現多種運算符時,運算的優先順序和結合規則顯得十分重要。在學習中,只要我們對此合理進行分類,找出它們與我們在數學中所學到運算之間的不同點之後,記住這些運算也就不困難了,有些運算符在理解後更會牢記心中,將來用起來得心應手,而有些可暫時放棄不記,等用到時再記不遲。 先要明確運算符按優先順序不同分類,《C程序設計》運算符可分為15種優先順序,從高到低,優先順序為1 ~ 15,除第2、3級和第14級為從右至左結合外,其它都是從左至右結合,它決定同級運算符的運算順序. 二.學好C語言的四種程序結構 (1)順序結構 順序結構的程序設計是最簡單的,只要按照解決問題的順序寫出相應的語句就行,它的執行順序是自上而下,依次執行。 例如;a = 3,b = 5,現交換a,b的值,這個問題就好像交換兩個杯子水,這當然要用到第三個杯子,假如第三個杯子是c,那麼正確的程序為: c = a; a = b; b = c; 執行結果是a = 5,b = c = 3如果改變其順序,寫成:a = b; c = a; b = c; 則執行結果就變成a = b = c = 5,不能達到預期的目的,初學者最容易犯這種錯誤。 順序結構可以獨立使用構成一個簡單的完整程序,常見的輸入、計算,輸出三步曲的程序就是順序結構,例如計算圓的面積,其程序的語句順序就是輸入圓的半徑r,計算s = 3.14159*r*r,輸出圓的面積s。不過大多數情況下順序結構都是作為程序的一部分,與其它結構一起構成一個復雜的程序,例如分支結構中的復合語句、循環結構中的循環體等。 (2) 分支結構 順序結構的程序雖然能解決計算、輸出等問題,但不能做判斷再選擇。對於要先做判斷再選擇的問題就要使用分支結構。分支結構的執行是依據一定的條件選擇執行路徑,而不是嚴格按照語句出現的物理順序。分支結構的程序設計方法的關鍵在於構造合適的分支條件和分析程序流程,根據不同的程序流程選擇適當的分支語句。分支結構適合於帶有邏輯或關系比較等條件判斷的計算,設計這類程序時往往都要先繪制其程序流程圖,然後根據程序流程寫出源程序,這樣做把程序設計分析與語言分開,使得問題簡單化,易於理解。程序流程圖是根據解題分析所繪制的程序執行流程圖。 學習分支結構不要被分支嵌套所迷惑,只要正確繪制出流程圖,弄清各分支所要執行的功能,嵌套結構也就不難了。嵌套只不過是分支中又包括分支語句而已,不是新知識,只要對雙分支的理解清楚,分支嵌套是不難的。下面我介紹幾種基本的分支結構。 ①if(條件) { 分支體 } 這種分支結構中的分支體可以是一條語句,此時「{ }」可以省略,也可以是多條語句即復合語句。它有兩條分支路徑可選,一是當條件為真,執行分支體,否則跳過分支體,這時分支體就不會執行。如:要計算x的絕對值,根據絕對值定義,我們知道,當x>=0時,其絕對值不變,而x<0時其絕對值是為x的反號,因此程序段為:if(x<0) x=-x; ②if(條件) {分支1} else {分支2} 這是典型的分支結構,如果條件成立,執行分支1,否則執行分支2,分支1和分支2都可以是1條或若干條語句構成。如:求ax^2+bx+c=0的根 分析:因為當b^2-4ac>=0時,方程有兩個實根,否則(b^2-4ac<0)有兩個共軛復根。其程序段如下: d=b*b-4*a*c; if(d>=0) {x1=(-b+sqrt(d))/2a; x1=(-b-sqrt(d))/2a; printf(「x1=%8.4f,x2=%8.4f\n」,x1,x2); } else {r=-b/(2*a); i =sqrt(-d)/(2*a); printf(「x1=%8.4f+%8.4fi\n」r, i); printf(「x2=%8.4f-%8.4fi\n」r,i) } ③嵌套分支語句:其語句格式為: if(條件1) {分支1}; else if(條件2) {分支2} else if(條件3) {分支3} …… else if(條件n) {分支n} else {分支n+1} 嵌套分支語句雖可解決多個入口和出口的問題,但超過3重嵌套後,語句結構變得非常復雜,對於程序的閱讀和理解都極為不便,建議嵌套在3重以內,超過3重可以用下面的語句。 ④switch開關語句:該語句也是多分支選擇語句,到底執行哪一塊,取決於開關設置,也就是表達式的值與常量表達式相匹配的那一路,它不同if…else 語句,它的所有分支都是並列的,程序執行時,由第一分支開始查找,如果相匹配,執行其後的塊,接著執行第2分支,第3分支……的塊,直到遇到break語句;如果不匹配,查找下一個分支是否匹配。這個語句在應用時要特別注意開關條件的合理設置以及break語句的合理應用。 (3)循環結構: 循環結構可以減少源程序重復書寫的工作量,用來描述重復執行某段演算法的問題,這是程序設計中最能發揮計算機特長的程序結構,C語言中提供四種循環,即goto循環、while循環、do –while循環和for循環。四種循環可以用來處理同一問題,一般情況下它們可以互相代替換,但一般不提倡用goto循環,因為強制改變程序的順序經常會給程序的運行帶來不可預料的錯誤,在學習中我們主要學習while、do…while、for三種循環。常用的三種循環結構學習的重點在於弄清它們相同與不同之處,以便在不同場合下使用,這就要清楚三種循環的格式和執行順序,將每種循環的流程圖理解透徹後就會明白如何替換使用,如把while循環的例題,用for語句重新編寫一個程序,這樣能更好地理解它們的作用。特別要注意在循環體內應包含趨於結束的語句(即循環變數值的改變),否則就可能成了一個死循環,這是初學者的一個常見錯誤。 在學完這三個循環後,應明確它們的異同點:用while和do…while循環時,循環變數的初始化的操作應在循環體之前,而for循環一般在語句1中進行的;while 循環和for循環都是先判斷表達式,後執行循環體,而do…while循環是先執行循環體後判斷表達式,也就是說do…while的循環體最少被執行一次,而while 循環和for就可能一次都不執行。另外還要注意的是這三種循環都可以用break語句跳出循環,用continue語句結束本次循環,而goto語句與if構成的循環,是不能用break和 continue語句進行控制的。 順序結構、分支結構和循環結構並不彼此孤立的,在循環中可以有分支、順序結構,分支中也可以有循環、順序結構,其實不管哪種結構,我們均可廣義的把它們看成一個語句。在實際編程過程中常將這三種結構相互結合以實現各種演算法,設計出相應程序,但是要編程的問題較大,編寫出的程序就往往很長、結構重復多,造成可讀性差,難以理解,解決這個問題的方法是將C程序設計成模塊化結構。 (4)模塊化程序結構 C語言的模塊化程序結構用函數來實現,即將復雜的C程序分為若干模塊,每個模塊都編寫成一個C函數,然後通過主函數調用函數及函數調用函數來實現一大型問題的C程序編寫,因此常說:C程序=主函數+子函數。 因此,對函數的定義、調用、值的返回等中要尤其注重理解和應用,並通過上機調試加以鞏固。 三.掌握一些簡單的演算法 編程其實一大部分工作就是分析問題,找到解決問題的方法,再以相應的編程語言寫出代碼。這就要求掌握演算法,根據我們的《C程序設計》教學大綱中,只要求我們掌握一些簡單的演算法,在掌握這些基本演算法後,要完成對問題的分析就容易了。如兩個數的交換、三個數的比較、選擇法排序和冒泡法排序,這就要求我們要清楚這些演算法的內在含義 結語:當我們把握好上述幾方面後,只要同學們能克服畏難、厭學、上課能專心聽講,做好練習與上機調試,其實C語言並不難學

『貳』 怎麼樣將自己開發的Android應用程序編譯到系統Image中

1. 搭建編譯環境
編譯環境: Ubuntu 10.10
Android版本:Android 2.2

編譯過程中可能需要在Ubuntu上安裝必要的一些軟體,我安裝過的包含如下軟體,不同的系統可能會有差別:
jdk6(Android官方建議裝jdk5,但是我在編譯時會遇到java override問題,改用6沒有任何問題), bison, lib64z1-dev, libasound2-dev, flex, gperf, libncurses5-dev

2. 應用程序存放目錄
SimpleJNI是採用Android NDK和Java編寫的程序,包含apk和so庫文件,它的源代碼在source tree的development/samples/目錄下。
實際上package在編譯時所放的目錄並沒有明確限定,編譯後apk和so存放的位置是根據目錄下Android.mk所指定的編譯類型所決定的,例如:
SimpleJNI根目錄下的Android.mk中有一行include $(BUILD_PACKAGE),表示將該目錄下的模塊編譯成package,即apk文件,默認存放的位置為/system/app。
SimpleJNI/jni目錄下的Android.mk中有一行為include $(BUILD_SHARED_LIBRARY),表示將該目錄下的native.cpp編譯為共享庫文件,即so文件,默認存放的位置為/system/lib

因此,如果我們想要將自己編寫的程序編譯至image中,只需要將Eclipse下完成的整個工程到source tree下的某個目錄即可,我一般習慣放到packages/apps下。

3. 添加Android.mk
完成了上一步,可以知道,Android.mk在編譯中起著至關重要的作用,這其實就是Android編譯環境中的make file。為了完成我們的工作,需要在源代碼中添加Android.mk。添加自己的Android.mk可以仿照SimpleJNI中的Android.mk,稍微修改即可。我們首先看看SimpleJNI目錄下的兩個Android.mk的內容:
根目錄下的Android.mk

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := SimpleJNI

LOCAL_JNI_SHARED_LIBRARIES := libsimplejni

LOCAL_PROGUARD_ENABLED := disabled

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

根目錄下的Android.mk決定了整個工程編譯的配置,其中,

LOCAL_PATH 定義了當前的目錄

LOCAL_MUDULE_TAGS 定義了當前模塊的類型,編譯器在編譯時會根據類型的不同有些差別,有些tags的mole甚至不會被編譯至系統中。LOCAL_MUDULE_TAGS主要有如下幾種:user debug eng tests optional samples shell_ash shell_mksh。optional表示在所有版本的編譯條件下都被編譯至image中,剩下的表示在該版本中才會被編譯只image中,如user表示在user版本下才會被編譯至image中。
對於包含LOCAL_PACKAGE_NAME的mk文件,該項默認為optinal,具體可以參看build/core/package.mk。SimpleJNI中定義為samples的具體作用我也不太清楚,為了保險起見,我自己的apk一般定義為optional。

LOCAL_SRC_FILES 定義了編譯apk所需要的java代碼的目錄

LOCAL_PACKAGE_NAME 這里需要改成自己的package的名字

LOCAL_JNI_SHARED_LIBRARIES 定義了要包含的so庫文件的名字,如果你的程序沒有採用JNI,這行不需要。

LOCAL_PROGUARD_ENABLED 定義了Java開發中的ProGuard壓縮方法,主要用來分析壓縮程序的,在我自己的應用中我沒有加這行。

include $(BUILD_PACKAGE) 這行是build的關鍵,表示當前java代碼build成apk

include $(call all-makefiles-under,$(LOCAL_PATH)) 表示需要build該目錄下的子目錄的文件,這樣編譯系統就會在當前目錄下的子目錄尋找Android.mk來編譯so等其它程序。

根據上述所寫,創建我自己的Android.mk如下:

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := TestJniApp

LOCAL_JNI_SHARED_LIBRARIES := libtestjniapp

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))
看起來很簡單吧,基本不需要改動即可。

Jni目錄下的Android.mk

由於我們的TestJniApp是用JNI完成的,包含C源代碼,因此也需要一個jni目錄下的Android.mk。同樣首先看看SimpleJNI中jni目錄下的Android.mk的內容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

# This is the target being built.
LOCAL_MODULE:= libsimplejni

# All of the source files that we will compile.
LOCAL_SRC_FILES:= /
native.cpp

# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := /
libutils

# No static libraries.
LOCAL_STATIC_LIBRARIES :=

# Also need the JNI headers.
LOCAL_C_INCLUDES += /
$(JNI_H_INCLUDE)

# No special compiler flags.
LOCAL_CFLAGS +=

# Don't prelink this library. For more efficient code, you may want
# to add this library to the prelink map and set this to true. However,
# it's difficult to do this for applications that are not supplied as
# part of a system image.

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULE 當前模塊的名字,即編譯後的so文件的名字

LOCAL_SRC_FILES 所要編譯的文件

LOCAL_SHARED_LIBRARIES, LOCAL_STATIC_LIBRARIES 該模塊要鏈接的動態庫和靜態庫。

LOCAL_C_INCLUDES 要包含的頭文件

LOCAL_CFLAGS C語言編譯選項

LOCAL_PRELINK_MODULE 定義是否使用prelink工具,它用事先鏈接代替運行時鏈接的方法來加速共享庫的載入,不僅可以加快起動速度,還可以減少部分內存開銷。

經過修改後,我自己的TestJniApp中jni目錄下的Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libtestjniapp
LOCAL_SRC_FILES := com_test_app_Jni.c
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

這里有一點需要注意,如果要將so文件編譯入image,必須要修改LOCAL_MODULE_TAGS,將原有的值samples修改為user,或者可以直接刪掉 。刪掉是因為對於包含LOCAL_MODULE的mk文件,如果沒有指定LOCAL_MODULE_TAGS,該項默認為user,而只有定義為user的情況下,才會將so文件編譯入image,具體定義可以參看build/core/base_rule.mk。

4. 修改/bulid/target/proct/generic.mk 把工程編譯到系統中
至此,還有最後一部工作。為了將工程編譯進入image,還需要在/bulid/target/proct/generic.mk文件中將package name添加進去

PRODUCT_PACKAGES := /
AccountAndSyncSettings /
CarHome /
DeskClock /
……
SyncProvider /
TestJniApp

完成上面這些步驟後,在source tree根目錄下編譯image就可以了。

『叄』 C語言中條件編譯的作用

條件編譯屬於三種宏定義中的一種,條件指示符的最主要目的是防止頭文件的重復包含和編譯,例如:一個c文件包含同一個h文件多次,如果不加#ifndef宏定義,會出現變數重復定義的錯誤


條件編譯常用的有四個預處理命令:#if、#else、#elif、#endif。

#if指令的形式為:

#if常量表達式
代碼塊
#endif

#if後面的常量表達式為值,則編譯它與#endif之間的代碼,否則跳過這些代碼。指令#endif標識一個#if塊的結束。


#else被使用來標志#if的末尾和#else塊的開始。這是必須的,因為任何#if僅有一個#endif與之關聯。


#elif意指"else if",它形成一個if else if嵌套語句用於多種編譯選擇。#elif後面跟一個常量表達式,如果表達式是真,則編譯其後的代碼塊,不對其他#elif表達式進行檢測,否則順序測試下一塊。常見的形式如下:

形式1:

#ifdef標識符
/*程序段1*/
#else
/*程序段2*/
#endif

它的作用是當標識符已經由#define定義過了,則編譯程序段1,否則編譯程序段2,也可以使用簡單形式

#ifdef標識符
/*程序段1*/
#endif

形式2:

#ifndef標識符
#define標識符
/*程序段1*/
#else
/*程序段2*/
#endif

它的作用是當標識符沒有由#define定義過,則編譯程序段1,否則編譯程序段2 ,也可以使用簡單形式

#ifndef標識符
#define標識符
/*程序段1*/
#endif

形式3:

#if表達式
/*程序段1*/
#else
*程序段2*/
#endif

它的作用是 當「表達式」值為真時編譯程序段1。否則則編譯程序段2,也可以使用簡單形式

#if表達式
/*程序段1*/
#endif

形式4:

#if表達式1
/*程序段1*/
#elif表達式2
/*程序段2*/
............
#elif表達式n
/*程序段n*/
#endif

它的作用是當「表達式1」值為1時編譯程序段1,表達式2的值為真是編譯程序段2,否則依次順序判斷到表達式n。


最後,條件編譯的條件是一個常量表達式,支持邏輯與&&和或||運算。以上四種形式的條件編譯預處理結構都可以嵌套使用,

標識符: 在理論上來說可以是自由命名的,但每個頭文件的這個標識符都應該是唯一的。標識的命名規則一般是頭文件名全大寫,前後加下劃線,並把文件名中的「.」也變成下劃線,如:stdio.h。

#ifndef_STDIO_H_
#define_STDIO_H_
/*程序段*/
#endif

『肆』 怎樣使用動態庫中的條件編譯

publicstaticvoidabc(){#region要執行的代碼stringstrCode=@"usingSystem;usingSystem.Text;usingSystem.Collections.Generic;usingSystem.Linq;namespaceaaa{publicclassbbb{publicstaticstringccc(stringname){return""abc"";}}}";#endregion#region編譯參數=newCompilerParameters();objCompilerParams.GenerateExecutable=false;//編譯成exe還是dllobjCompilerParams.GenerateInMemory=false;//是否寫入內存,不寫入內存就寫入磁碟objCompilerParams.OutputAssembly="E:\abc.dll";//輸出路徑objCompilerParams.IncludeDebugInformation=false;//是否產生pdb調試文件默認是falseobjCompilerParams.ReferencedAssemblies.Add("System.dll");objCompilerParams.ReferencedAssemblies.Add("System.Core.dll");//編譯器選項:編譯成(存儲在內存中)的DLL/*objCompilerParams.CompilerOptions="/target:library/optimize";//編譯時在內存輸出objCompilerParams.GenerateInMemory=true;//不生成調試信息objCompilerParams.IncludeDebugInformation=false;*/#endregion#region編譯//創建編譯類CSharpCodeProviderobjCompiler=newCSharpCodeProvider();//進行編譯=objCompiler.CompileAssemblyFromSource(objCompilerParams,strCode);#endregion#region取得編譯成程序集,准備執行程序集里的類中的方法//獲取編譯結果:程序集AssemblyobjAssembly=objCompileResults.CompiledAssembly;//獲取編譯成的程序集的信息/*objectobjMainClassInstance=objAssembly.CreateInstance("Program");TypeobjMainClassType=objMainClassInstance.GetType();*/#endregion#region調用程序集中的類,執行類中的方法,得到結果/*objMainClassType.GetMethod("Main").Invoke(objMainClassInstance,null);objMainClassType.GetMethod("PrintWorld").Invoke(objMainClassInstance,null);*/#endregion

『伍』 android studio調試代碼有沒有運行

不管是什麼類型的編程語言,在程序開發中我們都難免會遇到各種各樣的bug,遇到bug相信大家最常用的調試手段應該就是日誌和debug了吧。其實除此之外還有很多代碼調試手段,本文是小編在一個android網站上面看到的,有關Android Studio開發工具中代碼調試相關技能技巧,在此分享給大家,一起來看看吧。

你知道上圖的三個斷點有什麼不同么?你有關注過Android Studio旁邊斷點的區別嗎?不了解也沒關系,下面就是一位Android大神和大家分享的Android Studio debug的相關知識,新技能get走起~~

調試基礎

一般來說有兩種辦法調試一個debuggable的apk;其一是下好斷點,然後用debug模式編譯安裝這個app;其二是 attach process ,在Android Studio裡面就是這么一個對話框:

第二種方法比較常用,我們可以在啟動apk之後,直接下斷點,然後attach process到制定進程,條件觸發之後就可以直接進入調試模式。

其他的一些單步執行, stepinto , step out , force step into 等就不提了;基本的跟蹤手段。而下斷點最簡單的辦法,是在代碼編輯器的左側,行號右邊滑鼠點擊一下即可。

Evaluate Expression

這個功能非常實用,可以在斷點處直接進入一個求值環境,在這里你可以執行任何你感興趣的表達式;如下圖:

比如在斷點處有一個對象
object,如果你要查看它的某個屬性很簡單,在Debug窗口就能看到,但是如果你想要執行它的某個方法看看結果是什麼呢?藉助這個可以實現。當然它
的功能遠不止這么多,相當於直接進入了一個 REPL 環境,非常實用。忘了說了,快捷鍵 Alt + F8 :P

條件斷點

假設你的斷點在一個列表的循環裡面,可是你只對這個列表的某一個元素感興趣,只想在遇
到這個元素的時候才斷下來;你是一直人肉 F9
直到滿足條件嗎?條件斷點就是滿足這種需求的,顧名思義,在特定條件下的斷點。使用起來也非常簡單,在你的斷點上滑鼠有件會出現一個小窗口,寫上條件即
可。

日誌斷點

很多時候我們調試更多的是列印日誌定位異常代碼,縮小范圍之後再使用斷點解決問題;所以經常做的事情就是在代碼裡面添加日誌信息,輸出函數參數,返回信息,輸出我們感興趣的變數信息等。

但是這么做一個問題就是,我們添加了日誌代碼需要重新編譯;在沒有 Instant Run 之前的黑暗時代這么做是非常痛苦的,每次編譯少則幾十秒,多則幾分鍾;這樣無意義的等待簡直就是折磨;其實,除了熱部署工具,我們還可以使用日誌斷點解決這個問題。

首先,在想要輸出信息的地方下一個斷點;然後右鍵這個斷點,在出現的設置框裡面把這個
斷點的 suspend 屬性設置為 False ,這樣雖然叫做「斷點」,但是並不會真正斷下來;然後,我們在 log message
裡面填上我們想要輸出的日誌信息。如下圖(注意標紅位置):

這樣,每次代碼執行到這個斷點的位置,並不會使我們的程序停下來,而是輸出我們告訴它的日誌信息,然後繼續執行;非常方便。

方法斷點

傳統的調試方式是以行為單位的,所謂單步調試;但是很多時候我們關心的是某個函數的參
數,返回值;使用方法斷點,我們可以在函數級別進行調試;如果經常跳進跳出函數或者只對某個函數的參數感興趣,這種類型的斷點非常實用。具體使用方法有兩
種方式;最簡單的是在你感興趣的方法頭那一行打上斷點,這時候你會發現斷點圖標有點不一樣,這就是方法斷點了,如下圖:

另外一種方式是通過 斷點設置窗口。

異常斷點

在有些情況下,我們只對某些特定的異常感興趣,或者我們只對異常感興趣;我們希望只要程序發生異常程序就能斷下來;這好像保存現場一樣,只要發生命案了(異常),第一時間保存現場,這樣什麼指紋之類的線索就會清晰很多,壞蛋就算想逃也是插翅難飛啊。

Android Studio給了我們這個能力!那就是 異常斷點 !可以在特定異常發生的時候,直接讓整個程序斷下來;如果你對所有異常感興趣,直接 Throwable 即可。

具體做法是,進入 Run ->View BreakPoints 或者使用快捷鍵打開斷點設置窗口;如下圖:

點擊左上角的:heavy_plus_sign: ,會出現一個選擇框;選擇 Exception Breakpoint ;然後會出現一個對話框,選擇你感興趣的異常:

Field WatchPoint

在上面我們添加異常斷點的時候,點擊加號的時候,有四個選項;第一個就是我們前面所說的第二種方法斷點的添加方式,第三個是異常斷點,那麼第二個 Field WatchPoint 是干什麼的呢?

有沒有這樣一種場景:你發現某個值莫名其妙滴不知道什麼時候被誰給修改了,罪魁禍首是
誰?Java雖然是值傳遞,但是引用也可以是值;對象全部存放在堆上面,而堆是被所有線程共享的,因此在非常復雜的場景下,你根本不知道這些共享變數被誰
修改了,這樣非常危險;在多線程環境下,不變性是一個很重要的特性,我們看到高並發的語言諸如 Erlang , Scala
對於這種不變性都有著某種程度的支持。

那麼我們怎麼揪出這個修改我們值的搗蛋鬼呢?那就是這個 Field WatchPoint 的功能了;使用它我們可以在某個 Field 被訪問或者修改的時候讓程序斷下來;完美解決這個問題。

下斷點的方式和方法斷點類似,也有兩種;第一種是直接在某個欄位的聲明處下斷點,這時候斷點圖標會改變,如下圖:

右鍵這個斷點我們可以進行一些設置,比如默認是被修改的時候斷下來,你也可以改為每次訪問這個欄位就斷下來。

另外一種方式是 Run ->View BreakPoint 打開設置,與異常斷點類似。

結束語

上面介紹了這么多代碼調試的功能,其實還有很多細節;打開斷點設置窗口(Run -> View Breakpoint`):

我們可以對 感興趣的類,感興趣的某個特定對象下斷點,也可以設置斷點的次數,還能使斷點在特定的線程才斷下來;這些細節就不詳細介紹了,大家自己去發掘!

以上就是Android Studio中一些超有用的調試技巧,大家在代碼調試中,不妨可以試試上述方法,希望通過本文的分享,大家也能和我一樣收獲頗多。

『陸』 JAVA如何實現條件編譯

條件編譯絕對是一個好東西。如在C或CPP中,可以通過預處理語句來實現條件編譯。代碼如下:
#IFDEF DEBUG
#UNDEF DEBUG
#ENDIF
#define DEBUG
#IFDEF DEBUUG
/*
code block 1
*/
#ELSE
/*
code block 2
*/
#ENDIF
但是在JAVA中卻沒有預處理,宏定義這些東西,而有時在一些項目中,我們又需要條件編譯。那麼,在JAVA中,該如何實現條件編譯呢?
我們來看一個例子。
編寫一個helloworld程序。代碼如下:
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
保存為Hello.java並編譯,得到一個class文件,並且觀察到文件大小是417位元組。然後我們對這個文件進行反編譯,用jd-gui。得到代碼如下:
import java.io.PrintStream;
public class Hello

『柒』 條件編譯的指令

條件編譯指令將決定哪些代碼被編譯,而哪些是不被編譯的。可以根據表達式的值或者某個特定的宏是否被定義來確定編譯條件。 一般形式有如下幾種
(1) #if表達式//語句段1#else//語句段2]#endif如果表達式為真,就編譯語句段1,否則編譯語句段2
(2) #if表達式1//語句段1#elif表達式2//語句段2#else//語句段3#endif如果表達式1真,則編譯語句段1,否則判斷表達式2;如果表達式2為真,則編譯語句段2,否則編譯語句段3 (1)#ifdef的一般形式: #ifdef宏名//語句段#endif作用:如果在此之前已定義了這樣的宏名,則編譯語句段。
(2)#ifndef的一般形式: #ifndef宏名//語句段#endif作用:如果在此之前沒有定義這樣的宏名,則編譯語句段。
#else可以用於#ifdef和#ifndef中,但#elif不可以。 #include<stdio.h>#defineLETTER1intmain(intargc,char*argv[]){charstr[20]=CLanguage,c;inti;i=0;while((c=str[i])!=''){i++;#ifdefLETTER1if(c>='a'&&c<='z')c=c-32;#elseif(c>='A'&&c<='Z')c=c+32;#endifprintf(%c,c);}return0;}運行結果為clANGUAGE

『捌』 C語言中條件編譯和If語句之間的差別,各適用於什麼情況

條件編譯是C語言中預處理部分的內容,它是編譯器編譯代碼時最先處理的部分,

條件編譯裡面有判斷語句,比如 #if 、#else 、#elif 及 #endif
它的意思是如果宏條件符合,編譯器就編譯這段代碼,否則,編譯器就忽略這段代碼而不編譯,如
#define A 0 //把A定義為0
#if (A > 1)
printf("A > 1"); //編譯器沒有編譯該語句,該語句不生成匯編代碼
#elif (A == 1)
printf("A == 1"); //編譯器沒有編譯該語句,該語句不生成匯編代碼
#else
printf("A < 1"); //編譯器編譯了這段代碼,且生成了匯編代碼,執行該語句
#endif

而 if 語句則不然,if 是 C 語言中的關鍵字,它根據表達式的計算結果來覺定執行那個語句,它裡面的每個分支都編譯了的, 如
#define A 0
if (A > 1)
printf("A > 1"); //編譯器編譯該語句,但因為A == 0 未執行
else if(A == 1)
printf("A == 1"); //編譯器編譯該語句,但因為A == 0 未執行
else
printf("A < 1"); //編譯器編譯該語句,因為A == 0 故執行

所以 簡單地講,條件編譯是根據 宏條件 選擇性地編譯語句,它是編譯器在編譯代碼時完成的;
條件語句是根據條件表達式選擇性地執行語句,它是在程序運行時進行的。

『玖』 android怎麼在Eclipse裡面配置條件編譯

eclipse下編譯android代碼的流程如下:
1.點擊android工程,點擊run

2.彈出窗口,選擇運行設備,如下圖,點擊run就可以編譯,運行

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:593
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:888
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:581
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:765
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:684
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1012
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:255
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:114
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:806
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:712