带你搞懂指针和数组方面的相关例题
Posted Layman光~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你搞懂指针和数组方面的相关例题相关的知识,希望对你有一定的参考价值。
引言
要搞懂下面这些例题,首先你要知道关于数组名的意义以下这几点:
数组名的意义:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
一维数组
//32位平台下
//一维数组
int main()
{
int a[] = { 1, 2, 3, 4 };
printf("%d\\n", sizeof(a));//16
//计算的是整个数组的大小,整个数组4个元素,每个元素字节大小为4,所以结果为4 * 4 = 16
printf("%d\\n", sizeof(a + 0));//4
//a + 0表示的是第一个元素的地址,它计算的是地址的大小,地址的大小在32位平台下为4,在64位平台下为8
printf("%d\\n", sizeof(*a));//4
//a在这里表示为数组首元素的地址,即1的地址,对1的地址解引用。就是求数组首元素的大小。1是整型,整型大小为4
printf("%d\\n", sizeof(a + 1));//4
//a在这里表示为首元素的地址,首元素地址加1表示跳过一个元素,a + 1指向的是第二个元素的地址。第二个元素的地址大小为4
printf("%d\\n", sizeof(a[1]));//4
//计算数组第二个元素的大小,即结果为4
printf("%d\\n", sizeof(&a));//4
//计算的是整个数组的地址,只要求地址的大小,就记住,32位平台下大小为4,64位平台下大小为8.这里结果是4
printf("%d\\n", sizeof(*&a));//16
//计算的是整个数组的大小,&a表示取出的是整个数组的地址,然后对整个数组的地址进行解引用,所以计算的就是整个数组的大小。结果为16
printf("%d\\n", sizeof(&a + 1));//4
//这里&a表示的是整个数组的地址,它加1,即是跳过整个数组,然后指向下一个位置的地址。即数组后面的空间的地址,结果为4.
printf("%d\\n", sizeof(&a[0]));//4
//计算的是数组第一个元素的地址的大小。结果为4
printf("%d\\n", sizeof(&a[0] + 1));//4
//计算的是数组第二个元素的地址的大小。结果为4
return 0;
}
字符数组
//32位平台下
//字符数组
int main()
{
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\\n", sizeof(arr));//6
//数组名单独放在sizeof内部,计算的是整个数组的大小,因为数组有6个元素,每个元素是char类型。所以结果为6
printf("%d\\n", sizeof(arr + 0));//4
//表示的是首元素地址,结果为4
printf("%d\\n", sizeof(*arr));//1
//表示的是对数组首元素地址进行解引用。计算的是字符‘a’的大小,为1
printf("%d\\n", sizeof(arr[1]));//1
//计算的是字符‘b’的大小,结果为1
printf("%d\\n", sizeof(&arr));//4
//计算的整个数组的地址大小,结果为4
printf("%d\\n", sizeof(&arr + 1));//4
//计算的是跳过整个数组后的位置的地址,结果为4
printf("%d\\n", sizeof(&arr[0] + 1));//4
//计算的是第二个元素,字符‘b’的地址。结果为4
printf("%d\\n", strlen(arr));//随机值
//这里的arr表示首元素地址,strlen是求长度,给一个地址,从前向后数,遇到‘\\0’停下来。
//这里没有‘\\0',故结果是随机值。准确的说是比6大的随机值,因为数组里面已经有了6个元素。
printf("%d\\n", strlen(arr + 0));//随机值
//这里的arr + 0表示首元素地址.故结果也是随机值
printf("%d\\n", strlen(*arr));//报错
//首先strlen()的使用,它接收的得是一个地址;而*arr在这里表示的是字符‘a’,把字符给它传过去,故结果会报错
printf("%d\\n", strlen(arr[1]));//报错
//同上,结果报错
printf("%d\\n", strlen(&arr));//
//&arr在这里表示的是数组地址,把数组地址给strlen传过去,strlen接收它,
//站在它的角度,依然是字符串的地址,依然是从字符‘a’的地址开始向后数,故结果仍是随机值
printf("%d\\n", strlen(&arr + 1));//随机值
//在这里计算的是从跳过整个数组后的位置的地址,开始向后数直到遇到‘\\0',才停止的长度。故为随机值。
//准确来说,与上面的区别来说,结果为随机值-6.
printf("%d\\n", strlen(&arr[0] + 1));//随机值
//从字符‘b’开始向后数,结果也为随机值。准确来说,结果为随机值 - 1.
char arr[] = "abcdef";
//[a b c d e f \\0]
printf("%d\\n", sizeof(arr));//7
//计算的是整个数组的大小,结果为7
printf("%d\\n", sizeof(arr + 0));//4
//计算的是首元素地址a的大小,结果为1
printf("%d\\n", sizeof(*arr));//1
//对数组的首元素地址进行解引用,即计算的是a的大小,结果为1
printf("%d\\n", sizeof(arr[1]));//1
//计算的是字符b的大小,结果为1
printf("%d\\n", sizeof(&arr));//4
//计算的是整个数组的地址,结果为4
printf("%d\\n", sizeof(&arr + 1));//4
//计算的是跳过整个数组的后的位置的地址,结果为4
printf("%d\\n", sizeof(&arr[0] + 1));//4
//计算的是b的地址,结果为4
printf("%d\\n", strlen(arr));//6
//计算的是字符串的长度,从a的地址开始向后数,遇到\\0停止,结果为6
printf("%d\\n", strlen(arr + 0));//6
//从a的地址开始向后数,遇到\\0停止,结果为6
printf("%d\\n", strlen(*arr));//报错
//传给strlen的不是地址,故结果报错
printf("%d\\n", strlen(arr[1]));//报错
//传给strlen的不是地址,故结果报错
printf("%d\\n", strlen(&arr));//6
//从a的地址开始向后数,遇到\\0停止,结果为6
printf("%d\\n", strlen(&arr + 1));//随机值
//跳过整个数组之后的位置的地址开始向后数,不知何时遇到\\0,故结果为随机值
printf("%d\\n", strlen(&arr[0] + 1));//5
//从b的地址开始向后数,遇到\\0停止,结果为5
char *p = "abcdef";
printf("%d\\n", sizeof(p));//4
//计算的是指针变量的大小,p在这里是一个字符指针。结果为4
printf("%d\\n", sizeof(p + 1));//4
//p本来是a的地址,p + 1 就变成了b的地址,故结果为4
printf("%d\\n", sizeof(*p));//1
//p是a的地址,对a解引用,计算的是a的大小,结果为1
printf("%d\\n", sizeof(p[0]));//1
//p[0]等同于*(p + 0),计算的是a的大小,结果为1
printf("%d\\n", sizeof(&p));//4
//计算的是p的地址,结果为4
printf("%d\\n", sizeof(&p + 1));//4
//计算的是跳过p后的位置的地址,结果为4
printf("%d\\n", sizeof(&p[0] + 1));//4
//计算的是b的地址,结果为4
printf("%d\\n", strlen(p));//6
//把a的地址交给p,从a的地址开始数,结果为6
printf("%d\\n", strlen(p + 1));//5
//从b的地址开始数,结果为5
printf("%d\\n", strlen(*p));//报错
//传给strlen的不是地址,故结果报错
printf("%d\\n", strlen(p[0]));//报错
//传给strlen的不是地址,故结果报错
printf("%d\\n", strlen(&p));//随机值
//p的地址不清楚,故结果为随机值
printf("%d\\n", strlen(&p + 1));//随机值
//跳过p的后的位置的地址,结果为随机值
printf("%d\\n", strlen(&p[0] + 1));//5
//从b的地址开始数,结果为5
return 0;
}
二维数组
//二维数组
int main()
{
int a[3][4] = { 0 };
printf("%d\\n", sizeof(a));//48
//计算的是整个数组的大小,二维数组,三行四列,共有12个元素,每个元素是int型,故结果为48
printf("%d\\n", sizeof(a[0][0]));//4
//计算的是第一行第一个元素的大小,结果为4
printf("%d\\n", sizeof(a[0]));//16
//把a[0]看作一个一维数组,那么a[0]就可以看作一维数组的数组名,数组名单独放在sizeof内部,
//所以a[0]表示整个的第一行,计算的是整个第一行的大小,第一行有4个元素,结果为16
printf("%d\\n", sizeof(a[0] + 1));//4
//a[0]作为数组名并没有单独放在sizeof内部,也没有取地址,
//因此在这里表示的是第一行第一个元素的地址,加1表示的是第一行第二个元素的地址,故结果为4
printf("%d\\n", sizeof(*(a[0] + 1)));//4
//同上,对第一行第二个元素解引用得到一个整型元素,大小为4.
printf("%d\\n", sizeof(a + 1));//4
//二维数组数组名a在这里表示首元素地址,即第一行的地址,第一行地址加1,得到的是第二行的地址,结果为4
printf("%d\\n", sizeof(*(a + 1)));//16
//*(a + 1)等同于a[1],把a[1]看作一维数组的数组名,则计算的是第二行的大小,结果为16
//a + 1是第二行的地址,对第二行解引用,则求的是整个第二行的大小
printf("%d\\n", sizeof(&a[0] + 1));//4
//对第一行的数组名取地址,得到第一行的地址,加1得到的就是第二行的地址,结果为4
printf("%d\\n", sizeof(*(&a[0] + 1)));//16
//对第二行的地址进行解引用,计算的就是整个第二行的大小
printf("%d\\n", sizeof(*a));//16
//a在这里表示首元素的地址,二维数组的首元素就是第一行,
//即a表示第一行的地址,对第一行的地址解引用,得到的就是整个第一行的大小
printf("%d\\n", sizeof(a[3]));//16
//sizeof()内部的表达式是不计算的,因此不会去访问它。
//根据它的类型属性我们可以知道a[3]等同于a[0] a[1] a[2]。因此在这里它的结果为16.
return 0;
}
以上是关于带你搞懂指针和数组方面的相关例题的主要内容,如果未能解决你的问题,请参考以下文章