数组和指针的问题

数组指针问题

一、一维数组、二维数组
  • 数组

C语言标准规定 当数组名作为数组定义的标识符或者sizeof的操作数或者&的操作数的时候,数组名才会表示整个数组本身,在其他表达式中,数组名会被转换为指向第0个元素的指针

//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr);
printf("%d\n",&arr);
printf("%d\n",&arr[0]);
//输出为:
11532380
11532380
11532380
//结论:在数组中数组名就是数组中第一个元素的地址。数组名可以看作一个指针。
*************************************************************************************
//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr);
printf("%d\n",arr+1);
printf("%d\n",&arr+1);
printf("%d\n",&arr[0]+1);
//输出为:
5963088
5963092
5963128
5963092
//结论:我们可以看到第三个输出比第一个大了40,所以虽然&arr也是输出数组的首地址,但是&arr表示整个数组,我们给&arr+1会看到它的地址增大40,移动到了数组最后一个元素的后面。而arr+1和&arr[0]+1只是增大4,移动到了数组的第二个元素处。
  • 二维数组
//定义一个二维数组
int arr[2][3]={1,2,3,4,5,6};
printf("%d\n",arr);
printf("%d\n",&arr);
printf("%d\n",arr[0]);
printf("%d\n",&arr[0]);
printf("%d\n",&arr[0][0]);
//输出为:
2227336
2227336
2227336
2227336
2227336
//结论:无论是一维数组还是二维数组还是几维数组,只要是数组,数组名就是数组的首地址。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
printf("%d\n",arr);
printf("%d\n",arr+1);
printf("%d\n",&arr+1);
printf("%d\n",arr[0]+1);
printf("%d\n",&arr[0]+1);
printf("%d\n",&arr[0][0]+1);
//输出为:
12123344
12123356
12123368
12123348  
12123356
12123348
//结论:二维数组中虽然arr、&arr、&arr[0]都是二维数组的首地址,但是其中arr和&arr[0]都代表一整行,&arr代表整个二维数组,arr[0]代表一个int。
二、指向数组元素的指针、数组指针、指针数组
  • 指向数组元素的指针:它指向的是数组中的元素
//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int* p=arr;
int* p1=&arr;
printf("%d \n", p);
printf("%d \n", p1);
printf("%d \n", p+1);
printf("%d \n", p1+1);
//输出为:
19920880
19920880
19920884
19920884
//结论:指向数组的指针,是指向数组的第一个元素的地址,指针移位也是一次移动int的字节数4个。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
int* p=arr;
int* p1=&arr;
int* p2=arr[0];
int* p3=&arr[0];
int* p4=arr[0][0];
printf("%d\n",p);
printf("%d\n",p1);
printf("%d\n",p2);
printf("%d\n",p3);
printf("%d\n",p4);
//输出:
4126964
4126964
4126964
4126964
1
//结论:指针指向二维数组是输出的是二维数组的首地址。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
int* p=arr; //错误的操作,因为arr是一个二级指针,p是一级指针,虽然可以指向,但是会警告
int* p1=&arr; //错误的操作,因为arr是一个二级指针,p1是一级指针,虽然可以指向,但是会警告
int* p2=arr[0]; //正确,p2指向数组的第一行,p2+1也就是arr[0]+1也就是移位一个int大小的字节。
int* p3=&arr[0];//错误的操作,因为arr是一个二级指针,p是一级指针,虽然可以指向,但是会警告
int* p4=&arr[0][0];//正确,指向第一行第一列的元素的地址,p4+1就是移位一个int大小
printf("%d\n",p);
printf("%d\n",p+1);
printf("%d\n",p1+1);
printf("%d\n",p2+1);
printf("%d\n",p3+1);
printf("%d\n",p4+1);
  • 数组指针:它指向的是一个数组。
//定义一个一维数组
int a[5]={1,2,3,4,5};
//定义一个数组指针
int (*p)[5]=a;//错误的赋值方法,p是一个二级指针,a是一个一级指针,所以我们要用一级指针的地址给p赋值
int (*p)[5]=&a;//正确的赋值方法
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
}
int (*p)[3]=arr;//我们可以把arr这个数组看成两个一维数组,a[0]、a[1]这两行,而p就是指向的a[0]这一行,所以p+1,就指向了a[1]这一行。
printf("%d\n",p);
printf("%d\n",p+1);
//输出为:
14547600
14547612
三、数组作为函数的参数传递会被弱化为指针
//深入理解数组作为参数传递进入函数会被弱化为指针
void test(int* arr)
{
    printf("%d\n",sizeof(arr));    
}

void test1(int a[10])
{
    printf("%d\n",sizeof(a));    
}

int main()
{
    int num[10]={1,2,3,4,5,6,7,8,9,10};
    test(num);
    test1(num);
    printf("%d\n",sizeof(num));
    
    return 0;
}

//输出结果:
4
4
40
//结论:数组传进函数中会被弱化为指针,我们可以看到无论形参是指针类型还是数组,我们sizeof他们都是4字节,这是因为指针类型的大小就是4字节。而我们直接sizeof(num)就是整个数组的大小。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值