数组与指针有关内容及相关用算

本文详细介绍了C语言中一维和二维数组的定义及使用,深入探讨了数组与指针之间的相互作用,通过多个实例讲解了sizeof与strlen函数在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一维数组定义:

int arr[10];
int arr[]={1,2,3};

二维数组在内存也是连续存放;二维数组的首元素a[0]表示第一行的数组元素;
指针与数组的相关用算:

例1:

int a[] = { 1, 2, 3, 4 };
printf("%d\n",sizeof(a));           //  4*4=16
printf("%d\n", sizeof(a + 0));      //    4  首元素地址+0还是首元素地址,首元素的字节
printf("%d\n", sizeof(*a));         //    4   *a为首元素,
printf("%d\n", sizeof(a[1]));       //    4  a[1]表示第二个元素
printf("%d\n",sizeof(&a));          //    4     注:&数组名时,数组名表示整个数组,取出的是数组的地址;地址都是4个字节
printf("%d\n", sizeof(*&a));        //    16        取出的是整个数组元素
printf("%d\n", sizeof(&a[0]));      //    4         取出的是第一个元素的地址
printf("%d\n", sizeof(&a[0] + 1));  //    4             取出的是第二个元素的地址

重点:数组名表示整个数组有两种情况,其余情况都代表首元素:

(1):数组名单独放在sizeof内部时,相当于整个数组 ;
(2) :&数组名时,数组名表示整个数组;
例:sizeof(&a):表示数组的地址,而地址为4个字节,其意义体现在(&a+1)意味着跳过整个数组;而sizeof(&a+1)表示跳过整个数组指向数组之后,但其表示地址,值为4;

例2:

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", sizeof(arr));//        6 没有\0,共6个字节,表示整个数组,
printf("%d\n", sizeof(arr + 0));      //    4      表示第一个元素的地址
printf("%d\n", sizeof(*arr));       //        1     表示第一个元素
printf("%d\n", sizeof(arr[1]));     //       1         表示第二个元素的值
printf("%d\n", sizeof(&arr));//        4               表示整个数组的地址
printf("%d\n", sizeof(&arr + 1)); //        4       表示跳过整个数组的地址
printf("%d\n", sizeof(&arr[0] + 1));//    4           表示第二个元素的地址
sizeof 求的是字节数,若有\0,则\0也算字节;

例3:

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", strlen(arr));        //随机值,没有\0,停不下
printf("%d\n", strlen(arr + 0));    //随机值,没有\0,停不下
printf("%d\n", strlen(*arr));       //错误,strlen函数参数为地址,不可为值
printf("%d\n", strlen(arr[1]));     //错误,
printf("%d\n", strlen(&arr));       //随机值X,没有\0,停不下
printf("%d\n", strlen(&arr + 1));   //随机值X-6,没有\0,停不下,
printf("%d\n", strlen(&arr[0] + 1));//随机值X-1
strlen函数应传的是地址,不可为值;strlen求的是长度

例4:

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));            //7有\0,\0在sizeof计算时也为一个字节;
printf("%d\n", sizeof(arr + 0));        //4  arr + 0表示第一个元素的地址
printf("%d\n", sizeof(*arr));           //1  *arr表示第一个元素
printf("%d\n", sizeof(arr[1]));         //1  arr[1]表示第二个元素,类型为char
printf("%d\n", sizeof(&arr));           //4  &arr表示整个数组的地址
printf("%d\n", sizeof(&arr + 1));       //4
printf("%d\n", sizeof(&arr[0] + 1));    //4  &arr[0] + 1表示第二个元素的地址

printf("%d\n", strlen(arr));            //6 有\0,求整个数组的长度
printf("%d\n", strlen(arr + 0));        //6
printf("%d\n", strlen(*arr));           //错误;
printf("%d\n", strlen(arr[1]));         //错误;
printf("%d\n", strlen(&arr));           //6
printf("%d\n", strlen(&arr + 1));       //随机
printf("%d\n", strlen(&arr[0] + 1));    //5 &arr[0] + 1表示第二个元素的地址

例5:

char *p = "abcdef"; 
printf("%d\n", sizeof(p));              //4 有\0,p所指向字符串首元素,表示首元素的地址 
printf("%d\n", sizeof(p + 1));          //4
printf("%d\n", sizeof(*p));             //1
printf("%d\n", sizeof(p[0]));           //1
printf("%d\n", sizeof(&p));             //4
printf("%d\n", sizeof(&p + 1));         //4
printf("%d\n", sizeof(&p[0] + 1));      //4

printf("%d\n", strlen(p));              //6
printf("%d\n", strlen(p + 1));          //5
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));      //5

解析:
printf(“%d\n”, strlen(&p)); //随机
printf(“%d\n”, strlen(&p + 1)); //随机
p指向a,p存放的是a的地址,p的类型为char*,&p取的是p的地址,&p取出的类型为char**,char* *pp二级指针,则strlen(&p)的值为随机,
strlen(&p + 1);&p+1表示跳到指针后面如图,(&p + 1)=1*sizeof(char*)即指针的类型;

这里写图片描述

例6:

int a[3][4] = { 0 };
printf("%d\n", sizeof(a));              //12*4=48   个字节
printf("%d\n", sizeof(a[0][0]));        //4   int型,
printf("%d\n", sizeof(a[0]));           //4*4=16  a[0]表示第一行的数组名,放在sizeof内部表示第一行数组的大小
printf("%d\n", sizeof(a[0] + 1));       //4   a[0]没有单独放在sizeof内部,则要降级变为第一行第一个元素的地址,再+1表示第一行第二个元素的地址;
printf("%d\n", sizeof(*(a[0] + 1)));    //4  *(a[0] + 1))表示第一行第二个元素
printf("%d\n", sizeof(a + 1));          //4   a没有单独放在sizeof内部,则降级表示第一行的地址,再+1表示第二行的地址
printf("%d\n", sizeof(*(a + 1)));       //16  *(a + 1))表示取出第二行的元素
printf("%d\n", sizeof(&a[0] + 1));      //4  a[0]表示第一行数组名,&a[0]表示取出第一行整个数组的地址,再+1表示第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));   //16   &a[0] + 1在sizeof中表示第二行的地址,再*表示第二行的元素
printf("%d\n", sizeof(*a));             //16   a没有单独放在sizeof中,表示第一行数组名,再解引用,表示第一行数组
printf("%d\n", sizeof(a[3]));           //16   a[3]虽然越界,表示第四行数组名,在sizeof为第四行的元素,但由于sizeof内部不参与运算,不去取值,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值