講到指針和數組,先給大家看一道例題:
題目:填空練習(指向指針的指針)
1.程序分析:
2.程序源代碼:
main()
{ char *s[]={"man","woman","girl","boy","sister"};
char **q;
int k;
for(k=0;k<5;k++)
{ ;/*這裡填寫什麼語句*/
printf("%s\n",*q);
}
}
指向指針的指針是什麼呢?我們把一個指向指針變量的指針變量,成為多級指針變量,char **p;這種。
我們再看這道題 char *s[]={"man","woman","girl","boy","sister"};這時一個字符串數組,為什麼存放字符串的數組要定義成指針數組呢?我們先來看看指針數組是什麼
指針數組的實質還是數組,是存放指針的數組int *p[] ,(int *)p[]是數組指針,指向數組地址的指針,這兩個概念好像很繞是吧,很難分辨,在這裡,博主將自己記憶的方法告訴大家,int *p[] 大家可以根據運算符優先級來記憶,[]的優先級 > *的優先級,所以這首先是個數組,然後才是指針,所以是指針數組;(int *)p[],()和[]優先級相等,但()是左結合,所以(int *)p[]先是指針,後是數組,所以這是個數組指針。
回到這一題,看這一句printf("%s\n",*q);我們知道%s後面跟的應該是一個地址,而*p是p中所指的數據,所以p地址中保存的還是一個地址,這就是多級指針,而我們用char **q;我們只知道q所指向的首地址,後面的數據如何分配,我們不得而知,所以這道題應該怎麼做呢?
大家看看我們添加的內容:
[cpp] view
plain copy
#include <stdio.h>
int main()
{
char *s[]={"man","woman","girl","boy","sister"};
char **q;
int k;
for(k = 0;k < 5;k++)
{
q = &s[k];
printf("%s\n",*q);
}
}
大家看輸出結果:
[cpp] view
plain copy
fs@ubuntu:~/qiang/shuzu$ gcc -o shuzu5 shuzu5.c
fs@ubuntu:~/qiang/shuzu$ ./shuzu5
man
woman
girl
boy
sister
fs@ubuntu:~/qiang/shuzu$
為什麼我們給的是p = &s[k]而不是*p = &s[k]呢?這裡我們應該先理解二維數組
提到二維數組,我們又不得不提一維數組,一維數組 int a
這裡int是我們數據元素的數據類型,a是什麼,a是數組名,代表數組的首地址,是數組第一個元素的地址,也就是可以說,a是int a
的地址,a[0]也是;
這裡記住a是地址常量,是常量!常量!常量!重要的事說三遍!常量的特性是什麼,不能對其賦值,大家記住這一點!"[]"是變址運算符,所以*(a+i)和a[i]無條件等價!
n是數據的偏移量,是數據的偏移量,而不是字節的偏移量!這點和指針的*p++一樣,是數據的偏移量,因為我們數組裡放的是整型數據,也可能是字符型數據,所占字節大小是不一樣的,所以是數據的偏移量!
我們回到二維數組 以int [3][4]為例,如下圖
我們知道a[3]中a是地址,a[3][4]呢?a這裡也是地址,存放的是什麼數據呢?看圖就知道,存放的是a[0] a[1] a[3],而a[0] a[1] a[2]是什麼呢?其實是地址,地址裡指向的分別是a[0][0] a[1][0] a[2][0]的數據,那我們是不是也可以將二維數據當成一個二級指針來看呢?大家思考一下。
博主思考了一下,說a裡面存放的是a[0] a[1] a[2]的地址不太確切 ,但a[0] a[1] a[2]在這裡確實是地址 ,上面說到二維數組是否可以看成二級指針,當然不能這樣看,大家應該知道,a確實是代表地址,但它與指針有什麼區別呢?大家看a[1] 的地址如何表示呢?是a+1,指針怎麼表示呢?是p+1,好像是一樣哦,但大家應該明白這裡
a 是常量 ,p是變量,a + 1 中 a 的值沒有發生變化,數組裡面所有數據的地址都是由唯一的常量 a 來確定的! 而p + 1,
p 的值已經發生了變化,因為 p 是變量!!!!!
我們再看看char *s[]={"man","woman","girl","boy","sister"},為什麼要加*呢?因為存放的是字符串啊。字符串用地址來表示的啊!所以二級指針 二維數組 指針數組 這幾個概念有時很容易把人搞暈,大家一定要注意分辨!
今天先寫到這,後面會指針數組的深入內容!