指针和数组题目

/int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16
    此时a为数组名,当数组名直接放在sizeof内部时,sizeof(数组名)表示的时数组的大小
	printf("%d\n", sizeof(a + 0));//4/8 个字节
	a虽然为数组名,但a+0放在sizeof中,并不相当于sizeof(数组名),此时a表示&a[0],a+0表示&a[0]为一个指向数组首元素的指针,大小为48字节
	printf("%d\n", sizeof(*a));//4
	a是数组首元素的地址 - &a[0]
	*a -> *&a[0] -> a[0],大小为4个字节
	printf("%d\n", sizeof(a + 1));//4/8
	a为数组首元素的地址&a[0] a+1即为&a[1],为指向数组第二个元素的指针,大小为48个字节
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4/8
	&a取出的是a这个数组的地址,也就是一个数组指针,无论什么指针,指针的大小总为48个字节
	int(*p)[4]=&a;
	
	printf("%d\n", sizeof(*&a));//16
	*&相互抵消,结果即为sizeof(a),即sizeof(数组名),大小为16
	printf("%d\n", sizeof(&a + 1));//4/8
	&a取出的是数组的地址,+1指向下一个数组,是数组指针,只要是指针,大小即为48个字节

	printf("%d\n", sizeof(&a[0]));// 4/8
	取出首元素的地址,即为一个指针大小为48
	printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址
    &a[0]+1即为&a[1],即指向第二个元素的指针,大小为48
	return 0;
}
int main()
{
	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };
	注意,这种情况时数组就只有abcdef这六个字符,没有其它字符,并没有\0
	printf("%d\n", sizeof(arr));//6.sizeof计算的是占用内存的大小,单位是字节,并不关注内存中到底存放的是什么
	②.sizeof不是函数,是操作符
	③.strlen是针对字符串的,求的是字符串的长度,本质上统计的是'\0'之前出现的字符个数
	这里arr这个字符数组直接放入sizeof中,求得就是它的大小为6个字节
    printf("%d\n", sizeof(arr + 0));//arr+0是数组首元素的地址 4/8
    arr+0等同于&arr[0]+0即为&arr[0]即为一个指针指向字符数组的首元素,只要是指针大小就为48个字节
    printf("%d\n", sizeof(*arr));//1
    arr是&arr[0] *arr[0]就是arr[0]sizeof(arr[0])求的就是字符数组首元素的大小,为1个字节
    printf("%d\n", sizeof(arr[1]));//1
    字符数组第二个元素的大小,就是一个字节
    printf("%d\n", sizeof(&arr));//4或8
    &arr是一个指针,存放的是数组的地址
    char(*p)[6]=&arr;
    只要是指针无论大小均为48个字节
    printf("%d\n", sizeof(&arr + 1));
    &arr + 1跳过一个数组后的地址,4/8
    printf("%d\n", sizeof(&arr[0] + 1));//4/8 
    &arr[0]+1即为&arr[1]

	printf("%d\n", strlen(arr));//随机值
	strlen传入的参数是一个地址,该函数的作用是统计这个地址之后到'\0'的字符个数
	在sizeof(数组名)中,计算的是整个数组的大小,而在strlen(数组名)中,数组名则代表着首元素的地址传入strlen
	由于以这种方式定义字符数组的结尾并非\0,因为不知道\0的位置,故不知道从数组首元素到'\0'有几个字符,所以结果为随机值
	printf("%d\n", strlen(arr + 0));//随机值
	与上题相同,arr+0还是&arr[0],所以结果仍为随机值
    printf("%d\n", strlen(*arr));//非法访问
    strlen的参数要是一个地址,但*arr的结果是*&arr[0]即为arr[0],也就是把'a'当做地址传入了,其的ASCII码值为97,故为非法访问
    printf("%d\n", strlen(arr[1]));//非法访问
    arr[1]的结果是字符'b',ASCII码值即为98,所以会把这个98当做地址来传入了,会造成非法访问
    printf("%d\n", strlen(&arr));//随机值
    其实传入&arr[0],传入&arr传入的都是同一个地址,故效果是一样的,都是随机值
    printf("%d\n", strlen(&arr + 1));//随机值-6
    &arr+1跳过的是6个字符,即跳过6个字节,所以会比传入&arr造成的随机值少6个字节
    printf("%d\n", strlen(&arr[0] + 1));//随机值-1
    &arr[0]+1跳过的是1个字节,所以会比传入&arr的随机值少1个字节
    


	return 0;
}
3.char arr[] = "abcdef";char arr1[] = { 'a','b','c','d','e','f' }不同,其最后有'\0',相当于char arr1[] = { 'a','b','c','d','e','f''\0' };
	printf("%d\n", strlen(arr));//6strlen(数组名)中,数组名就代表数组首元素的地址
	printf("%d\n", strlen(arr + 0));//6
	arr+0实际上就是&arr[0],与上一题相同
	printf("%d\n", strlen(*arr));//err
	在strlen中,arr可一视同仁为数组首元素地址&arr[0],故*arr即为*&arr[0]即为arr[0],把arr[0]'a'的ASCII码值当做地址传入会造成非法访问
	printf("%d\n", strlen(arr[1]));//err
	与上一题相同,把ASCII码值当做地址非法传入
	printf("%d\n", strlen(&arr));
	&arr即为数组地址,而数组地址与数组首元素地址是相同的
	printf("%d\n", strlen(&arr + 1));
	&arr是一个数组指针 char(*)[],指向的是一个数组,其+1跳过的是一个数组的大小,因不知道下一个\0在哪,故结果为随机值
	printf("%d\n", strlen(&arr[0] + 1));
	&arr[0]+1即为&arr[1],所以从&arr[1]'\0'共·5个元素

	printf("%d\n", sizeof(arr));//7
	因为数组内加上'0'有七个元素,故大小为7sizeof只关心数组的大小)
	printf("%d\n", sizeof(arr + 0));//4/8
	arr+0即为&arr[0]是一个指针大小为48个字节
	printf("%d\n", sizeof(*arr));// 1
	*arr即为*&arr[0]*arr就是数组首元素
	arr[0]   *(arr+0)
	int sz = sizeof(arr)/sizeof(*arr);
	int sz = sizeof(arr)/sizeof(arr[0]);
	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
	return 0;
```4.

```c
char* p = "abcdef";

printf("%d\n", strlen(p));//6
因为p存放的是字符串变量首元素的地址,从字符串首元素的地址到'\0'6个字符
printf("%d\n", strlen(p + 1));/ 5
p+1跳过一个char类型,故p+1存放的是'b'的地址
printf("%d\n", strlen(*p));//err
*p的结果是'a',将'a'的ASCII码值传入,即把97当做地址传入,形成非法访问
printf("%d\n", strlen(p[0]));//err
p[0]*(p+0) 即传入字符'a'与上一题相同,形成非法访问
printf("%d\n", strlen(&p));//随机值
![在这里插入图片描述](https://img-blog.csdnimg.cn/cd76ecee84004fbeace942153178c3f9.png)



printf("%d\n", strlen(&p + 1));//随机值
这个随机值与上一题的随机值并无关系,因为从&p到&p+1中可能存在'\0',结果不可预知
printf("%d\n", strlen(&p[0] + 1));//5
&p[0]+1即为&p[1],结果为5


printf("%d\n", sizeof(p));//4 / 8
p就是一个指针变量,它指向一个字符串常量,将字符串变量首元素的地址放入p中,故p的类型为字符指针
printf("%d\n", sizeof(p + 1));//'b'的地址,4/8
p是一个字符指针,对其+1跳过一个字符的大小,不过p+1还是指针,大小为48
printf("%d\n", sizeof(*p));//1
*p即对p解引用,得到的是'a'的大小即为1个字节
printf("%d\n", sizeof(p[0]));//*(p+0)--'a' 1
p[0]即为 *(p+0)即为'a'
printf("%d\n", sizeof(&p));//4或8
&p即为p的地址,大小为48,不过要注意p的地址跟这个字符串常量已经没关系了
因为p是一个指针,所以&p是个二级指针 char**a=&p;
printf("%d\n", sizeof(&p + 1));
&p跳过一个char*的大小,不过其还是指针,故大小还是48个字节
printf("%d\n", sizeof(&p[0] + 1));
&p[0]+1即为&p[1]即为&*(p+1)即为p+1是一个指向字符'b'的指针,还是一个指针,故大小为48
4.  int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	printf("%d\n", sizeof(a));//48 
    a这个二维数组的数组名单独放在sizeof内部,计算整个数组的大小
	printf("%d\n", sizeof(a[0][0]));//4
	第一行第一个元素,大小为4个字节
	printf("%d\n", sizeof(a[0]));//16
	**a[0] 第一行的数组名**,这时数组名单独放在sizeof内部了
	计算的是数组的大小,单位是字节,16
	printf("%d\n", sizeof(a[0] + 1));//4或8
	a[0]虽然是数组名,但不是直接放在sizeof中的,a[0]+1等于&a[0][0]+1即为&a[0][1];
	&a[0][1]是个指针指向第一行第二个元素
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	结果为a[0][1]
	printf("%d\n", sizeof(a + 1));//4或8
	a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
    二维数组的首元素是第一行,这里的a就是第一行的地址---  int (*)[4]
    a+1即为 &a[0]+1即为 &a[1],即为第一行的地址,它其实是数组指针

	printf("%d\n", sizeof(*(a + 1)));//16
	*(a+1)-->a[1]
	sizeof(a[1])a[1]是二维数组中的一维数组数组名,求得的是a[1]的大小
	printf("%d\n", sizeof(&a[0] + 1));//4或8
     &a[0]+1 即为&a[1]
	printf("%d\n", sizeof(*(&a[0] + 1)));//16  a[1]
	&a[0]+1即为&a[1]*&a[1]即为a[1]
	printf("%d\n", sizeof(*a));//16 *a - 就是第一行
    *a即为*&a[0]即为a[0]
	printf("%d\n", sizeof(a[3]));//16
	
int a = 5;
short s = 11;
printf("%d\n", sizeof(s = a + 2));//2
printf("%d\n", s);//11

test.c-编译-链接-test.exe
sizeof中的表达式根本不会运算,故sizeof(s=a+2)根本不会运算,后面打印的s不会是a+2
由于s的类型就是short类型,故sizeof(short)就是2了,不会计算里面的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值