進擊的小白——指標與陣列(未完待續)
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 *);