一维数组与指针-加深对指针与数组的理解

前言

看前须知:
编译器为 vs2022
电脑为 64位
故:指针大小为 8字节

一维数组

整形数组

int main(void)
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16 
	printf("%d\n", sizeof(a+0));//8 指针
	printf("%d\n", sizeof(*a));//4 元素
	printf("%d\n", sizeof(a+1));//8 指针
	printf("%d\n", sizeof(a[1]));//4 元素
	printf("%d\n", sizeof(&a));//8 指针
	printf("%d\n", sizeof(*&a));//16 整个数组大小 int(*P)[4] = &a
	printf("%d\n", sizeof(&a+1));//8 指针,其地址是4后面空间的地址
	printf("%d\n", sizeof(&a[0]));//8
	printf("%d\n", sizeof(&a[0]+1));//8
	return 0;
}

解析

  1. sizeof( ) 括号内单独放数组名,表示整个数组,故大小为 4(int) * 4(元素个数)=16
  2. 数组名(a)没单独放在sizeof的括号里,则数组名表示首元素的地址,a+0 相当于指针+整数 ,类型为指针,为8字节
  3. *a 同上,这里a为首元素的地址,解引用为首元素 1 ,1是int类型,4字节
  4. a+1同第二个解释
  5. a[1] <==> *(a + 1)
  6. &a 表示取出整个数组的地址,为指针,8字节
  7. *&a 为整个数组,16字节
  8. &a + 1 ,&a表示取出整个数组的地址,&a+1为指针+整数,+1表示跳过整个数组,如图
    在这里插入图片描述

字符数组

1

int main(void)
{
	char arr[] = { 'a','b','c','d','e','f'};
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//8
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//8
	printf("%d\n", sizeof(&arr + 1));//8  +1跳整个数组
	printf("%d\n", sizeof(&arr[0] + 1));//8
	printf("%d", sizeof(arr[0]+1));//4
	return 0;
}

解释:

1 - 7:与整型数组的解释差不多
8. 一个表达式具有两种属性:值属性,类型属性
sizeof() 的括号内部仅体现表达式的类型属性,即不进行运算,仅推测其结果的类型
所以:arr[0]+1,arr[0]属于char,1属于int,若计算则须整型提升为int类型,可推测表达式结果为int类型,为4字节


2

int main(void)
{
    char arr[] = { 'a','b','c','d','e','f'};
    printf("%d\n", strlen(arr));//随机    strlen需要传地址 int my_strlen(const char* str)
	printf("%d\n", strlen(arr+0));//随机
	printf("%d\n", strlen(*arr));//err *arr = a,把a的ASCII码值传过去 97 不是个合法的地址
	printf("%d\n", strlen(arr[1]));//err 不是地址为错误
	printf("%d\n", strlen(&arr));//随机 char (*)[6] = &arr即使传过去的是数组的地址,对于strlen依然当作为数组首元素的地址
	printf("%d\n", strlen(&arr+1));//随机 与上一个随机值差6
	printf("%d\n", strlen(&arr[0]+1));//随机 与上上个差1

  return 0;
}
解释:

strlen函数 int strlen (const char* p) 需要传地址过去 ,从传过去的地址开始往后直达遇到 \0 (0)
对于 char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’}; 数组只存有 该6个元素 无\0,故其会一直数到数组之外 直到遇到 \0 (0)
而由于不知道数组外存储的是什么,故无法得出准确值
3. a的ASKCII码值为97 为十六进制的61在这里插入图片描述


3

char arr[] = “abcdef”; 数组有 7个元素 如下

char arr[] = "abcdef"; // 相当于 [a b c d e f \0]
	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//8
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//8
	printf("%d\n", sizeof(&arr + 1));//8 +1跳一个数组 7字节
	printf("%d\n", sizeof(&arr[0] + 1));//8 - 指向b
	printf("%d", sizeof(arr[0] + 1));//4

	printf("%d\n", strlen(arr));//6   
	printf("%d\n", strlen(arr + 0));//6
	printf("%d\n", strlen(*arr));//err *arr = a,把a的ASCII码值传过去 97 不是个合法的地址
	printf("%d\n", strlen(arr[1]));//err
	printf("%d\n", strlen(&arr));//6 char (*)[6] = &arr即使传过去的是数组的地址,对于strlen依然认为是数组首元素的地址
	printf("%d\n", strlen(&arr + 1));//随机
	printf("%d\n", strlen(&arr[0] + 1));//5

4

char* p = "abcdef";
	printf("%d\n", sizeof(p));//8 指针
	printf("%d\n", sizeof(p + 1));//8  指针
	printf("%d\n", sizeof(*p));//1 *p = a 为char类型 1字节
	printf("%d\n", sizeof(p[0]));//1 p[0] <==> *(p+0)---------------------------$
	printf("%d\n", sizeof(&p));//8 二级指针
	printf("%d\n", sizeof(&p + 1));//8 二级指针 指向p后面
	printf("%d\n", sizeof(&p[0]+1));//8 b的地址

	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5
	printf("%d\n", strlen(*p));//err
	printf("%d\n", strlen(p[0]));//err
	printf("%d\n", strlen(&p));//随机
	printf("%d\n", strlen(&p + 1));//随机 与上面的随机值的关系无从得知,p的地址不知道是什么
	//可能P的地址中有0 ,导致函数停止
	printf("%d\n", strlen(&p[0] + 1));//5
解释

注:char *p = “abcdef”; 可看作 char arr[] = “abcdef”; char *p = arr;
p[0] < == > *(p+0) < == > 0[p]
在这里插入图片描述


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值