#include<stdio.h> int main() { int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a)); //结果是16,这里算的是整个数组 printf("%d\n", sizeof(a + 0)); //结果是4或8,这里算的是第一个地址的大小 printf("%d\n", sizeof(*a)); //结果是4,这里算的是首元素大小 printf("%d\n", sizeof(a + 1)); //结果是4或8,这里算的是第二个地址的大小 printf("%d\n", sizeof(a[1])); //结果是4,这里算的是第二个元素的大小 printf("%d\n", sizeof(&a)); //结果是4或8,这里算的是整个数组的地址大小 printf("%d\n", sizeof(*&a)); //结果是16,这里先是取出整个数组地址,然后对整个数组解引用,也就是算出的是整个数组的大小 printf("%d\n", sizeof(&a + 1)); //结果是4或8,这里跳过了整个数组,计算数组后面的地址大小,所以是4或8,&a的类型是int(*)[4] printf("%d\n", sizeof(&a[0])); //结果是4或8,这里算的是第一个元素的地址大小 printf("%d\n", sizeof(&a[0] + 1)); //结果是4或8,这里算的是第二个元素的地址大小 return 0; }
注意:这里&a的类型是int(*)[4],数组指针,
&a+1是跳过整个数组
sizeof()和char型一维数组
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr)); //6,这里计算的是整个数组 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,这里计算的是跳过整个数组之后,整个地址的大小 printf("%d\n", sizeof(&arr[0] + 1)); //还是4或8,这里计算的是第二个元素的地址大小
strlen和char型一维数组
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", strlen(arr)); //随机值,这里计算的是整个数组,即从第一个元素开始往后计算直到找到\0位置,随机值是因为这个数组里面没有\0 printf("%d\n", strlen(arr + 0)); //随机值,这里strlen是从第一个元素开始往后数,随机值的值跟上面的值一样 printf("%d\n", strlen(*arr)); //报错,这里传的是第一个元素,第一个元素是一个值,strlen()括号里面的必须是char *类型的指针变量,而这里面的元素是char类型不是char *类型,若把'a'传过去,则相当于把97当作指针穿了过去 printf("%d\n", strlen(arr[1])); //报错,传的是第二个元素,跟上面的值一样 printf("%d\n", strlen(&arr)); //随机值,跟前面一样,传的是整个地址,整个地址是从第一个元素的地址开始的,随意会产生随机值,由于是从第一个元素开始,所以产生的结果会跟第一个一样 printf("%d\n", strlen(&arr + 1)); //随机值,这里是跳过了整个数组,然后开始计算,遇到\0便停止,跟第一个随机值相差6 printf("%d\n", strlen(&arr[0] + 1)); //随机值,从第二个元素的地址开始计算,遇到\0停止,跟第一个随机值相差1
sizeof()和字符串数组
char arr[] = "abcdef"; printf("%d\n", sizeof(arr)); //7,有\0 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,跳过这个数组后,计算后面的地址大小 printf("%d\n", sizeof(&arr[0] + 1)); //4或8,跳过第一个元素后,计算后面的地址大小,而不是数组里面的内容大小
sizeof和字符串数组
char arr[] = "abcdef"; printf("%d\n", sizeof(arr)); //7,有\0 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,跳过这个数组后,计算后面的地址大小 printf("%d\n", sizeof(&arr[0] + 1)); //4或8,跳过第一个元素后,计算后面的地址大小,而不是数组里面的内容大小
strlen和字符串
char arr[] = "abcdef"; printf("%d\n", strlen(arr)); //6,遇到\0停止打印 printf("%d\n", strlen(arr + 0)); //6,遇到\0停止打印 printf("%d\n", strlen(*arr)); //报错,传的不是char *类型 printf("%d\n", strlen(arr[1])); //报错,穿的不是char*类型 printf("%d\n", strlen(&arr)); //6,传的是整个数组地址,从第一个元素的地址开始 printf("%d\n", strlen(&arr + 1)); //随机值,跨过整个数组之后,开始计算遇到\0停止 printf("%d\n", strlen(&arr[0] + 1)); //5,从第二个元素开始计算,遇到\0停止
字符指针和sizeof()
char* p = "abcdef"; printf("%d\n", sizeof(p)); //4或8,这里的p是指针,p里面村的是第一个元素的地址, printf("%d\n", sizeof(p + 1)); //4或8,指向第二个元素的地址 printf("%d\n", sizeof(*p)); //1,第一个元素的大小 printf("%d\n", sizeof(p[0])); //1,第一个元素的大小 printf("%d\n", sizeof(&p)); //4或8,&p是二级指针 printf("%d\n", sizeof(&p + 1)); //4或8,跨过了整个数组 printf("%d\n", sizeof(&p[0] + 1)); //4或8,从第二个元素开始计算地址的大小
字符指针和strlen()
char* p = "abcdef"; printf("%d\n", strlen(p)); //6,p是首元素地址 printf("%d\n", strlen(p + 1)); //5,从第二个元素开始计算 printf("%d\n", strlen(*p)); //报错,因为穿的是一个值,不是char *类型的 printf("%d\n", strlen(p[0])); //报错,传的是一个值,不是char *类型的 printf("%d\n", strlen(&p)); //随机值,p是一个一级指针,&p就是一个二级指针,也就是说这里的strlen是从p的地址开始向后数的遇到\0停止 printf("%d\n", strlen(&p + 1)); //随机值,跨过了整个数组,然后开始计算遇到\0位置 printf("%d\n", strlen(&p[0] + 1)); //随机值,从第一个元素开始计算遇到\0为止,这个和上面的相差的数字也是随机值,不是一个确定的数,因为他们遇到\0的情况不相同 //倒数第二个和倒数第一个相差的值,是一个随机值,因为&p是从p的地址开始数,当没到&p[0]+1时,可能会出现\0也有可能不会出现\0,而&p[0]+1,时从第二个元素的地址开始数,什么时候遇到\0则说不准
&p+1和&p[0]+1结果相差为随机值的原因,有可能在p[0]+1往右移动且没到达&p+1的时候遇到\0,也有可能会和&p+1遇到同一个\0,由于这里的\0具有不确定性,所以他们俩者相差的就是一个随机值。
二维数组和sizeof()
int a[3][4] = { 0 }; printf("%d\n", sizeof(a)); //48,这里计算的是整个数组的大小 printf("%d\n", sizeof(a[0][0])); //4,这里计算第一个元素的大小 printf("%d\n", sizeof(a[0])); //16,a[0]第一行元素的大小 printf("%d\n", sizeof(a[0] + 1)); //4/8,这里的a[0]不再单独放在()内部,有+1的操作,所以这里的a[0]表示首元素的地址,+1就表示第二个元素地址的大小,所以这里的是地址 printf("%d\n", sizeof(*(a[0] + 1))); //4,这个是第一行,第二个元素的大小 printf("%d\n", sizeof(a + 1)); //4/8,a有+1的操作,所以a表示首元素地址,即第一行,a+1就是第二行的地址,由于算的是地址所以是4/8 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表示首元素地址,*a就是解引用,所以是16 printf("%d\n", sizeof(a[3])); //16,这里并没有越界,因为他没有去访问第四行
总结
数组名的意义:
1. sizeof( 数组名 ) ,这里的数组名表示整个数组,计算的是整个数组的大小。
2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。