举例说明指针数组、指向指针的指针如何表示?_指针指向字符串

举例说明指针数组、指向指针的指针如何表示?_指针指向字符串C语言数组指针加1的问题目录1. 用C++语言测试2. 用汇编语言测试(MASM环境)指向数组的指针存储的是连续的内存地址,而内存地址的最小编址单位是1字节,如果存储的数据本身移动几个字节

C语言数组指针加1的问题   目录   1. 用C++语言测试   2. 用汇编语言测试(MASM环境)   指向数组的指针存储的是连续的内存地址,而内存地址的最小编址单位是1字节,如果存储的数据本身移动几个字节,则内存地址也相应地移动几个字节。而数组指针的加1移动几个字节,取决于所指向的数组类型,这部分是由C/C++的编译器实现去处理的。下面具几个例子说明(下面的例子在MSVC的X64平台,指针本身占8个字节):   1. 用C++语言测试   (1) 指向1字节的数组指针:   void TestPointerSize()   {   char data[] = {1,2,3,4,5,6,7,8,9,10};   char* ptr = data;   printf(“ptr size=%d,data=%I64d   ”,sizeof(ptr),data);   for(int i=0;i<10;i++)   {   printf(“data[%d]=%d,ptr=%I64d   ”,i,*ptr,ptr);   ptr = ptr + 1;   }   }   输出如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   从图中可以看到,指针本身的大小占8个字节,数组名是数组的首地址,常量指针。但注意,sizeof(data)是计算整个数组的存储大小,而不是首地址的大小。指针每次加1,也是加1字节长度,即1个数组素的大小。   (2) 指向2字节的数组指针:   void TestPointerSize()   {   short data[] = {1,2,3,4,5,6,7,8,9,10};   short* ptr = data;   int n = sizeof(data);   printf(“ptr size=%d,data=%I64d   ”,sizeof(ptr),data);   for(int i=0;i<10;i++)   {   printf(“data[%d]=%d,ptr=%I64d   ”,i,*ptr,ptr);   ptr = ptr + 1;   }   }   输出如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   可以看到,指针每次加1,是加2字节长度,即1个数组素的大小。   (3) 指向4字节的数组指针:   void TestPointerSize()   {   int data[] = {1,2,3,4,5,6,7,8,9,10};   int* ptr = data;   int n = sizeof(data);   printf(“ptr size=%d,data=%I64d   ”,sizeof(ptr),data);   for(int i=0;i<10;i++)   {   printf(“data[%d]=%d,ptr=%I64d   ”,i,*ptr,ptr);   ptr = ptr + 1;   }   }   输出如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   可以看到,指针每次加1,是加4字节长度,即1个数组素的大小。   (4) 指向8字节的数组指针:   void TestPointerSize()   {   __int64 data[] = {1,2,3,4,5,6,7,8,9,10};   __int64* ptr = data;   int n = sizeof(data);   printf(“ptr size=%I64d,data=%I64d   ”,sizeof(ptr),data);   for(int i=0;i<10;i++)   {   printf(“data[%d]=%I64d,ptr=%I64d   ”,i,*ptr,ptr);   ptr = ptr + 1;   }   }   输出如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   可以看到,指针每次加1,是加8字节长度,即1个数组素的大小。   2. 用汇编语言测试(MASM环境)   (1) 指向1字节的数组指针:   汇编声明一个数组:   .const   data_ byte 1,2,3,4,5,6,7,8,9,10   C++下声明一个访问数组素的函数,并用汇编实现   extern “C” int GetArrayItem(int i,char* ptr);   汇编语言实现:   .code   GetArrayItem proc   ; Make sure ‘i’ is valid   cmp ecx,0   jl InvalidIndex ;jump if i < 0   cmp ecx,[NumFibVals_]   jge InvalidIndex ;jump if i >= NumFibVals_   ; Sign extend i for use in address calculations   ;mov rax,offset data_ ;get   lea rbx,data_  ;取得数组的偏移地址,我们可以理解为取得数组的地址,也可换成offset伪指令   xor rax,rax   mov eax,ecx   imul eax,1   ;i的值乘以数据的大小,这里是1字节   movsxd rax,eax  ;符号扩展到64位   add rbx,rax ;得到数组的偏移地址   mov eax,[rbx] ;取得偏移地址指向的内存存储的值   mov [rdx],eax  ;将值复制到外部传入的指针所指示的内存地址   mov eax,1 ;set success return code   ret   InvalidIndex:   xor eax,eax ;set error return code   ret   GetArrayItem endp   end   调用代码:   void TestPointerSize()   {   char* ptr = (char*)malloc(sizeof(char));   for(int i=0;i<10;i++)   {   GetArrayItem(i,ptr);   printf(“data[%d]=%d   ”,i,*ptr);   }   free(ptr);   }   输出结果如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   (2) 指向2字节的数组指针:   汇编声明一个数组:   .const   data_ word 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010   汇编访问代码改一句:   imul rbx,2   ;i的值乘以数据的大小,现在这里是2字节   改调用函数:   extern “C” int GetArrayItem(int i,short* ptr);   调用代码:   void TestPointerSize()   {   short* ptr = (short*)malloc(sizeof(short));   for(int i=0;i<10;i++)   {   GetArrayItem(i,ptr);   printf(“data[%d]=%d   ”,i,*ptr);   }   free(ptr);   }   输出结果如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   (3) 指向4字节的数组指针:   汇编声明一个数组:   .const   data_ dword 3001,3002,3003,3004,3005,3006,3007,3008,3009,3010   汇编访问代码改一句:   imul rbx,4   ;i的值乘以数据的大小,现在这里是4字节   改调用函数:   extern “C” int GetArrayItem(int i,int* ptr);   调用代码:   void TestPointerSize()   {   int* ptr = (int *)malloc(sizeof(int));   for(int i=0;i<10;i++)   {   GetArrayItem(i,ptr);   printf(“data[%d]=%d   ”,i,*ptr);   }   free(ptr);   }   输出结果如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串   (4) 指向8字节的数组指针:   汇编声明一个数组:   .const   data_ qword 8001,8002,8003,8004,8005,8006,8007,8008,8009,8010   汇编访问代码:   GetArrayItem proc   ; Make sure ‘i’ is valid   cmp ecx,0   jl InvalidIndex ;jump if i < 0   cmp ecx,[NumFibVals_]   jge InvalidIndex ;jump if i >= NumFibVals_   ; Sign extend i for use in address calculations   ;mov rax,offset data_ ;get   lea rbx,data_  ;取得数组的偏移地址,我们可以理解为取得数组的地址,也可换成offset伪指令   xor rax,rax   mov eax,ecx   imul eax,8  ;i的值乘以数据的大小,这里是8字节   movsxd rax,eax ;符号扩展到64位   add rbx,rax ;得到数组的偏移地址   mov rax,[rbx] ;取得偏移地址指向的内存存储的值   mov [rdx],rax  ;将值复制到外部传入的指针所指示的内存地址   mov eax,1 ;set success return code   ret   InvalidIndex:   xor eax,eax ;set error return code   ret   GetArrayItem endp   改调用函数:   extern “C” int GetArrayItem(int i,__int64* ptr);   调用代码:   void TestPointerSize()   {   __int64* ptr = (__int64*)malloc(sizeof(__int64));   for(int i=0;i<10;i++)   {   GetArrayItem(i,ptr);   printf(“data[%d]=%d   ”,i,*ptr);   }   free(ptr);   }   输出结果如图:   
举例说明指针数组、指向指针的指针如何表示?_指针指向字符串

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/38168.html

(0)
上一篇 2024年 9月 8日 下午7:56
下一篇 2024年 9月 8日

相关推荐

关注微信