写在前面
想必在C语言的学习过程中,指针是让大家最为头痛的一个东西,那么接下来我将通过几个例题让大家更了解指针和数组。
数组名的意义
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
例题
一维数组
int main( )
{
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));
return 0;
}
大家可以思考一下这些输出值都是什么???
接下来就来揭晓答案
int main( )
{
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//答案:16 a表示整个数组
printf("%d\n",sizeof(a+0));//答案:4/8 a+0是第一个元素的地址,sizeof(a+0)计算的是地址的大小,故在32位平台上是4,64位平台上为8
printf("%d\n",sizeof(*a));//答案:4 *a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小
printf("%d\n",sizeof(a+1));//答案:4/8 a+1是第二个元素的地址,sizeof(a+1)计算地址的大小,故在32位平台上是4,64位平台上为8
printf("%d\n",sizeof(a[1]));//答案:4 计算的是第二个元素的大小
printf("%d\n",sizeof(&a));//答案:4/8 &a虽然是数组的地址,但也是地址,计算一个地址的大小,故在32位平台上是4,64位平台上为8
printf("%d\n",sizeof(* &a));//答案:16 计算数组的大小
printf("%d\n",sizeof(&a+1));//答案:4/8 &a取出的是整个数组的地址,&a+1也表示地址,故在32位平台上是4,64位平台上为8
printf("%d\n",sizeof(&a[0]));//答案:4/8 &a[0]取出的是第一个元素的的地址,故在32位平台上是4,64位平台上为8
printf("%d\n",sizeof(&a[0]+1));//答案:4/8
return 0;
}
字符数组
第一题
int main()
{
char arr[ ] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
思考一下,来看答案:`
int main()
{
char arr[ ] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//答案:6 arr表示整个数组
printf("%d\n", sizeof(arr + 0));//答案4/8 arr表示首元素的地址,sizeof(arr+0)表示首元素地址的大小,故在32位平台上是4,64位平台上为8
printf("%d\n", sizeof(*arr));//答案:1 *arr表示首元素
printf("%d\n", sizeof(arr[1]));//答案:1 arr[1]表示第二个元素
printf("%d\n", sizeof(&arr));//答案:4/8 &arr表示整个数组的地址,但也是地址,故在32位平台上是4,64位平台上为8
printf("%d\n", sizeof(&arr + 1));//答案:4/8 &arr+1为未知量的地址,但也是地址,故在32位平台上是4,64位平台上为8
printf("%d\n", sizeof(&arr[0] + 1));//答案:4/8 &arr[0]为第一个元素的地址,故在32位平台上是4,64位平台上为8
printf("%d\n", strlen(arr));//答案:随机值 arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
printf("%d\n", strlen(arr + 0));//答案:随机值 arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
printf("%d\n", strlen(*arr));//答案:err *arr为第一个元素,strlen会把他当做一个地址,故会报错
printf("%d\n", strlen(arr[1]));//答案:err *arr为第二个元素,strlen会把他当做一个地址,故会报错
printf("%d\n", strlen(&arr));//答案:随机值 arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
printf("%d\n", strlen(&arr + 1));//答案:随机值-6 arr里面存的是字符而非字符串,所以没有\0,从数组最后一个元素的后面开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值-6
printf("%d\n", strlen(&arr[0] + 1));//答案:随机值-1 arr里面存的是字符而非字符串,所以没有\0,从数组第二个元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值-1
return 0;
}
strlen遇到\0才会停下
第二题
int main( )
{
char arr[ ] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
请大家先思考片刻
接下来看答案:
int main( )
{
char arr[ ] = "abcdef";
printf("%d\n", sizeof(arr));//答案:7 arr此时表示整个数组,a b c d e f \0
printf("%d\n", sizeof(arr + 0));//答案:4/8 arr+0此时表示首元素地址
printf("%d\n", sizeof(*arr));//答案:1 *arr此时表示首元素
printf("%d\n", sizeof(arr[1]));//答案:1 arr[1]表示第二个元素
printf("%d\n", sizeof(&arr));//答案:4/8 &arr表示整个元素的地址
printf("%d\n", sizeof(&arr + 1));//答案:4/8
printf("%d\n", sizeof(&arr[0] + 1));//答案:4/8
printf("%d\n", strlen(arr));//答案:6 a b c d e f \0 到\0停止,故结果为6
printf("%d\n", strlen(arr + 0));//答案:6
printf("%d\n", strlen(*arr));//答案:err
printf("%d\n", strlen(arr[1]));//答案:err
printf("%d\n", strlen(&arr));//答案:6 从首元素开始算,到\0停止
printf("%d\n", strlen(&arr + 1));//答案:随机值 从\0后开始数,直到遇到\0停止
printf("%d\n", strlen(&arr[0] + 1));//答案:5 从第二个元素开始算,到\0停止
return 0;
}
第三题
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p + 1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
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));
return 0;
}
OK,思考片刻来看答案
int main()
{
char* p = "abcdef";//P指向常量字符串首元素的地址
printf("%d\n", sizeof(p));//答案:4/8 sizeof(p)即求常量字符串的首元素地址的大小
printf("%d\n", sizeof(p + 1));//答案:4/8 还是求地址的大小
printf("%d\n", sizeof(*p));//答案:1 首元素
printf("%d\n", sizeof(p[0]));//答案:1 p[0]-->*(p+0)
printf("%d\n", sizeof(&p));//答案:4/8
printf("%d\n", sizeof(&p + 1));//答案:4/8
printf("%d\n", sizeof(&p[0] + 1));//答案:4/8
printf("%d\n", strlen(p));//答案:6 p指向常量字符串首元素的地址,
printf("%d\n", strlen(p + 1));//答案:5 从第二个元素开始查
printf("%d\n", strlen(*p));//答案:err *p为字符串
printf("%d\n", strlen(p[0]));//答案:err p[0]为a
printf("%d\n", strlen(&p));//答案:随机值 p后内存中未知
printf("%d\n", strlen(&p + 1));//答案:随机值 p后内存未知
printf("%d\n", strlen(&p[0] + 1));//答案:5 从第二个元素开始数
return 0;
}
二维数组
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//答案:48 a表示整个数组
printf("%d\n", sizeof(a[0][0]));//答案:4 首元素
printf("%d\n", sizeof(a[0]));//答案:16 第一行整行
printf("%d\n", sizeof(a[0] + 1));//答案:4/8 a[0]作为数组名没有单独放在sizeof内部,也没有取地址,a[0]是第一行第一个元素的地址,所以a[0]+1是第一行第二个元素的地址
printf("%d\n", sizeof(*(a[0] + 1)));//答案:4 第一行第二个元素
printf("%d\n", sizeof(a + 1));//答案:4/8 a作为数组名没有单独放在sizeof内部,也没有取地址,a是二维数组第一个元素的地址,即第一行的地址,所以a+1是第二行的地址
printf("%d\n", sizeof(*(a + 1)));//答案:16 第二行的元素
printf("%d\n", sizeof(&a[0] + 1));//答案:4/8 就是第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));//答案:16 就是第二行的元素
printf("%d\n", sizeof(*a));//答案:16 a作为数组名没有单独放在sizeof内部,也没有取地址,a就是首元素的地址即第一行的地址,所以*a就是第一行
printf("%d\n", sizeof(a[3]));//答案:16 a[3]就是第四行数组名(如果有),其实没有,也能通过类型计算大小
return 0;
}
3+5表达式有两个结果
1.值属性=8
2.类型属性=int