程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 指針和結構類型的關系

指針和結構類型的關系

編輯:C++入門知識

指針和結構類型的關系

  可以聲明一個指向結構類型對象的指針。

  例十一:


struct MyStruct
{
 int a;
 int b;
 int c;
}
MyStruct ss={20,30,40};
//聲明了結構對象ss,並把ss的三個成員初始化為20,30和40。
MyStruct*ptr=&ss;
//聲明了一個指向結構對象ss的指針。它的類型是MyStruct*,它指向的類型是MyStruct。
int*pstr=(int*)&ss;
//聲明了一個指向結構對象ss的指針。但是它的類型和它指向的類型和ptr是不同的。

  請問怎樣通過指針ptr來訪問ss的三個成員變量?

  答案:

ptr->a;
ptr->b;
ptr->c;

  又請問怎樣通過指針pstr來訪問ss的三個成員變量?

  答案:

*pstr;//訪問了ss的成員a。
*(pstr+1);//訪問了ss的成員b。
*(pstr+2)//訪問了ss的成員c。

  雖然我在我的MSVC++6.0上調式過上述代碼,但是要知道,這樣使用pstr來訪問結構成員是不正規的,為了說明為什麼不正規,讓我們看看怎樣通過指針來訪問數組的各個單元:

  例十二:

int array[3]={35,56,37};
int*pa=array;

  通過指針pa訪問數組array的三個單元的方法是:

*pa;//訪問了第0號單元
*(pa+1);//訪問了第1號單元
*(pa+2);//訪問了第2號單元

  從格式上看倒是與通過指針訪問結構成員的不正規方法的格式一樣。

  所有的C/C++編譯器在排列數組的單元時,總是把各個數組單元存放在連續的存儲區裡,單元和單元之間沒有空隙。但在存放結構對象的各個成員時,在某種編譯環境下,可能會需要字對齊或雙字對齊或者是別的什麼對齊,需要在相鄰兩個成員之間加若干個"填充字節",這就導致各個成員之間可能會有若干個字節的空隙。

  所以,在例十一中,即使*pstr訪問到了結構對象ss的第一個成員變量a,也不能保證*(pstr+1)就一定能訪問到結構成員b。因為成員a和成員b之間可能會有若干填充字節,說不定*(pstr+1)就正好訪問到了這些填充字節呢。這也證明了指針的靈活性。要是你的目的就是想看看各個結構成員之間到底有沒有填充字節,嘿,這倒是個不錯的方法。

  通過指針訪問結構成員的正確方法應該是象例十二中使用指針ptr的方法。

  指針和函數的關系

  可以把一個指針聲明成為一個指向函數的指針。


int fun1(char*,int);
int(*pfun1)(char*,int);
pfun1=fun1;
....
....
int a=(*pfun1)("abcdefg",7);//通過函數指針調用函數。 

  可以把指針作為函數的形參。在函數調用語句中,可以用指針表達式來作為實參。

  例十三:


int fun(char*);
int a;
char str[]="abcdefghijklmn";
a=fun(str);
...
...
intfun(char*s)
{
int num=0;
for(int i=0;i{
num+=*s;s++;
}
return num;

  這個例子中的函數fun統計一個字符串中各個字符的ASCII碼值之和。前面說了,數組的名字也是一個指針。在函數調用中,當把str作為實參傳遞給形參s後,實際是把str的值傳遞給了s,s所指向的地址就和str所指向的地址一致,但是str和s各自占用各自的存儲空間。在函數體內對s進行自加1運算,並不意味著同時對str進行了自加1運算。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved