数组名的意义:
-
温馨提示,切记这几句话,对下面的题很有帮助,都是面试真题!!!
-
sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
-
&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
-
除此之外所有的数组名都表示首元素的地址。
//一维数组
//int a[] = { 1, 2, 3, 4 };
//printf("%d\n", sizeof(a));//16 sizeof(数组名)计算的是整个数组的大小
//printf("%d\n", sizeof(a + 0));//4/8 这里不是单独的数组名,a+0表示首元素地址加0,还是首元素地址,地址占4或8个字节
//printf("%d\n", sizeof(*a));//4 a是首元素的地址对首元素地址解引用,找到第一个元素,大小是4个字节
//printf("%d\n", sizeof(a + 1));//4或8 首元素地址加1是第二个元素地址,还是地址就是4或8字节
//printf("%d\n", sizeof(a[1]));//4 第二个元素的大小
//printf("%d\n", sizeof(&a));// 4 取地址a 取的是整个数组地址,还是地址呀,所以占4或8字节
//printf("%d\n", sizeof(*&a));//16 --先取整个数组的地址,再解引用找到这个数组,计算数组的大小
//printf("%d\n", sizeof(&a + 1));//4或8 &a 是整个数组的地址,再加1跳过整个数组,后下一块空间的地址
//printf("%d\n", sizeof(&a[0]));//4或8 取得是数组数组首元素的地址
//printf("%d\n", sizeof(&a[0] + 1));// 4或8 取首元素的地址再加1是第二个元素的地址//字符数组
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", sizeof(arr)); //6 数组名单独放在sizeof,计算整个素组的大小
printf("%d\n", sizeof(arr + 0)); // 4或8 数组首地址+0,还是地址
printf("%d\n", sizeof(*arr)); // 1 对数组的首地址解引用找到‘a’ 计算a的大小
printf("%d\n", sizeof(arr[1]));//1 计算a的大小
printf("%d\n", sizeof(&arr));//4或8 取数组名是取得整个数组的地址,也是地址呀
printf("%d\n", sizeof(&arr + 1));// 4或8 &arr取整个数组的地址再+1 挑个一个数组之后的地址
printf("%d\n", sizeof(&arr[0] + 1));// 4或8 &arr[0],首元素地址加一,第二个元素的地址printf("%d\n", strlen(arr));//随机值 不知道'\0'的位置
printf("%d\n", strlen(arr + 0));// 随机值 数组首地址+0 还是从指向a,从a开始向后读 还是找不到'\0'
printf("%d\n", strlen(*arr)); //err arr数组名首元素地址,解引用找到a,a的ASCII是97,在97向后读肯定错了
printf("%d\n", strlen(arr[1]));//err strlen(字符b),ASCII是98
printf("%d\n", strlen(&arr));// 6 取数组名,在strlen看来整个数组的地址,和数组的首地址一样,还是从a向后读
printf("%d\n", strlen(&arr + 1));// 随机值-6,跳过一个数组,在向后读,还是找不到'\0'
printf("%d\n", strlen(&arr[0] + 1));//随机值-1 首地址+1 第二个元素地址向后读char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //7 计算整个数组的大小
printf("%d\n", sizeof(arr + 0));// 4或8 计算首元素地址的大小
printf("%d\n", sizeof(*arr));//1 数组名解引用,找到第一个元素,计算第一个元素的大小
printf("%d\n", sizeof(arr[1]));//1 计算第一个元素的大小
printf("%d\n", sizeof(&arr)); //4或8 取的整个数组的地址,也是地址呀
printf("%d\n", sizeof(&arr + 1)); // 4或8 整个数组地址+1,跳过整个数组的后的第一个地址
printf("%d\n", sizeof(&arr[0] + 1));// 4或8 &a的地址+1 是b的地址printf("%d\n", strlen(arr));//6 计算有几个元素
printf("%d\n", strlen(arr + 0)); //6 和上面一样
//printf("%d\n", strlen(*arr)); //err 解引用arr找到a a的ASCII是97 向后读不对滴
//printf("%d\n", strlen(arr[1]));// err 找到a 向后读是不对滴
printf("%d\n", strlen(&arr)); // 6 取得整个数组的地址,也是首地址呀,往后读
printf("%d\n", strlen(&arr + 1));// 随机值 跳过这个数组
printf("%d\n", strlen(&arr[0] + 1));//5 取第一个元素的地址在+1 就第二个元素地址char *p = "abcdef";
//首先要想是吧整个字符赋給指针变量P了吗?
//当然不是,是吧字符串首元素的地址给了P
printf("%d\n", sizeof(p));// 4或8 p是指针变量,4或8个字节
printf("%d\n", sizeof(p + 1));//4或8 p存的是a的地址加一是b的地址,还是地址
printf("%d\n", sizeof(*p));// 1 p->a 再解引用找到a 大小1个字节
printf("%d\n", sizeof(p[0]));// 1 找到的a 大小1个字节 ~*(p+0)
printf("%d\n", sizeof(&p));// 4或8 &p的地址也是地址呀printf("%d\n", sizeof(&p + 1)); //4或8 &p的地址再加一跳过p这块空间的下一个地址 ,还是一个地址
printf("%d\n", sizeof(&p[0] + 1));//4或8 p[0] 是a 再&地址,+1后是b的地址
printf("%d\n", strlen(p));// 6 p->a 向后读一共6个
printf("%d\n", strlen(p + 1));//5 p指向a 再加1 指向b
printf("%d\n", strlen(*p));//err p是首地址,解引用找到a a的ASCII是97 向后读是错滴
printf("%d\n", strlen(p[0]));//err *(p+0) 找到a
printf("%d\n", strlen(&p)); //随机值 &p 是取得p的地址,往后找谁™知道'\0' 在哪
printf("%d\n", strlen(&p + 1)); // 随机值 跳过p这块空间 往后读 也不知道'\0' 在哪
printf("%d\n", strlen(&p[0] + 1));// 5 p[0] 是a 再取a的地址,再+1 是b的地址 再向后读//二维数组
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48 sizeof(数组名)求的整个数组的大小,4*4*3=48
printf("%d\n", sizeof(a[0][0]));//4 计算第0行 0列的元素大小printf("%d\n", sizeof(a[0]));//16 解释:a[0]可以理解为第一行的数组名,
//此时就是sizeof(a[0])---数组名单独放在了sizeof内部,计算的是第一行的大小printf("%d\n", sizeof(a[0] + 1));//4或8 a[0]是第一行的数组名,并没有单独放在sizeof里面,也没有&地址,所以a[0] 表示第一行第一个元素的地址 再加1就是第二个元素的地址
printf("%d\n", sizeof(*(a[0] + 1)));//4 a[0]是第一行的数组名,没有单独放在sizeof内部,也没取地址,所以表示第一行的第一个元素地址,再加一就是第一行第二个元素的地址,再解引用找到了该元素,计算该元素的大小
printf("%d\n", sizeof(a + 1));//4或8 a是二维数组的数组名,a表示二维数组首元素的地址,即是二维数组的第一行的地址,二维数组首地址加1跳过这一行,找到了第二行的地址
printf("%d\n", sizeof(*(a + 1)));//16 *(a+1)~a[1] a是二维数组的名,没有单独放在sizeof内部,也没有&数组名,a表示二维数组首元素的地址,即二维数组第一行的地址,+1就找到了二维数组的第二行,再解引用计算的二维数组第二个元素大小,即第二行的大小
printf("%d\n", sizeof(&a[0] + 1));//4或8 &a[0],取的是第一行的数组名表示整个数组的地址,加1是第二行的地址,也是地址呀,所以计算的是地址的大小
printf("%d\n", sizeof(*(&a[0] + 1)));//16 然后再解引用是计算第二行的大小printf("%d\n", sizeof(*a));//16 ~*(a+0)~a[0] a没有单独的放在sizeof内部,也没有&数组名,a表示二维数组首元素的地址,也就是 一维数组的地址,再解引用找到的是这个一维数组,计算一维数组的大小
printf("%d\n", sizeof(a[3]));//16 a[3]其实是第4行的数组名(如果有的话,其实不存在)但是可以给通过类型计算大小
第二部分:笔试题
第一题
#include<stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1)); return 0;
}
//程序的结果是什么?第二题
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
printf("%p\n", p + 0x1);//p是结构体类型指针,(结构体大小是20字节)+1就是跳过20字节,十六禁止的20是14
//100014
printf("%p\n", (unsigned long)p + 0x1);//把P转换成无符号长整形,再+1 就是100001
//100001
printf("%p\n", (unsigned int*)p + 0x1);//把p转换为无符号整形指针,+1就是向后跳4个字节,
//100004
return 0;
}第三题
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;
} -
第4 题
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];//这是把第1行的a[0]的首地址给了p,而不是把二维数组的首元素地址给了p
printf("%d", p[0]);
return 0;
}第五题
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;
}第6题
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;
}第7题
int main()
{
char *a[] = { "work", "at", "alibaba" };
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}