1. objective-c 中如何在一個函數中調用自己類中的另外一個函數
Objective-c方法調用流程
Objective-c是一門動態語言,動態兩個字主要就體現在我們調用方法的時候,運行時回動態的查找方法,然後調用相應的函數地址。運行時是整個Objective-c程序的基石,有了它我們的程序才能正常運行起來。
NSObject是Cocoa中絕大部分類的基類,它主要是提供了序列話,拷貝對象,以及支持運行時動態識別的框架。
在Objective-c中每一個類對象最開始的位置都會有一個isa指針,該指針指向一塊內存區域,該部分主要包含兩部分信息:
1、指向父類的指針。
2、自身的方法分發表。
有了這兩部分,Objective-c的方法的調用流程就可以跑起來了。當我們調用一個對象的某一個方法的時候,首先會在當前類的分發表中尋找該方法,如果找不到對應的方法,然後再去其父類中尋找該方法,依次類推直到找到對應的方法為止,流程圖如下:

你可能會想到,如果一個類有很深的繼承層次,每次去調用根類的某個函數,豈不是都要做很多次查找。理論上是這個樣子的,不過runtime也並非那麼傻,它會為每一個類(不是對象)維護一個經常調用的方法的列表,只要調用過就會緩存起來(官方沒有明確說明緩存機制),這樣當程序運行穩定以後整個方法調用的過程就會更加高效。
通過學習官方文檔Objective-C Runtime Programming Guide,可以發現其實所有的selector調用最後都會轉化為C類型的函數調用。舉個例子我們創建了一個A類型的對象aSample,然後調用其test方法([aSample test]),編譯的時候,編譯器就會將該調用轉化為objc_send(aSample, selector)的形式,runtime會調用test方法實現所對應的函數地址。該函數的參數包含了兩個隱含的參數self以及_cmd,其中self指向調用該方法的對象,_cmd則代表要調用的方法。
前面提到了NSObject提供了很多遍歷的方法可以和運行時進行交互,其中有個方法methodForSelector,通過它我們可以直接獲取到指定的方法對應的函數指針。通常我們直接使用Objective-c方式的方法調用就可以了,但有時程序中可能會頻繁的調用某一個方法,為了提高效率。我們可以直接獲取到方法對應的函數地址,然後直接調用該函數,這樣就少了動態識別的時間。
2. 在c語言編程中,傳值方式和傳引用方式之間有什麼區別
傳值方式:
當一個函數是傳值方式的時候,你調用這個函數的時候傳入的實參的值會被拷貝到形參,
但是形參與實參之間並沒有什麼聯系,比如變數b=5,a=b;這個時候將b賦值給a,他們的值相等,但是當這以後無論a的值怎麼改變都不會影響到b,b=5,a=b;a=1;這時候b依然是5,這就是傳值方式
#include<stdio.h>
voidadd(inta,intb)
{
a=a+b;//改變了形參a的值
returna;
}
voidmain()
{
inta=1,b=2;
printf("%d ",add(a,b));//3
printf("%d ",a);//1
printf("%d ",b);//2
}
傳引用方式:
當你調用一個函數時,傳入的是實參的地址的時候,這時候修改形參,實參也會受到影響,不過這種傳地址某種意義是傳值,首先將實參的地址拷貝到形參,他們兩個以後就沒有關系了,你也可以改變形參保存的地址,實參的地址不會改變,但是你操作的是形參對應地址的內容,與實參對應地址的內容一致,操作是同一個對象,所以形參對這個地址的操作,在實參那裡也會看到效果
#include<stdio.h>
voidadd(int*a,int*b)
{
*a=*a+*b;//改變了形參a的值
return*a;
}
voidmain()
{
inta=1,b=2;
printf("%d ",add(&a,&b));//3
printf("%d ",a);//3
printf("%d ",b);//2
}
3. C語言定義一個頭文件的格式和引用它的方法
擴展名為.h的文件,在C語言中被稱為header file, 也就是頭文件。
頭文件的數據格式就是普通的文本文件,可以通過新建文本文件(txt),再把擴展名改為.h的方式創建,在此不贅述。
一、頭文件內容格式。
頭文件內容並沒有固定的格式要求,不過一般為防止嵌套引用給編譯器帶來死鎖或者沒必要的開銷,一般約定整個頭文件中所有內容在一個條件編譯下,即如下格式:
#ifndef 宏名
#define 宏名
//頭文件主體
#endif
這樣可以保證一個頭文件在一個源文件中最多隻被引用一次。為避免宏名重復,宏名一般由頭文件名轉換而來,如果頭文件名是xxx.h,那麼宏名一般定義為:
_XXX_H_
即前後各加一個下劃線,同時文件名中除數字、字母、下劃線以外的字元均轉換為下劃線(_)。
頭文件主體中內容同樣沒有做強制約定,可以出現在源文件(.c)中的任何代碼均可以放在頭文件中。不過一般情況下可以包括以下幾種內容:
1 引用其它頭文件,格式為
#include <xxx.h>
或
#include "xxx.h"
二者區別在介紹頭文件引用時再詳細介紹。
2 定義私有類型。比如
typedef unsigned long U32; //為了簡寫而給無符號32位整型定義一個新的名字
struct xxx {};
也可以是enum, union等復雜類型。
3 宏定義。比如
#define MAX(a,b) (a>b?a:b)
4 函數聲明。比如
void test_function(void);
5 全局變數聲明。比如
extern int global_var;
6 如果有一個靜態全局變數需要在不同源文件中使用,但各文件之間互不相關。那麼可以放在頭文件中。如:
static int gs_var = 3;
7 對於支持C99規范的C編譯器,還可以把內聯函數定義在頭文件中。比如
staticinlineintget_min(inta,intb)
{
if(a>b)returnb;
returna;
}
以上是常見的頭文件中的元素。但實際上頭文件中也可以放全局變數的定義,全局函數的實現等。但是頭文件中一旦定義了這樣的元素,這個頭文件在一個工程中只能被一個文件引用,否則編譯器會報重復定義的錯誤。
比如如果有一個規模很大的常量數組,比如一副圖片的二進制值,如果把它定義在源文件中,就會顯得很冗餘,因為並不會經常修改。 這時可以定義在頭文件中,只在一個源文件中引用,當有多幅圖片需要隨時更換時,也可以通過簡單的在源文件中修改引用的頭文件名達到修改的目的。
二、頭文件的引用。
頭文件引用的方法其實之前已經大致說過了,在源文件中引用頭文件和在頭文件中引用的格式是一樣的:
#include<xxx.h>或者
#include "xxx.h"
xxx為頭文件名。
用<>和""是有一定的區別的。在編譯器查找頭文件的時候,會在兩個區域分別查找。
一個是系統頭文件區域,即類似於stdio.h一類的C庫函數頭文件區。
另一個是自定義頭文件區,比如當前目錄,以及其它自定義的目錄。
用<>時,編譯器會先在系統區域查找,然後再查找自定義區域。而用""時則相反。
由於一般並不推薦自定義頭文件名與系統頭文件名相同(容易引起歧義並難以維護),所以先後順序並不是太重要,尤其在硬體速度越來越快的今天,使用哪種符號引用頭文件已經差別很小了。
4. 構造函數何時被調用( ) A、類定義時 B.創建對象時 C.調用對象方法時 D.使用對象的變數時
B.每個實例創建時會被調用
類定義並不涉及創建類,也不需要分配空間,僅定義數據類型, 因此無需調用構造函數
能調用對象方法, 說明類的構建已經完成; 同理使用變數也是.

5. C語言中如何引用其它C源文件中的函數
在源文件A1.c中調用A2.c 中的函數有兩種方法:
1、在A2.c中有完整的函數定義,在A1.c中添加一下要用到的函數原型(聲明)就可以了,例如:
在A2.c中:有函數void A2(){...};。
在A1.c中:在文件前頭增加一行:void A2();就可以了。
2、把A2.c中完整定義的函數的原型,寫到一個A2.h文件中,然後在A1.c的文件頭增加#include "A2.h"就可以了。
以上兩種方法,在A1.c中都可以正常的調用,就跟在A2.c中調用一樣。
其實函數默認是外部的,只要在其他文件中聲明就能使用;但是注意如果在前面加上static,就只能在本文件中使用了,不能再被其他的文件調用。

(5)c創造方法和引用方法擴展閱讀:
1、一個.h文件要 對應有一個.c文件,這樣鏈接器就可以調用這個文件里的函數。比如a.h 和 a.c。
2、把相應的函數定義寫在.c文件中。這里要強調一點:要加上#include ".h",這個一般作為一種工程規范。因為如果.c文件中的函數也需要調用同個.c中的其它函數,那麼這個.c往往會include對應的.h。比如頭文件里進行了變數的聲明,這個時候對應的.c文件是一定要加上這個頭文件的。
3、再在其他的main.c文件開頭添加#include "a.h"。
6. 如何在C/C++中調用Java的方法
JNI允許您從本機代碼內調用 Java 類方法。
要做到這一點,通常必須使用 Invocation API 在本機代碼內創建和回初始化一個 JVM。
下列是答您可能決定從 C/C++ 代碼調用Java 代碼的典型情況:
1.希望實現的這部分代碼是平台無關的,它將用於跨多種平台使用的功能。
2.需要在本機應用程序中訪問用 Java 語言編寫的代碼或代碼庫。
3.希望從本機代碼利用標准 Java 類庫。
從C/C++ 程序調用 Java 代碼的四個步驟:
1.編寫 Java 代碼。
這個步驟包含編寫一個或多個 Java 類,這些類實現(或調用其它方法實現)您想要訪問的功能。
2.編譯 Java 代碼。
在能夠使用這些 Java 類之前,必須成功地將它們編譯成位元組碼。
3.編寫 C/C++ 代碼。
這個代碼將創建和實例化 JVM,並調用正確的 Java 方法。
4.運行本機 C/C++ 應用程序。
將運行應用程序以查看它是否正常工作。我們還將討論一些用於處理常見錯誤的技巧。

7. objective-c 實例方法\類方法如何調用
在書寫了類的聲明和實現後,應用程序如何去調用它呢?
在Objective-c中,調用方法的簡單格式如下:
1[實例 方法]; 如: [person setAge:32]; 其中 person是Person類的實例。
或者是:
2 [類名 方法名]; 如:NSString str = [NSDate date]; 這是直接調用類NSdate中的方法date來得到當前日期和時間。
在Objective-c中,調用一個類或實例的方法,也稱為給這個類或實例發消息(message)。類的實例稱為「接收方」。所以,通用方法調用的格式也可以理解為:
[接收方 消息];
在術語上,整個表達式也叫做消息表達式。這是官方的正式稱呼。
當然,一個方法可能會有參數,也有可能會有多個參數,因此完整的方法調用格式如下:
[接收方法 名子1:參數1 名子2:參數2 名子3:參數 ... ]
如:
[person setAge:32];
[person setName:@"sam" andSecondName:@"job"];
註:在多參數方法調用時,可以省略從第二個開始的方法名子。
如:
[person setName:@"sam" :@"job"];
一個方法中還可以調用另外一個方法調用,如:
[NSString stringWithFormat:[test format]];
註:方法的調用一定要加上中括弧「[........]」
8. 在C語言中,函數實參與形參之間的數據傳遞方式是( )傳遞方式。
函數實參與形參之間的數據傳遞方式是( 值傳遞)傳遞方式,在C語言中,數內據傳遞方式有值容傳遞和引用傳遞,值傳遞:傳值,實際是把實參的值賦值給行參,相當於。
那麼對行參的修改,不會影響實參的值 。引用傳遞: 實際是傳值的一種特殊方式,只是他傳遞的是地址,不是普通的賦值,那麼傳地址以後,實參和行參都指向同一個對象,因此對形參的修改會影響到實參。

傳值調用中,只使用了實參的值。傳值調用機制里,形參是一個局部變數,其初始值為相應實參的值。在引用調用機制里,將實參的地址傳遞給形參,從表面上看是以實參變數取代形參,因此任何發生在形參上的改變實際上都發生在實參變數上。
引用傳遞是將變數的內存地址傳遞給方法,方法操作變數時會找到保存在該地址的變數,對其進行操作。會對原變數造成影響。可以將一個變數通過引用傳遞給函數,這樣該函數就可以修改其參數的值。
9. java A有自己的子類B,C繼承A,也就是A是B和C的父類,C能調用B的方法嗎
多態性是指允許不同類的對象對同一消息作出響應。多態性包括參數化多態性和包含多態性。多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。
多態有兩種表現形式:重載和覆蓋
首先說重載(overload),是發生在同一類中。與什麼父類子類、繼承毫無關系。
標識一個函數除了函數名外,還有函數的參數(個數和類型)。也就是說,一個類中可以有兩個或更多的函數,叫同一個名字而他們的參數不同。
他們之間毫無關系,是不同的函數,只是可能他們的功能類似,所以才命名一樣,增加可讀性,僅此而已!
再說覆蓋(override),是發生在子類中!也就是說必須有繼承的情況下才有覆蓋發生。
我們知道繼承一個類,也就有了父類了全部方法,如果你感到哪個方法不爽,功能要變,那就把那個函數在子類中重新實現一遍。
這樣再調用這個方法的時候,就是執行子類中的過程了。父類中的函數就被覆蓋了。(當然,覆蓋的時候函數名和參數要和父類中完全一樣,不然你的方法對父類中的方法就不起任何作用,因為兩者是兩個函數,毫不關系)
A a=new C();
創建的是父類A的對象,調用的方法是A中的方法
C a=new C()
創建子類C的對象,調用的方法是C中的方法
10. C語言和匯編怎樣引用對方定義的變數
C中要使用匯編裡面函數的話 需要在匯編裡面使用export xxx 導出函數標號 C中加extern xxx匯編要使用C裡面的函數的話 需要在匯編里使用import xxx 導入外部標號