!!‧✧̣̥̇‧✦‧✧̣̥̇‧✦ ‧✧̣̥̇:Solitary-walk
⸝⋆ ━━━┓
- 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━ ➴ ⷯ本人座右铭 : 欲达高峰,必忍其痛;欲戴王冠,必承其重。
自
信
希望在看完我的此篇博客后可以对你有帮助哟此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
接下来可是满满的干货,咱也就是说,没点底子咱还真拿捏不了
草图如下:
分析如下:
int a[4] = { 1, 2, 3, 4 };//在VS环境下,采用小端存储,
int* ptr1 = (int*)(&a + 1);// 分析同第6行代码分析
int* ptr2 = (int*)((int)a + 1);//对于这个我们需要知道数据是如何在内存中存储的,注意a这里是首元素的地址,(int)a强转成int 类型数据(int)a+1此时向后移动一个字节
printf("%x %x", ptr1[-1], *ptr2);// %x是以16进制打印,补充 :%d 是10进制打印 %o是以8进制
return 0;
&a+1 :跳过整个数组的地址,此时对应指针类型int *[5] 即数组指针,(int*)(&a + 1)表示强转成int*类型指针
ptr1[-1] 等价于 *(ptr - 1),访问的是元素4
数组a在内存中的存储如下:
int* ptr2 = (int*)((int)a + 1);
因为此时ptr2指针类型是int*,所以解引用访问4个字节,即 00 00 00 02
又因为VS是小端存储
所以以16进制打印出来的是
20000000
{
int a[3][2] = { (0,1), (2,3), (4,5) };
//注意这里是圆括号而不是花括号,圆括号里面是逗号表达式
int* p;
p = a[0]; //指向第一行元素的位置
printf("%d", p[0]);// 1 访问的是第一行第一个位置
return 0;
}
草图如下:
int main()
{
int a[5][5];//二维数组,a对应的类型 int(*)[5]
int(*p)[4];//数组指针,指向数组元素个数为4
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
// p[4] = *(p+4) 跳过4个int(*)[4]的数组 a[4] = *(a+4):跳过4个int (*)[5]的数组
return 0;
return 0;
}
分析如下:
首先我们要知道几个点:
二维数组我们可以把他看成一维数组的数组
对于指针加整数,跳过几个元素,取决于指针类型,以及是指向数组还是指向元素
对于数组a而言,对应类型int(*)[5]
a+1 跳过1个类型为int(*)[5]的数组
对于p而言,对应类型int(*)[4]
p+1 跳过1个类型为int(*)[4]的数组
指针相减(大减小)得到的是元素个数
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1); // &aa+1跳过整个数组
int* ptr2 = (int*)(*(aa + 1));// aa类型int(*)[5] 此时跳过一维数组
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));// 10 5
return 0;
}
分析如下:
char* a[] = { "work","at","alibaba" };// 这是一个字符指针数组,数组内容是字符串,字符串传递的是第一个字符的地址
char** pa = a;//数组名表示数组首元素地址,pa此时指向第一个字符串的起始位置
pa++;//因为pa所对应的指针类型是char**,此时pa++跳过一个元素,即指向第二个字符串的起始位置
printf("%s\n", *pa);// at %s是以字符串的形式打印所以遇到\0即结束打印
解析如下:
首先我们要知道以下几点:
1)这是一个字符指针数组,它的每一个元素是字符串
2)数组名的含义(包括2种特殊情况)
3)指针加整数跳过几个元素
char** pa = a;
//数组名表示数组首元素地址,pa此时指向第一个字符串的起始位置
pa++;//因为pa所对应的指针类型是char**,此时pa++跳过一个元素,即指向第二个字符串的起始位置
要是感觉还不错的话,麻烦各位大佬们给个关注,点个赞呗,您的支持是我不断前进的动力,都看到这里了,想必和我一样对编程世界怀着同样的期待~~