C/C++第三課~指針2、函數(shù)

指針、函數(shù)

1、const (相當(dāng)于java 的 final )

注意:const 放到誰的前面,誰不可改變。所以,<一般const的語法需要從右往左看,const修飾誰,誰就不可變>

const char *p;  // 修飾的是 char 。所以 p 的內(nèi)容不可以修改,但是可以把p指向一個(gè)新的 char 的內(nèi)容地址
char const *p1; // 跟上面的 沒有 區(qū)別。因?yàn)閏onst 不可以修飾 * 符號,只能修飾char
char * const p2;  // p2不可以改變,但是p2是一個(gè)指針,所以p2對應(yīng)的地址中的 內(nèi)容可以改變
const char * const p3; // p3的地址不可以改變,p3 的地址中的 char 內(nèi)容也不可以改變

2、多級指針

指向指針的指針
一個(gè)指針包含一個(gè)變量的地址。當(dāng)我們定義一個(gè)指向指針的指針時(shí),第一個(gè)指針包含了第二個(gè)指針的地址,第二個(gè)指針指向包含實(shí)際值的位置。
**存放的是其他指針的地址,所以下面代碼中 i 的地址和 j 的內(nèi)容是一樣的 **

    int a = 10;
    int *i = &a;
    int **j = &i;
    // 解引用
    printf("i的地址是 %#x, j中存放的地址是 %#x\n", i, *j);
    printf("j的地址是 %#x\n", j);
    printf("j 解引用 數(shù)據(jù)是 %d\n", **j);
結(jié)果:
i的地址是 0xe129a528, j中存放的地址是 0xe129a528
j的地址是 0xe129a520
j 解引用 數(shù)據(jù)是 10

3、函數(shù)

函數(shù)參數(shù)

傳值調(diào)用
    把參數(shù)的值 **復(fù)制** 給函數(shù)的形式參數(shù)。修改形參不會影響實(shí)參
引用調(diào)用
    如果形參為指向 **實(shí)參地址的指針** ,可以通過指針修改 實(shí)參。
    所以參數(shù)為指針的原因就是 為了 可以 修改 實(shí)參。不然得通過返回值,再次賦值給實(shí)參。

C 函數(shù)參數(shù) ~ 與 java 的區(qū)別

public void addition_isCorrect() {
        int a = 10;
        String str = "abcde";
        Bean bean = new Bean();
        change(a, str, bean);
        System.out.println(str + "  " + a + "  " + bean);
    }
    public void change(int a, String str, Bean bean) {
        a = 12;
        str = "1344";
        bean.age = 123;
        bean.name = "345678";
    }
    class Bean{
        int age = 100;
        String name = "majie";
        @Override
        public String toString() {
            return "Bean{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    結(jié)果: abcde  10  Bean{age=123, name='345678'}
    int 和 String 沒有修改(傳值調(diào)用), Bean 類卻修改了其 屬性的值(類似引用調(diào)用)。

上面是java 的參數(shù)相關(guān)的代碼,下面是c的

void add(int a, int *b) {
    printf("a 的值是 %d, b 的值是一個(gè)地址 %#x \n", a, b);
    *b = a + *b;
    printf("和值是 %d \n", *b);
}

void change(int **b) {
    int ad = 1001;
    // 因?yàn)閎是指針的指針,所以*b中是地址
    *b = &ad;
// **b 表示的就是 對應(yīng)的地址中的數(shù)據(jù)
    **b = ad;
}

int main(){
    int c = 12;
    int *f = &c;
    printf("c 的值是 %d, f 的值是一個(gè)地址 %#x \n", c, f);
    printf("add 調(diào)用之前 *f 是 %d \n", *f);
    add(c, f);
    printf("當(dāng)前的c是 %d, 當(dāng)前的 *f 是 %d \n", c, *f);

    // 多級指針的意義 此時(shí) *f 的內(nèi)容是 24, 將 f 這個(gè)變量的地址,傳遞給 change 函數(shù)
    change(&f);
    printf("當(dāng)前的 *f 是 %d \n", *f);
    return 0;
}
結(jié)果:
c 的值是 12, f 的值是一個(gè)地址 0xe0c23528 
add 調(diào)用之前 *f 是 12 
a 的值是 12, b 的值是一個(gè)地址 0xe0c23528 
// add 方法中 f 和 b 是同一個(gè)地址,同時(shí)在add 方法中修改了 (*f) 的值
和值是 24 
當(dāng)前的c是 24, 當(dāng)前的 *f 是 24 
// 在change 方法中再次傳入 指針 f 的地址,同時(shí)修改了 指針f  <指向的地址>,所以變成了 1001
當(dāng)前的 *f 是 1001 

c中也有可變參數(shù),使用的是 ... 需要引入 #include<stdarg.h>

4、函數(shù)指針 ~ 指向函數(shù)的指針變量

C中可以接收一個(gè)函數(shù)作為參數(shù)

/**
 *  void (*p)(char *) 表示這個(gè)參數(shù)是一個(gè)函數(shù)
 *  void 表示 返回值
 *  char* 表示參數(shù)
 *  p 變量表示這個(gè)函數(shù)
 *  (*p) 表示 指向這個(gè)函數(shù)的 指針
*/
void say(void (*p)(char*), char *msg) {
    p(msg);
}

void dayin(char *msg) {
    printf("%s\n", msg);
}

int main()
{
    // 聲明一個(gè)函數(shù)指針的變量,他指向了一個(gè)函數(shù) (這個(gè)變量的定義類別要跟這個(gè)函數(shù)一致)
    void (*functionP)(char*) = dayin;
    say(functionP, "niubi");
    retutrn 0;
}

//typedef 創(chuàng)建別名 由編譯器執(zhí)行解釋
typedef void(*Callback)(int);
typedef long long int64_t; int64_t 就可以作為一個(gè) 類或者屬性來使用。 相當(dāng)于 long long 了

int number(int num) {
    num = 1001 + num;
    return num;
}

// 有點(diǎn)類似于 java 的回調(diào)或者接口
typedef int(*Callback)(int);   // 此時(shí)Callback 就是一個(gè)別名,像類一樣,

int main() {
    Callback call = number;
    printf("num=%d\n", call(3));
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容