C語言 指針入門 看這一篇就夠了


C語言 指針入門 看這一篇就夠了

指針的運算 詳解 [C語言必知必會]

指針的運算

指針加減 常量

請看下面的程序,猜測一下結果:

<code>int main() {

int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* a = &arr;

printf("a = %p\\n", a);
printf("a + 1 = %p\\n", a + 1);
printf("a - 1 = %p\\n", a - 1);

}
/<code>

運行結果:

<code>a     = 00AFF82C
a + 1 = 00AFF830
a - 1 = 00AFF828
/<code>

可以看到, a 與 a + 1 和 a - 1 都差了四個字節

指針加減常量 加減的大小為 sizeof(類型) * 常量

再試試 char 類型?

<code>int main() { 


char arr[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10',};
char* a = &arr;

printf("a = %p\\n", a);
printf("a + 1 = %p\\n", a + 1);
printf("a - 1 = %p\\n", a - 1);

}
/<code>

結果如我們所料:

<code>a     = 0095F9E0
a + 1 = 0095F9E1
a - 1 = 0095F9DF
/<code>

相差大小 為 1

指針 - 指針

先來看一段程序吧:

<code>int main() {

char arr1[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10', };
int arr2[5] = { 1, 2, 3, 4, 5 };

char* ch1 = &arr1[4];
char* ch2 = &arr1;
int* i1 = &arr2[4];
int* i2 = &arr2;

printf("ch1 - ch2 = %d\\n", ch1 - ch2);
printf("ch2 - ch1 = %d\\n", ch2 - ch1);
printf("\\ni1 - i2 = %d\\n", i1 - i2);
printf("i2 - i1 = %d\\n", i2 - i1);

}
/<code>

指針相減 結果會是 指針相差的大小嗎?看結果:

<code>ch1 - ch2 = 4
ch2 - ch1 = -4


i1 - i2 = 4
i2 - i1 = -4
/<code>

指針 減 指針 意義是 兩個地址之間相隔的單元格數也可以理解為:指針相差的大小 / sizeof(類型)

如果想輸出兩個指針 相差的距離(大小)只需要將變量類型 更改成普通類型,如下:

<code>int main() {

char arr1[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10', };
int arr2[5] = { 1, 2, 3, 4, 5 };

//變量不再是指針變量
char ch1 = &arr1[4];
char ch2 = &arr1;
int i1 = &arr2[4];
int i2 = &arr2;

printf("ch1 - ch2 = %d\\n", ch1 - ch2);
printf("ch2 - ch1 = %d\\n", ch2 - ch1);
printf("\\n");
printf("i1 - i2 = %d\\n", i1 - i2);
printf("i2 - i1 = %d\\n", i2 - i1);

}
/<code>

輸出結果:

<code>ch1 - ch2 = 4
ch2 - ch1 = -4

i1 - i2 = 16
i2 - i1 = -16
/<code>

普通類型是無法進行解引用操作的

總結一下

指針 可以 加減常數,指針之間可以相減,可以比較(如:> == < >=等)但是指針不能乘除,相加 這是沒有意義的舉個很簡單的例子,時間可以相減,但是時間乘除或者相加有什麼意義呢?

NULL

通過前面的學習,我們知道:內存中的地址有很多編號。如果你的機器是 32 位,那麼內存範圍是:0 ~ 2^32 -1(32位2進制數全1) 最大值大約為 4GBNULL其實就表示 0地址補充個小知識點:1kB=1024B =2^10(次方是二進制形式)1MB=1024kB =2^201GB=1024MB =2^301TB=1024GB =2^40

NULL有什麼用?

0地址規定為我們不能寫入的地址,你的指針不指向 0地址,如果你的指針指向了 0地址 那麼程序運行時會崩潰。基於這個特點,0地址 也就是NULL有了很重要的功能:

  • 函數返回 NULL指示錯誤
  • 防止野指針。用NULL初始化指針,如果指針使用時沒有指向任何實際地址,程序崩潰。

NULL類型時 void * 可以設置任何類型為NULL下面的程序是官網上講NULL時給出的例子:

<code>#include <stdlib.h>
#include <stdio.h>
int main(void)
{
// 能設置任何類型指針為 NULL
int* p = NULL;
struct S* s = NULL;
void(*f)(int, double) = NULL;

// 多數返回指針的函數用空指針指示錯誤
char* ptr = malloc(10);
if (ptr == NULL) printf("Out of memory");
free(ptr);
}
/<stdio.h>/<stdlib.h>/<code>

void*

void* 表示 不知道指向什麼類型的 指針比如:

<code>int i = 1;
int* p = &i;
void* q = (void*)p;
/<code>

這麼寫並沒有改變 p 所指向的變量的類型, 而是可以讓程序用不同的眼光通過 p看它所指的變量。

指針類型的作用

1. 指針的類型決定了指針向前或者向後走一步有多大

2. 指針的類型決定了,對指針解引用的時候有多大的權限(能操作幾個字節)




分享到:


相關文章: