12、黑馬程序員-C語言指針

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------


一、什麼是指針?
指針是用來存放變量地址的。通過指針可以間接操縱變量。

二、指針的定義
變量類型 *變量名;
如:int *p;定義了一個int類型的指針p。
注意:任何類型的指針都佔據8個字節的存儲空間

三、指針的初始化
1、先定義,後初始化
int a = 10; // 定義變量a
intint *p;     // 定義int型指針p
p = &a;     // 給指針p賦值,存放的是變量a的存儲地址

2、定義的同時初始化
int a = 10;      // 定義變量a
intint *p = &a;     // 定義int型指針p,同時給指針p賦值,存放的是變量a的存儲地址

四、指針的使用

1、取出指向變量的值
int a = 10;
intint *p = &a;
int value = *p;   // 訪問指針p所指向的變量a的值,並賦值個value,value = 10;

2、給指針指向的變量賦值
int a = 10;
intint *p = &a;
*p = 20;         // 指針p所指向的變量的值被改成20,也就是a的值被改成20

* 的含義:
int *p = &a 中的 * 用來說明 p 是一個指針類型的變量,和變量類型是一個整體。
*p 中得 * 用來訪問 p 所指向的變量a

3、使用注意
在指針指向變量之前,不要對其所指的內容賦值。因爲此時指針指向的地址不確定。如下是錯誤的:
intint *p;
*p = 10;

4、輸入a和b兩個整數,按先大後小的順序輸出a和b。
void main()
{
    int *p1,*p2,*p,a,b;
    scanf("%d,%d",&a,&b);
    p1=&a;p2=&b;
    if(a<b)
    {
        p=p1;
        p1=p2;
        p2=p;
    }
    printf("\na=%d,b=%d\n",a,b);
    printf("max=%d,min=%d\n",*p1, *p2);
}

五、指針與數組

1、數組名就是數組的地址,也是數組首元素的地址,既然是地址,也就可以賦值給指針變量。

int values[5] = {10, 9, 8, 67, 56};
intint *p = values;
intint *p2 = &values[0];

printf("%p\n", p);
printf("%p\n", p2);

輸出:

0x7fff549f2c60
0x7fff549f2c60

2、利用指針來訪問數組元素
int values[5] = {10, 9, 8, 67, 56};
intint *p = values;
// 數組方式
for (int i = 0; i < sizeof(values) / sizeof(int); i++) {
    printf("values[%d] = %d\t", i, values[i]);
}
printf("\n");

// 數組訪問方式1
for (int i = 0; i < sizeof(values) / sizeof(int); i++) {
    printf("values[%d] = %d\t", i, p[i]);
}
printf("\n");
// 數組訪問方式2
for (int i = 0; i < sizeof(values) / sizeof(int); i++) {
    printf("values[%d] = %d\t", i, *(p + i));
}

輸出:

values[0] = 10values[1] = 9values[2] = 8values[3] = 67values[4] = 56

values[0] = 10values[1] = 9values[2] = 8values[3] = 67values[4] = 56

values[0] = 10values[1] = 9values[2] = 8values[3] = 67values[4] = 56
注意:
*(p + 1);表示把指針指向的地址移到下一個該變量類型的地址

同理,*(p + i);表示在p指向的地址的基礎上,把指針指向的地址移到第 i 個該變量類型的地址

3、數組作爲參數傳遞給函數的本質是把數組的地址傳遞給函數。
void test(int v[])
{
    printf("大小:%lu\n", sizeof(v));
    printf("地址:%p\n", v);
}
int main()
{
    int values[5] = {10, 9, 8, 67, 56};
    printf("大小:%lu\n", sizeof(values));
    printf("地址:%p\n", values);
    
    test(values);
    return 0;
}

輸出:
大小:20
地址:0x7fff55dc6c60

大小:8
地址:0x7fff55dc6c60

六、指針與字符串

1、指針字符串的基本

字符串的本質是字符數組,所以字符串的名字也就是第一個字符的地址,也是字符串的地址。
之前定義字符串的方式是:
char name[] = "itcast";

有了指針後,可以:
char *name = "itcast";

區別:

字符數組方式:
* 特點:字符串裏面的字符是可以修改的
* 使用場合:字符串的內容需要經常修改

指針方式:
* 特點:字符串其實是一個常量字符串,裏面的字符是不能修改
* 使用場合:字符串的內容不需要修改,而且這個字符串經常使用

2、指針字符串的使用
在輸入的字符串中查找有無‘k’字符。
void main()
{
    char st[20],*ps;
    int i;
    printf("input a string:\n");
    ps=st;
    scanf("%s",ps);
    for(i=0;ps[i]!='\0';i++)
        if(ps[i]=='k')
        {
            printf("there is a 'k' in the string\n");
            break;
        }
    if(ps[i]=='\0') printf("There is no 'k' in the string\n");
}

七、清空指針

假設p是任意的指針。清空指針的值方式如下:
p = 0;
p = NULL;

八、爲什麼int類型的指針只能指向int類型的變量

先看下面的程序:
int i = 2;
char c = 1;
// int類型的指針指向char類型的變量
intint *p = &c;
printf("%d", *p);

輸出結果:
513

內存分析:

由於p是int類型的指針,指向的地址是 ffc1,於是就從 ffc1 取出四個字節的內容來:0000 0000 0000 0000 0000 0010 0000 0001,換算成十進制就是513,這就是int類型的指針爲什麼不能指向char類型的變量的原因。
總結:同種類型的指針只能指向同種類型的變量

九、函數和指針

1、返回指針的函數
數據類型 *函數名(參數列表)
{
    // ...
}
如:
charchar *pChar()
{
    return "hello";
}

2、指向函數的指針
數據類型 (*pointName)(參數列表);
如:
void test()
{
    printf("調用了test函數\n");
}

int sum(int a, int b)
{
    return a + b;
}
int main()
{
    int (*p)(int, int); // 定義
    p = sum;            // 初始化
    int c = p(10, 11);  // 調用函數,相當於sum(10, 11);
    printf("c is %d\n", c);
    
    void (*p2)() = test; // 定義的同時初始化
    p2();               // 調用函數
    
    return 0;
}

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章