天天看點

詳解C語言中的指針類型

文章目錄

      • 什麼是指針類型
      • 定義帶 * 類型的變量
          • 總結
      • 指針變量的指派
      • 指針變量寬度
      • 指針類型的自加和自減
          • 總結
      • 指針類型的加減運算
          • 總結
      • 指針類型的比較

什麼是指針類型

在C語言中,指針類型就是資料類型,是給編譯器看的,也就是說,指針類型與數組、int、char這種類型是平級的,是同一類的。

詳解C語言中的指針類型

定義帶 * 類型的變量

先看定義的這幾個變量:

double a;
int b;
short c;
char d;
float e;
struct p player;
           

這都是之前我們用到的類型,它們的含義、記憶體的配置設定我們都了解了,這所有的類型,後面都可以跟一個 * ,就像這樣:

double* a;
int* b;
short* c;
char* d;
float* e;
struct* p player;
           
總結
  1. 任何變量都可以帶 * ,加上 * 以後變成新的類型,統稱“指針類型”。
  2. *可以是任意多個。

指針變量的指派

以前我們指派都是直接指派,其實是簡寫的,它的完整形式是這樣:

int x;
x = (int)1;
           

現在我們要給指針類型的變量指派,就可以這麼寫:

int* x;
x = (int*)1;
           

即使是變量與變量至之間指派,隻要類型相同,也是可以的。

指針變量寬度

我們看一下指針變量的寬度是怎麼配置設定的:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char* x;
	short* y;
	int* z;

	x = (char*)1;
	y = (short*)1;
	z = (int*)1;

	system("pause");
	return;
}
           

檢視反彙編可以看到,無論你定義的是什麼樣的指針類型,最終都是4個位元組存儲:

詳解C語言中的指針類型

即使後面有多個 * ,寬度也是4位元組。

指針類型的自加和自減

我們先看一下基本類型的自加:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char a;
	short b;
	int c;
	a = 1;
	b = 2;
	c = 3;
	a++;
	b++;
	c++;
	printf("%d %d %d \n",a,b,c);
	system("pause");
	return;
}
           

運作結果:

詳解C語言中的指針類型

這沒什麼好說的,太正常了,我們看一下指針類型的自加是怎麼樣的:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char* a;
	short* b;
	int* c;
	a = (char*)1;
	b = (short*)1;
	c = (int*)1;
	a++;
	b++;
	c++;
	printf("%d %d %d \n",a,b,c);
	system("pause");
	return;
}
           

運作結果:

詳解C語言中的指針類型

發現不同了吧,指針類型的自加或者自減,處理的是去掉*後的位元組寬度,char是1個位元組,short是2個位元組,int是4個位元組,是以當a,b,c都為1的時候,自加的結果因為資料類型的不同而不同,變成了2,3,5。

但是,這裡我們用的都是一個 * 的指針類型,如果 * 是多個,會是什麼結果呢?

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char** a;
	short** b;
	int** c;
	a = (char**)1;
	b = (short**)1;
	c = (int**)1;
	a++;
	b++;
	c++;
	printf("%d %d %d \n",a,b,c);
	system("pause");
	return;
}
           

運作結果:

詳解C語言中的指針類型

這時候結果又都相同了,都加了4,這是因為一個指針類型在堆棧中占4個位元組,是以隻要兩個*及以上,最終的自加自減結果都是以4來處理的。

總結
  1. 不帶*的類型自加自減以1來處理。
  2. 帶一個*的指針類型自加自減以去掉 * 後的類型寬度來處理。
  3. 兩個*及以上的指針類型自加自減以4來處理。

指針類型的加減運算

其實指針類型的自加與自減我們弄明白了以後,它的加減運算我們就不難了解了,看一下這個例子:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char* a;
	short* b;
	int* c;
	a = (char*)1;
	b = (short*)1;
	c = (int*)1;
	a = a+5;
	b = b+5;
	c = c+5;
	printf("%d %d %d \n",a,b,c);
	system("pause");
	return;
}
           

運作結果:

詳解C語言中的指針類型

先不急着總結,在寫一個多*的看看什麼結果:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char** a;
	short** b;
	int** c;
	a = (char**)1;
	b = (short**)1;
	c = (int**)1;
	a = a+5;
	b = b+5;
	c = c+5;
	printf("%d %d %d \n",a,b,c);
	system("pause");
	return;
}
           

運作一下,發現不同了吧:

詳解C語言中的指針類型
總結
  1. 指針類型可以加減一個整數,但不能乘除。
  2. 指針類型的變量+n=指針類型的變量+n*(去掉一個n後類型的寬度)。
  3. 指針類型的變量-n=指針類型的變量-n*(去掉一個n後類型的寬度)。

指針類型的比較

指針類型也是可以進行比較的:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void main()
{
	char* a;
	char* b;

	a = (char*)200;
	b = (char*)100;
	if(a>b)
	{
		printf("正确!\n");
	}
	else
	{
		printf("錯誤!\n");
	}
	return;
}
           

運作結果:

詳解C語言中的指針類型

看一下反彙編:

詳解C語言中的指針類型

這裡可以看到,比較用的指令是jbe,這個jbe是無符号數比較,也就是說指針類型在比較的時候是不看符号的,即使這裡a等于-200,輸出的結果依然是正确:

詳解C語言中的指針類型

繼續閱讀