C语言 ——对数组名进行解引用,取地址,还有sizeof和strlen进行操作解析

文章目录

  • 前言
  • 一、数组名的理解(一维数组)
  • 二、数组名的理解(字符数组)
  • 三、数组名的理解(字符串数组)
  • 四、数组名的理解(字符串指针)
  • 五、二维数组


前言

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。
  4. strlen()是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数
  5. sizeof()只关注占用内存空间的大小,不在乎内存中放的是什么

一、数组名的理解(一维数组)

数组名表示首元素地址

//一维数组
int main()
{int a[] = {1,2,3,4};			初始化四个元素printf("%d\n",sizeof(a));		16sizeof(a),a表示整个数组,计算的是整个数组的大小,单位是字节。printf("%d\n",sizeof(a+0));		4/8  (32位或者64)  a + 0 == &a[0]+0sizeof(a+0),数组名a+0等于首元素+0,结果就是 4/8printf("%d\n",sizeof(*a));		4sizeof(*a) 		*a中的a是数组首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素printf("%d\n",sizeof(a+1));		4/8sizeof(a+1)		首元素 + 1printf("%d\n",sizeof(a[1]));	4sizeof(a[1])   	计算的是下标位1的大小printf("%d\n",sizeof(&a));		4/8sizeof(&a)		&a取出的数组的地址,数组的地址,也就是个地址,数组的地址就是4/8字节,主要是地址就是4/8printf("%d\n",sizeof(*&a));		16	 sizeof(*&a) *&抵消剩下个a数组的解引用就是访问整个数组&a拿到的是数组名的地址,类型是int(*)[4],是一种数组指针数组指针解引用找到的是 *&a ----> aprintf("%d\n",sizeof(&a+1));	4/8&a + 1 是从数组a的地址向后跳过一个(4个整形元素的)数组的大小&a + 1 还是地址,是地址就是4/8字节printf("%d\n",sizeof(&a[0]));	4就是首元素元素的地址计算的是地址的大小printf("%d\n",sizeof(&a[0]+1));	4/8计算的是第二个元素的地址return 0;
}

二、数组名的理解(字符数组)

#include
#include
int main()
{char arr[] = {'a','b','c','d','e','f'};		7个元素(\0)printf("%d\n", sizeof(arr));		6一个数组1个字节不算\0printf("%d\n", sizeof(arr+0));		4/8sizeof(arr+0)	是数组首元素的地址  是地址在这就是4/8printf("%d\n", sizeof(*arr));	18arr就是数组首元素,大小是1字节*arr == arr[0]*(arr+0) == arr[0]arr+0就是首元素大小printf("%d\n", sizeof(arr[1]));	1printf("%d\n", sizeof(&arr));4/8	&arr是数组的地址,是地址就是4/8printf("%d\n", sizeof(&arr+1));	4/8&arr+1跳过整个数组,指向下个地址,是地址就是4/8printf("%d\n", sizeof(&arr[0]+1));	4/8&arr[0] + 1  是第二个元素的地址是地址就是4/8个字节strlenprintf("%d\n", strlen(arr));	随机值arr首元素strlen会一直向后跑知道找到\0一直往后寻找知道找到\0printf("%d\n", strlen(arr+0));	还是随机值arr+0  还是首元素地址printf("%d\n", strlen(*arr)); 	strlen('a');--->strlen(97);野指针strlrn要传过去地址不传地址会报错printf("%d\n", strlen(arr[1]));	strlen('b');--->strlen(98);野指针报错printf("%d\n", strlen(&arr));	随机值printf("%d\n", strlen(&arr+1));	随机值-6因为跳过一个数组进入下一个数组printf("%d\n", strlen(&arr[0]+1));	随机值-1从下标01开始向后找\0.所以-1return 0
}

三、数组名的理解(字符串数组)

int main()
{char arr[] = "abcdef";	7printf("%d\n", sizeof(arr));	7 printf("%d\n", sizeof(arr+0));	4/8arr+0就是首元素地址  只要是地址就是4/8printf("%d\n", sizeof(*arr));	1*arr  arr表示首元素地址  a的解引用得到aa就是1一个字节printf("%d\n", sizeof(arr[1])); 1计算下标为1的大小printf("%d\n", sizeof(&arr));4/8是地址就是4/8printf("%d\n", sizeof(&arr+1));	4/8跳过整个数组 指向下一个数组printf("%d\n", sizeof(&arr[0]+1));	4/8这里取的是b的地址   是地址那就是4/8strlenprintf("%d\n", strlen(arr));	6printf("%d\n", strlen(arr+0));	6arr+0首元素+0还是首元素printf("%d\n", strlen(*arr));	报错把首元素地址解引用strlen只能传地址printf("%d\n", strlen(arr[1]));	报错printf("%d\n", strlen(&arr));	6printf("%d\n", strlen(&arr+1));	随机printf("%d\n", strlen(&arr[0]+1));	5首元素+1开始计算return 0;
}

四、数组名的理解(字符串指针)

int main()
{char *p = "abcdef";p有自己的空间存放的是abcdef的地址printf("%d\n", sizeof(p));		4/8p是个指针变量,用sizeof来算那就是4/8字节printf("%d\n", sizeof(p+1));	4/8p的地址+1  还是地址,是地址就是4/8字节printf("%d\n", sizeof(*p));		1printf("%d\n", sizeof(p[0]));	1p[0]-->*(p+0)p本来就是指向首元素的+0等于没加==*p对一级指针取地址运算就是就相当于二级指针printf("%d\n", sizeof(&p));		4/8取出的是字符指针的地址 还是地址,只要是地址就是4/8printf("%d\n", sizeof(&p+1));	4/8地址+1还是地址&+1跳过本地址,指向下一个地址printf("%d\n", sizeof(&p[0]+1));4/8&p[0]+1 指向b的地址	地址就是4/8strlen()printf("%d\n", strlen(p));		6p里面放的是a的地址,传给strlen后计算到\0就停止printf("%d\n", strlen(p+1));	5p+1 首地址+1指向第二个字符b 开始计算就是5printf("%d\n", strlen(*p));		报错p存放a 将p解引用就是得到a,然后就报错printf("%d\n", strlen(p[0]));	报错printf("%d\n", strlen(&p));		随机值&p与abcdef的空间无关什么时候找到\0不知道printf("%d\n", strlen(&p+1));	随机值printf("%d\n", strlen(&p[0]+1));	5&p[0]已经指向a, +1后指向b,然后计算到\0停止return 0;
}

五、二维数组

在内存中是一段连续的空间

int main()
{//二维数组int a[3][4] = {0};&a + 1 跳过整个二维数组 printf("%d\n",sizeof(a));			3x4x4= 48printf("%d\n",sizeof(a[0][0]));		4第一行第一列	printf("%d\n",sizeof(a[0]));		4x4 = 16a[0] = 是第一行这个一维数组的数组名,单独放在sizeof内部,a[0]表示第一个整个这个一维数组sizeof(a[]0)计算的就是第一行的大小printf("%d\n",sizeof(a[0]+1)); 		4/8a[0]并没有单独放在sizeof内部,也没有取地址,a[0]就表示首元素的地址就是第一行这个一维数组的第一个元素的地址,a[0]+1计算第一行第二个元素的地址printf("%d\n",sizeof(*(a[0]+1))); 	4a[0]+1是第一行第二个元素*(a[0]+1)就是第一行第二个元素printf("%d\n",sizeof(a+1));			16a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址a表示首元素的地址,二维数组的首元素是它的第一行,a就是第一行的地址a+1就是跳过第一行,表示第二行的地址printf("%d\n",sizeof(*(a+1)));		16对第二行的地址解引用 就拿到第二行了计算的是第二行*(a+1) -->  a[1]sizeof(*(a+1))--> sizeof(a[1])printf("%d\n",sizeof(&a[0]+1));		16&a[0]-->a[0]在二维数组中表示第一行,取出第一行地址后进行+1拿到第二行的地址printf("%d\n",sizeof(*(&a[0]+1)));	4/8对第二行解引用拿到第二行的地址但只是拿到了地址printf("%d\n",sizeof(*a));			16a首元素地址第一行解引用拿到第一行printf("%d\n",sizeof(a[3]));		16表示第四行的地址sizeof(a[3])进行计算不进行访问return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部