1. 程式人生 > >進擊的小白——指標與陣列(未完待續)

進擊的小白——指標與陣列(未完待續)

1.

int *p = NULL;

這句程式碼的意思是,定義一個指向int型的指標變數p,並將p的值(地址)初始化為0x00000000,而不是把*p的值(地址指向的值)置為0x00000000。等價於:

int *p;
p = NULL;

2.

int *p;
*p = NULL;

與1對比,這句程式碼的意思是,把*p的值(地址指向的值)置為0x00000000,即p指向0x00000000。這種寫法p本身的值不知道,也就是p本身儲存的可能是非法地址,用以下方法來改寫:

int i = 10;
int *p = &i;
*p = NULL;

這是將i的地址賦給指標變數p,並讓p指向0x00000000。

3.

int *p = (int *)0x12ff7c;
*p = 0x100;

電腦中有的記憶體是沒有許可權訪問的,得到一個可以訪問的地址的方法是“int i = 0;”,然後檢視i的地址,肯定是可以訪問的。
這句程式碼的意思是,將地址0x12ff7c賦給指標變數p(必須進行強制型別轉換),p指向0xff00。
這句程式碼還可以寫成:

*(int *)0x12ff7c = 0x100;

4.

char *p = "abcdef";
char a[] = "123456";
char m, n;
m = *(p + 4);
n = a[4];

這段程式碼,第一行表示定義一個指向一塊記憶體的指標變數p,這塊記憶體儲存的是7個字元;第二行表示定義一個字串;第四、五行分別表示指標形式、下標式訪問指標或陣列。

5.

int a[5];
int *p, *q, *r;
int m, n, l, k;

p = a + 1;
q = &a[0] + 1;
r = &a + 1;

m = sizeof(a);
n = sizeof(a[5]);
l = sizeof(&a);
k = sizeof(&a[0]);


a不能做左值,作為右值時表示陣列首元素的首地址,而不是陣列首地址;
&a[0]表示陣列首元素的首地址;
&a表示陣列首地址。
因此a和&a[0]表示的含義相同,都是陣列首元素的首地址。


m = sizeof(a)的值為sizeof(int)*5,32位系統下為20;
n = sizeof(a[5])的值為sizeof(int),32位系統下為4,這裡代表陣列中單個元素的大小,是因為sizeof為關鍵字,不是函式,在編譯過程中並沒有真正去訪問a[5],因此雖然a[5]不存在,但也沒有報錯;
l = sizeof(&a)的值為一個指標變數的大小,32位系統下為4;
k = sizeof(&a[0])的值為一個指標變數的大小,32位系統下為4。


p = a + 1表示a向右偏移1個sizeof(a[0]),這裡移動的是1個sizeof(a[0])而不是1個sizeof(a),是因為a作為右值時表示的是陣列首元素的首地址;
q = &a[0] + 1表示a向右偏移1個sizeof(a[0]);
r = &a + 1表示a向右偏移1個sizeof[a]。

6.函式指標

int Func(int x);
int (*p)(int x);
p = &Func;

①第一句程式碼,聲明瞭一個函式。
②第二句程式碼,定義了一個指向函式的指標變數p(函式指標),首先它是一個指標變數,所以要有一個“*”,即(*p);其次前面的 int 表示這個指標變數可以指向返回值型別為 int 型的函式;後面括號中的 int 表示這個指標變數可以指向一個引數為int型的函式。
③第三句程式碼,將Func的首地址賦給指標變數p,其中函式名與陣列名類似,表示函式的首地址。

函式指標的定義方式:

函式返回值型別  (* 指標變數名) (函式引數列表);

函式指標的定義就是將“函式宣告”中的“函式名”改成“(*指標變數名)”;但是這裡需要注意的是:“(*指標變數名)”兩端的括號不能省略,括號改變了運算子的優先順序。如果省略了括號,就不是定義函式指標而是一個函式聲明瞭,即聲明瞭一個返回值型別為指標型的函式。

舉個例子:

#include <stdio.h>
int Max(int, int);  //函式宣告
int main(void)
{
	int (*p)(int, int);  //定義一個函式指標
	int a, b, c;
	p = Max;  //把函式Max賦給指標變數p, 使p指向Max函式
	printf("please enter a and b:");
	scanf("%d%d", &a, &b);
	c = (*p)(a, b);  //通過函式指標呼叫Max函式
	printf("a = %d\nb = %d\nmax = %d\n", a, b, c);
	return 0;
}
int Max(int x, int y)  //定義Max函式
{
	int z;
	if (x > y)
	{
		z = x;
	}
	else
	{
		z = y;
	}
	return z;
}

7.指標函式

int *F(int a);
int *F(int a)
{
	int b[2];
	b[0] = a;
	b[1] = a;
	return b;
}

指標函式,指的是返回值為指標的函式,可以用指標函式來返回一個數組地址。
應與函式指標做區別

8.字串賦值(未完待續)

	char a[10] = "OK!";
	char b[10];
	char *c;
	b[10] = a[10];
	*b = a;
	c = a;

a、b為字串,c為指向char型的指標,在除錯過程中可以發現
①b[10] = a[10]企圖實現將字串a賦值給b,但失敗了(為什麼,待解釋)
②*b = a也企圖實現將字串a賦值給b,也失敗了(為什麼,待解釋)
③c = a成功的將字串a賦值給了c指向char型記憶體。

待解釋:

int *p, q;
sizeof(void *);