c语言指针灵活性管窥
生活随笔
收集整理的這篇文章主要介紹了
c语言指针灵活性管窥
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近看到mit的[url=http://pdos.csail.mit.edu/6.828/2010/]操作系統課程網站[/url],其[url=http://pdos.csail.mit.edu/6.828/2010/labs/lab1/]實驗一[/url]
中練習四(exercise 4)中有一個關于指針使用的代碼:
#include <stdio.h>
#include <stdlib.h>
void
f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
int
main(int ac, char **av)
{
f();
return 0;
}
其中比較有趣的是 c = (int *) ((char *) c + 1);*c = 500 這兩行程序的執行結果。
在執行這兩行代碼前,數組a中四個元素的值分別為200,400,301,302,而在intel處理器的32位操作系統上執行完這兩行代碼后的值則為200,128144,256,302,即這兩行代碼修改了a[1]和a[2]的值。這是什么原因呢?
200,400,301,302這四個值用十六進制形式表示即為0x000000c8,0x00000190,0x0000012d,0x00000012e。由于intel處理器是little-endian的,即數據的較高位存儲在較低內存的位置。所以數組a中數值在內存中二進制表示形式(用十六進制書寫)則為 c8 00 00 00 90 01 00 00 2d 01 00 00 2e 01 00 00。在執行上面指針c的兩行代碼之前,指針c恰好指向90所在的位置。而c = (int*)((char *) c+1);則將本來為指向四個字節數據的指針強制轉換成指向一個字節數據的指針,這就導致此后的c+1的執行結果是指向0x01這個內容,之后又將c強制轉換成int類型并將其指向的內容賦值為500(0x000001F4)這樣原來的01 00 00 2d就被F4 01 00 00所覆蓋。所以數組a中數值就變為c8 00 00 00 90 f4 01 00 00 01 00 00 2e 01 00 00。即a中四個元素的值分別為200(0x000000c8),128144(0x0001f490),256(0x00000100),302(0x0000012e).
關于指針的更多講解見英文教程: [url=http://pweb.netcom.com/~tjensen/ptr/]http://pweb.netcom.com/~tjensen/ptr/[/url]
中練習四(exercise 4)中有一個關于指針使用的代碼:
#include <stdio.h>
#include <stdlib.h>
void
f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
int
main(int ac, char **av)
{
f();
return 0;
}
其中比較有趣的是 c = (int *) ((char *) c + 1);*c = 500 這兩行程序的執行結果。
在執行這兩行代碼前,數組a中四個元素的值分別為200,400,301,302,而在intel處理器的32位操作系統上執行完這兩行代碼后的值則為200,128144,256,302,即這兩行代碼修改了a[1]和a[2]的值。這是什么原因呢?
200,400,301,302這四個值用十六進制形式表示即為0x000000c8,0x00000190,0x0000012d,0x00000012e。由于intel處理器是little-endian的,即數據的較高位存儲在較低內存的位置。所以數組a中數值在內存中二進制表示形式(用十六進制書寫)則為 c8 00 00 00 90 01 00 00 2d 01 00 00 2e 01 00 00。在執行上面指針c的兩行代碼之前,指針c恰好指向90所在的位置。而c = (int*)((char *) c+1);則將本來為指向四個字節數據的指針強制轉換成指向一個字節數據的指針,這就導致此后的c+1的執行結果是指向0x01這個內容,之后又將c強制轉換成int類型并將其指向的內容賦值為500(0x000001F4)這樣原來的01 00 00 2d就被F4 01 00 00所覆蓋。所以數組a中數值就變為c8 00 00 00 90 f4 01 00 00 01 00 00 2e 01 00 00。即a中四個元素的值分別為200(0x000000c8),128144(0x0001f490),256(0x00000100),302(0x0000012e).
關于指針的更多講解見英文教程: [url=http://pweb.netcom.com/~tjensen/ptr/]http://pweb.netcom.com/~tjensen/ptr/[/url]
總結
以上是生活随笔為你收集整理的c语言指针灵活性管窥的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot工程的热部署
- 下一篇: 第一次使用Sourcetree成功上传g