C語言指標——指標的運算,指標運算
說指標之前,先說兩個比較不相關的東西,也當做是一種知識的補充。看下面的代碼:
#include <stdio.h>
int main(void)
{
char *s = "Hello world.";
printf(s);
}
運行這段代碼,會出現錯誤嗎?如果出現錯誤,是什麼錯誤?
分析:printf一種常規的用法就是printf("Please input a data:");這種用法相信很多人都使用過,但是將這種用法分析一下,這樣的用法printf函數接收到的參數是一個常量字串的首地址,然後就可以輸出這個字串,所以上面的代碼也是將字串的首地址(存放於字元型指標s中)傳遞給了printf,所以這段代碼的運行不會出現任何問題,甚至編譯的時候連警告都不會出現。再看下面的一段代碼:
#include <stdio.h>
int main(void)
{
char *s = "Hello world.";
printf(s, 1, 2, 3);
}
請問這段代碼是否正確,如果不正確,錯誤出在哪裡?
分析:要分析這個問題也還是比較容易的,printf函數和scanf函數是C語言中典型的兩個變長參數函數,printf也不知道自己會接收到多少個參數,它唯一知道的就是如果在輸入的字串說明符中有多少個輸出控制符(%d等)就會到後面去解析多少個參數,如果解析不到的話這種情況下才會報錯。但是如果前面並沒有說明需要參數,而後面跟了參數的話,這個它是不會理會的,所以這段代碼編譯和運行都不會出現問題,還是跟上面一樣,編譯的時候甚至警告都不會出現。
現在開始言歸正傳說說指標,這次就簡單的說說指標的加減運算,請看下面一段代碼:
#include <stdio.h>
int main(void)
{
int a[10];
printf("%p %p ", &a[0]+1, &a[1]);
}
請問程式輸出的兩個值一樣嗎?如果不一樣,兩者相差多少?
分析:這個問題需要對指標的運算理解比較深入才能答對,正確的答案是兩者輸出是一樣的,可能很多人碰到這個問題的時候會想,&a[0]之後得到的是第0個單元的地址,這個地址和&a[1]也就是第1個單元的地址應該是相差sizeof(int)個位元組,所以兩者輸出應該相差3。但是這樣的演算法忽略了指標的加減運算規則,指標或者說地址的運算往往依賴於指標或者地址的類型,比如我們常常會用int *p=a; printf("%d ", *p++);這種用法,通過p++就可以指向下一個int類型的單元!這就說明p裡面的值被p++這條語句增加了4,這一層的運算程式員是看不見的,後面實質進行的運算相當於p=p+1*sizeof(int);這裡也是一樣,int型的地址加1,並不是地址值簡單的加1,而是加了sizeof(int)個1,所以兩者輸出是一樣的。這個問題可以定義一個字元型的變數s,然後定義一個int類型的指標p,使用p=&s來給p賦值,這個時候編譯器會給出諸如:不能用char *賦值給int *指標的錯誤或者警告,這個也證明對某種類型的變數進行取地址操作,得到的資料類型是該資料類型指標。再看一個更極端的例子:
#include <stdio.h>
int main(void)
{
printf("%d ", (int *)0x04-(int *)0x00);
}
這個程式的輸出是多少呢?
程式運行之後輸出了1,這個當然是在32位機上啟動並執行結果,這個例子可以有助於理解上面的分析過程。
有關C語言指向指標的指標
指標變數能指向任意一個變數(包括指標變數)
指向指標的指標定義方法 ,例如int **p; 定義了一個指標變數p,他指向另一個指標變數(該指標變數又指向一個整型變數),是一個2級指標,由於指標運算子*是按自右向左順序結合,因此上述定義相當於:int *(*p); (*p)是指標變數形式,它外面的*表示p指向的又是一個指標變數,int表示後一個指標變數指向的是指標變數
怎樣使一個指標變數指向另一個指標變數呢?
int **p1;
int *p2;
int i=3;
p2=&i; (使p2指向i)
p1=&p2; (使p1指向p2)
C語言指標數組FOR運算
樓主,這個問題如果要用指標的話,應該使用數組指標,不是指標數組哇,寫法如下。
main()
{
int a[50],*p;
float avg=0.0;
p=a;
for(i=0;i<50 && *p>0;i++,p++) \\輸入負數則停止輸入;
{
scanf("%d",p);
avg=avg+*p;
}
avg=(avg-*p)/i;
printf("%f",avg); \\輸出平均值;
}