对于整形数组:
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); 此处a代表整个数组的大小,类型是int(*)【4】,大小是16
printf("%d\n",sizeof(a+0));此处a+0代表数组首元素的地址,类型是int*,大小4或者8
printf("%d\n",sizeof(*a));此处*a表示数组首元素,类型是int,大小是4
printf("%d\n",sizeof(a+1));此处a+1表示数组第二个元素的地址,类型int*,大小是4或者8
printf("%d\n",sizeof(a[1]));数组第二个元素,类型int,大小4
printf("%d\n",sizeof(&a));数组的地址,类型int**,大小4或8
printf("%d\n",sizeof(*&a));*和&抵消,可视为sizeof(a),大小16
printf("%d\n",sizeof(&a+1));指向数组后第一个字节的位置,类型和&a相同,大小4或8
printf("%d\n",sizeof(&a[0]));表示数组首元素的地址,类型int*,大小4或8
printf("%d\n",sizeof(&a[0]+1));表示数组第二个元素的地址,类型int*,大小4或8
对于字符数组:
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));整个数组的大小,类型是char【6】,大小6
printf("%d\n", sizeof(arr+0));数组首元素的地址,类型char*,大小4或8
printf("%d\n", sizeof(*arr));数组首元素,类型char,大小1
printf("%d\n", sizeof(arr[1]))数组第二个元素,类型char,大小1
printf("%d\n", sizeof(&arr));数组的地址,类型char(*)【6】,大小4或8
printf("%d\n", sizeof(&arr+1));跳过整个数组,指向数组后第一个字节,类型char(*)【6】,大小4或8
printf("%d\n", sizeof(&arr[0]+1));数组第二个元素的地址,类型char*,大小4或8
printf("%d\n", strlen(arr)); 内部是数组首元素的地址,结果未知,因为arr中没有\0作为结束标志
printf("%d\n", strlen(arr+0));内部是数组首元素的地址,结果未知,因为arr中没有\0作为结束标志
printf("%d\n", strlen(*arr));内部是数组首元素,相当于把‘a’的ascii值作为地址,非法访问。
printf("%d\n", strlen(arr[1]));内部是数组首元素,相当于把‘a’的ascii值作为地址,非法访问。
printf("%d\n", strlen(&arr));内部是数组的地址,结果未知。
printf("%d\n", strlen(&arr+1));内部是跨国数组的第一个字节的地址,结果未知。
printf("%d\n", strlen(&arr[0]+1));内部是第二个元素的地址,结果未知,因为arr中没有\0。
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));表示数组大小,类型char【7】,大小7.
printf("%d\n", sizeof(arr+0));表示数组首元素的地址,类型char*,大小4或8.
printf("%d\n", sizeof(*arr));表示数组第一个元素,类型char,大小1。
printf("%d\n", sizeof(arr[1]));表示数组第二个元素,类型char,大小1.
printf("%d\n", sizeof(&arr));表示数组的地址,类型char(*)【7】,大小4或8.
printf("%d\n", sizeof(&arr+1));表示跨过整个数组后的地址,类型char(*)【7】,大小4或8.
printf("%d\n", sizeof(&arr[0]+1));表示数组第二个元素的地址,类型char*,大小4或8.
printf("%d\n", strlen(arr));表示数组首元素的地址,大小6.
printf("%d\n", strlen(arr+0));表示数组首元素地址,大小6
printf("%d\n", strlen(*arr));表示数组第一个元素,将其ascii看做地址大小,非法访问。
printf("%d\n", strlen(arr[1]));表示数组第二个元素,同上
printf("%d\n", strlen(&arr));表示整个数组地址,大小6
printf("%d\n", strlen(&arr+1));表示跨过整个数组后的地址,大小未知
printf("%d\n", strlen(&arr[0]+1));表示数组第二个元素地址,大小5.
char *p = "abcdef";
printf("%d\n", sizeof(p));表示数组首元素的地址,类型char*,大小4或8
printf("%d\n", sizeof(p+1));表示数组第二个元素的地址,类型char*,大小4或8
printf("%d\n", sizeof(*p));表示数组首元素,类型char,大小1
printf("%d\n", sizeof(p[0]));表示数组首元素,类型char,大小1
printf("%d\n", sizeof(&p));表示指针的地址,类型char**,大小4或8
printf("%d\n", sizeof(&p+1));表示指针的地址的下一位,类型char**,大小4或8
printf("%d\n", sizeof(&p[0]+1));表示数组第二个元素的地址,类型char*,大小4或8
printf("%d\n", strlen(p));表示数组首元素的地址,大小6
printf("%d\n", strlen(p+1));表示数组第二个元素的地址,大小5
printf("%d\n", strlen(*p));表示数组首元素,非法访问
printf("%d\n", strlen(p[0]));同上
printf("%d\n", strlen(&p));表示指针的地址,结果未知(与字符串已经无关)
printf("%d\n", strlen(&p+1));表示指针的地址的下一位,结果未知(与字符串已经无关)
printf("%d\n", strlen(&p[0]+1));表示数组第二个元素的地址,大小5
对于二维数组:
int a[3][4] = {0};
printf("%d\n",sizeof(a));表示数组的地址,类型int【3】【4】,大小48
printf("%d\n",sizeof(a[0][0]));表示数组首元素,类型int,大小4
printf("%d\n",sizeof(a[0]));表示第一个一维数组的地址,类型int【4】,大小16
printf("%d\n",sizeof(a[0]+1));表示第二个元素a【0】【1】的地址,类型int*,大小4或8
printf("%d\n",sizeof(*(a[0]+1)));表示数组第二个元素a【0】【1】,类型int,,大小4
printf("%d\n",sizeof(a+1));表示数组第二个一维数组数组的地址,类型int(*)【4】,大小4或8
printf("%d\n",sizeof(*(a+1)));表示数组第二个一维数组,类型int【4】,大小16
printf("%d\n",sizeof(&a[0]+1));表示数组第二个一维数组的地址,类型int(*)【4】,大小4或8
printf("%d\n",sizeof(*(&a[0]+1)));表示数组第二个一维数组,类型int【4】,大小16
printf("%d\n",sizeof(*a));表示a【0】,类型类型int【4】,大小16
printf("%d\n",sizeof(a[3]))类型类型int【4】,大小16
int main() {
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0; }
本题ptr指向数组后第一个字节的位置,ptr减一则往前移动一个指针大小的字节,指向a【4】的地址,解引用为a【4】的值,为5
a+1表示数组第二个元素的地址,即&a【1】,解引用是a【1】,大小2.
int main() {
char*p=(char*)ox001.
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
p的类型是char*,加ox1相当跳过一个char类型,即加ox1,值为ox(1+1)
(unsign long)p的类型是unsigned long,加ox1就是加数字ox1,值为ox(1+1)
(unsigned int*)类型是unsigned int*,加ox1就是加一个int类型,值为ox(4+1)
一般来说指针加1就是加1个指针所指类型的数据的大,但应当注意对于指向数组的指针,一次是跳过数组的一个元素。
int main() {
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0;
}
ptr1指向数组后第一个字节的位置,ptr1【-1】可视为*(ptr1-1),其中ptr1-1就是减去一个int大小的地址,指向a【3】的地址,解引用是a【3】,大小4
(int)a+1就是在数组首元素的地址的基础上加1个字节,根据小端存储,ptr2的数据是ox02000000。
int main() {
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
p【0】可视为a【0】【0】,故为1
此处应当注意数组的元素,均是由逗号表达式组成的表达式,而逗号表达式只要最后一个元素,因此初始化二维数组可等价于int a【3】【2】={1,3,5}
int main() {
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
此处p【4】【2】指向数组a的第4*4+2=18的位置,即数组第19个元素,a【4】【2】指向数组a的第4*5+2=22的位置,即数组第23个元素。因此相减的结果是19-23=-4,%p的结果是-4的补码,即oxfffffffc,%d的结果是-4.
int main() {
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);
int *ptr2 = (int *)(*(aa + 1));
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
&aa+1跳过整个数组,减一后指向数组最后一个元素,即a【9】,大小是10
aa+1跳过一个一维数组,指向aa【1】,解引用就是aa【1】【0】的地址,减一就是aa【0】【4】的地址,即5.
应当注意二维数组可视为多个一维数组连续存放,,即在地址上是一直相连的。
int main() {
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
pa的类型是char**,,其内容是数组首元素的地址,pa++指向数组第二个元素,即a【1】,结果为at。
应注意