数组和指针

Posted wangweigang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组和指针相关的知识,希望对你有一定的参考价值。

这篇主要说数组和指针,之所以要把它们两放一块说,是因为讲解数组必须要讲到指针,这样就会融会贯通,灵活运用,而不是按部就班,照葫芦画葫芦,因为照葫芦画瓢在你不知道是怎么个回事的情况下,出错很正常,你还不会改,好,进入正题:

数组,就是一堆连续的具有相同类型的内存空间,每个空间都可以存储一个本数组的类型的元素。首先,要想用数组,既然知道它是用来存储数据的,那肯定得要空间,就是得先声明,先问计算机要空间。例如:

int main(void)
{
    int a[3];
    
    return 0;
}

这段代码中就一句语句,int a[3]; 这句语句就是告诉编译器,给我在内存上取一片空间给我用,这片空间是连续的三个int类型的空间,这块空间就归你使用,在使用时要注意,在数组中可以直接用数组名加下标的方式来对数组中的元素进行操作,但是下标都是从0开始,到n-1个一共n个,就像上面的数组,它的三个元素分别用a[0],a[1],a[2]来表示,如果你在程序中用到的下标超过了0到2这个范围,编译时候不会出错,编译器不会检查这种错误,但是运行是就会出错,在linux上的报错就是段错误,段错误的意思就是你使用了未定义的空间,就是使用了不属于你的空间,好,看以下代码

#include<stdio.h>
int main(void)
{
    int a[3],i;
    for(i = 0; i < 3; i++)
        scanf("%d",&a[i]);
    for(i = 0; i < 3; i++)
        printf("%d ",a[i]);
    printf("\\n");

    return 0;
}

处理数组一般都用循环处理,一维数据用一个循环,二维数组用两个循环(下面讲),循环中i从0开始到n-1结束,刚好对应了数组的下标。在第一个循环中,每次循环依次给a[0],a[1],a[2],赋值,他们三就代表了三个变量,所以取地址符&是必不可少的,然后第二个循环是依次输出三个数,读者在试代码时候,输入时每个数字中间以空格隔开,最后用回车结束输入;

数组和指针关系非常密切,对指针不了解的请先看我另一篇文章,指针http://www.cnblogs.com/wangweigang/p/8990237.html

数组在程序中,编译器会将它优化成指针,在你声明了int a[3]; 这个数组时,这个数组名就代表了第一个元素的地址,也就是说,这个数组名就是指向这个数组的第一个元素的指针

#include<stdio.h>
int main(void)
{
    int a[3],i;
    for(i = 0; i < 3; i++)
        scanf("%d",&*(a+i));
    for(i = 0; i < 3; i++)
        printf("%d ",*(a+i));
    printf("\\n");

    return 0;
}

在这个程序中,我把a[i]换成了*(a+i) 编译运行和上面一模一样,没一点毛病,也就验证了我刚才说的,所以说在程序中,可以有很多种表示数组的方法

#include<stdio.h>
int main(void)
{
    int a[3],i;
    int *p = a;
    
    for(i = 0; i < 3; i++)
        scanf("%d",&a[i]);
    for(i = 0; i < 3; i++)
        printf("%d ",a[i]);
    printf("\\n");
    
    a[2] = 10;
    printf("%d\\n",a[2]);
    2[a] = 11;
    printf("%d\\n",2[a]);
    
    p[2] = 4;
    printf("%d\\n",p[2]);
    2[p] = 5;
    printf("%d\\n",2[p]);

    return 0;
}

这个程序也没一点问题,运行结果也是你所想象的那样,可能你这就有些疑问了,你说a[i]和*(a+i)可以互换,我指针p指向了数组a,我当然既可以*(p+2)也可以p[2],这些没问题,但你这2[a],2[p]是什么鬼,不要惊讶,因为我说过,数组这程序中编译器都会换成指针,好那我*(a+2)和*(2+a)没啥区别啊,同样,那我a[2]和2[a]也没啥区别呗,编译器在编译过程中只是把方括号的形式转换成了解地址符*,圆括号和加号而已,所以如果你在看别人程序时候发现了这样的代码 2[a],2[p],0[a]之类的不要惊讶,只能说明写代码的人比较调皮而已。

顺便说一下,由于这个数组的每个元素都是一个int类型的变量,所以指针就定义成指向int变量的指针就行,理解这个会在我另一篇指针和二维数组中对于指向二维数组的指针的声明的剖析有很大的帮助。

那好,到这里你就可能要问了,我数组会用就行了,你给我讲指针干嘛用的,我要是在程序中像上面那样写不是多此一举吗。

这里就牵扯到函数了,在函数传参过程中,数组会变成指针,而且函数只能改变一个变量,即用返回值来赋值给这个变量,你要是想改变多个变量就得用指针,请看这个程序

技术分享图片

技术分享图片

这个程序是老师的一个作业题,要求用三个函数来实现对数组的输入,排序和输出,在这个程序中,你会发现,在输入和排序的时候,在其他函数中改变数组中元素的值,main函数的数组的值也会改变,参照上面我所说的,数组在传参的时候就是指针,然后就利用了指针进行了间接的赋值,所以会改变原函数中数组的值。所以在以后程序中,只要见指针是指向数组的,或者数组是参数的,都可以用两种表示方法来进行操作,习惯哪种就用哪种。

指针和数组先到这里,更多关于指针和数组的会在我的指针和二维数组中给大家详细介绍

原创,转载标明出处,谢谢!!

 

以上是关于数组和指针的主要内容,如果未能解决你的问题,请参考以下文章

如何在汇编函数中将元素数组作为参数传递时转发ARM寄存器的地址指针

20160211.CCPP体系详解(0021天)

更新:C++ 指针片段

片段中的 EditText 上的空指针异常 [重复]

错误代码:错误域 = NSCocoaErrorDomain 代码 = 3840“JSON 文本没有以数组或对象和允许未设置片段的选项开头。”

20160211.CCPP体系详解(0021天)