8.指針和(數組、函數)

【指針和數組】
      指針和一維數組
               數組名
               int a[5];//a是數組名,5是數組元素的個數,元素就是變量

               int a[3][4];//3行4列,a[0][0]是第一個元素,a[i][j]實際表示第i+1行第j+1列,即4行5列

               如果是實際的二維數組賦值,例如:a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}

               而在這個數組中第十二個數字23的真實位置如果按以下方式來排列:

               a[0][0]、a[0][1]、a[0][2]、a[0][3]

               a[1][0]、a[1][1]、a[1][2]、a[1][3]

               a[2][0]、a[2][1]、a[2][2]、a[2][3]

               則是a[3-1][4-1] == a[2][3]  也就是在第二行第三列,注意不要弄混淆了。

               int b[5];
               a = b; //erroe 因爲a是常量
               printf("%#x",&a[0]); 以16進制輸出第一個元素a[0]的地址
               printf("%#x",a);和printf("%#x",&a[0]);輸出的結果是一樣的,都爲0X12FF6C
-----------------------------------------------------------------------
一維數組名是個指針常量,它存放的是一維數組第一個元素的地址
------------------------------------------------------------------------------------------
下標和指針的關係:
       如果p是個指針變量,則
       p[i]永遠等價於*(p+i)
             [確定一個一維數組需要幾個參數]
             [如果一個函數要處理一個一維數組,則需要接受該數組的哪些信息]
如下面的例子所示:需要兩個參數:
             數組的第一個元素的地址
             數組的長度
--------------------------------------------------------------------
				#include <stdio.h>
				//f函數可以輸出任何一個一維數組的內容
				void f(int *pArr, int len)    //這裏的len表示數組的長度 
				{
					int i;
					for (i=0;i<len,++i)        //*pArr = *(pArr+i)
						printf("%d",*(pArr+i));  // *pArr *(pArr+1) *(pArr+2) *(pArr+3)
					printf("\n");
				}
				int main(void)
				{
					int a[5] = {1,2,3,4,5};
					int b[6] = {-1,-2,-3,4,5,-6}
					int c[100] = {1,99,22,33};

					f(a,5);   //a是int *   且 a 等同於 &a[0]
					f(b,6);
					f(c,100);
					
					return 0;
				}
				---------------------------------------------
				#include <stdio.h>
				void f(int * pArr, int len)
				{
					pArr[3] = 88;   //pArr[3]等價於*(pArr+3)
				}
				int main(void)
				{
					int a[6] = {1,2,3,4,5,6};
					printf("%d\n",a[3]);   //輸出的結果是4
					f(a,6);
					printf("%d\n",a[3]);   //輸出的結果是88
					return 0;      
				}

註釋:

         *pArr = *(pArr+i)         

         *pArr *(pArr+1) *(pArr+2) *(pArr+3)

         因爲f(a,6);中a指向的是a[0],值爲1,那麼傳遞給pArr以後,pArr也是指向的a[0],值也爲1
         又因爲p[i]永遠等價於*(p+i)即pArr[3]等價於*(pArr+3)即*(0+3)所以pArr[3]就相當於指向a[3]
         而pArr[3] = 88;就等於是給a[3]進行了重新賦值88,所以最後a[3]的值爲88

         pArr[3] = 88;和printf("%d\n",a[3]);中的pArr[3]和a[3]是同一個變量
				------------------------------------------------------------------------------------------	
				#include <stdio.h>
				void f(int * pArr, int len)
				{
					pArr[2] = 10;          //pArr[2] == *(a+2) == a[2]
				}
				int main(void)
				{
					int a[5] = {1,2,3,4,5}

					printf("%d\n",a[2]);
					f(a,5);
					printf("%d\n",a[2]);
				//	a = &a[2];     //error 因爲a是常量
				//	printf("%#X, %#X\n",a,&a[0]);
				//	a == &a[0]
					return 0;
				}
				------輸出結果爲2和10-------------------------------------------
指針變量的運算
        指針變量不能相加 不能相乘 也不能相除 只能相減
        如果兩個指針變量指向的是同一塊連續空間中的不同存儲單元
        則這兩個指針變量纔可以相減
					------------------------------------
					#include <stdio.h>
					int main(void)
					{
						int i = 5;
						int j = 10;
						int * p = &i;
						int * q = &j;
						int a[5];
						p = &a[1];
						q = &a[4];
						printf("p和q所指向的單元相隔%d個單元\n",p-q);   //並沒有實際的意義
						return 0;
					}
					------輸出結果爲:p和q所指向的單元相隔3個單元--------------------------
一個指針變量到底佔用幾個字節
    預備知識:
            sizeof(數據類型)
                 功能:返回值就是該數據類型所佔的字節數
                 例子:sizeof(int) = 4 sizeof(char) = 1 sizeof(double) = 8

    sizeof(變量名)
            功能:返回值是該變量所佔字節數

            假設p指向char類型變量(1個字節)
            假設p指向int類型變量(4個字節)
            假設p指向double類型變量(8個字節)
            p q r本身所佔的字節數是一樣的

總結:
         一個指針變量,無論它指向的變量佔幾個字節,該指針變量本身只佔4個字節
         一個變量的地址使用該變量首字節的地址來表示
					-------------------------------------------------------------------------
					#include <stdio.h>
					int main(void)
					{
						char ch = 'A';
						int i = 99;
						double x = 66.6;
						char * p = &ch;
						int * q = &i;
						double * r = &x;
						printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r));
						return 0;
					}
					------輸出結果爲:4 4 4---------------------------------------
詳解:
         硬件內存爲一個單元是一個字節,一個字節是8bit,而又一個字節是一個地址編號
         而x理論佔8個字節,即x有8個地址編號,那麼取x地址的時候到底是取的8個字節中即8個編號中哪一個來
         作爲x的編號呢?而最終規定使用 第一個字節的地址當做x的地址編號
          而最終無論是保留首地址還是末地址作爲x的地址編號,他們都佔4個字節即4*8=32bit,32也是cpu的線程總線數
        【2的32次方=4G RAM】 cpu的2的32次方個狀態,所以對應地址編號都按照32bit來進行存儲,所以無論是哪個編號
         它最終都只佔4個字節。所以輸出的結果爲4 4 4

【指針和函數】

			----------------------------
			#include <stdio.h>
			void g(int **q)        
			{
        		**q = 20;     //*q 就是p
			}
			int main(void)
			{
        		int i=1;
        		int *p=&i;
        		g(&p);         //p是int*類型,&p是int**類型
        		printf("i = %d\n",i);
        		return 0;
			}
			程序的運行結果是:i = 20
			---------------------------------------------------

【多級指針】

			-------------------------
			#include <stdio.h>
			int main(void)
			{
				int i = 10;
				int *p = &i;
				int **q = &p;
				int ***r = &q;
				//r=&p; error,因爲r是int***類型,r只能存放int**類型變量
				printf("i = %d\n",***r);
				return 0;	
			}
			程序運行結果爲i=10

			----------------------------------------------------------------------------------------
                                        解析:
                                               int i = 10 = *P = *(int i) = *q = *[*(int i)] = *r = *{*[*(int i)]}
                                               所以最終 ***r = i;



發佈了113 篇原創文章 · 獲贊 119 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章