指针就是指针,指针变量在 32位系统下,永远占 4  byte ,其值为某一个内存的地址。指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到。


    数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存任何类型的数据,但不能存函数。

 

    说起指针,就让我们想到数组。而数组和指针也是有区别的。指针,指的是描述一个变量的地址;我们可通过指针的偏移来指向下一个地址。数组,是描述相同元素的一个集合;数组名是常量地址,不可自加不可修改。

 

     我们可以通过数组的下标访问或指针指针阶引用输出常量字符串。如:p[i]  *p+i)。

#include<stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf("%d,%d", *(a + 1), *(ptr - 1));
    system("pause");
    return 0;
}

    分析:

    *(a+1)相当于a[0+1]=a[1]=2


    &a不降级,指的是整个数组,ptr是整个数组再加上1,则指的是a[4]紧接着后面的1个地址。再减去1,则指针又指回去并对其阶引用,相当于a[4],a[4]=5。


#include<stdio.h>
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf("%x,%x", ptr1[-1], *ptr2);
    system("pause");
    return 0;
}

     分析:

    &a不降级,是整个整型数组,+1,是整型数组4后的int大小的地址,ptr[-1]则通过下标方式对刚才的地址减去1后的地址,是4。


    a代表数组首元素的地址,将它强制类型转换为int型,表示的是首元素的内容,为1,2

    

    我根据sizeof分析数组与指针,如:

#include<stdio.h>
int main()
{
    int a[] = { 1, 2, 3, 4 };
    printf("%d\n", sizeof(a));//16
    printf("%d\n", sizeof(a + 0));//4
    printf("%d\n", sizeof(*a));//4
    printf("%d\n", sizeof(a + 1));//4
    printf("%d\n", sizeof(a[1]));//4
    printf("%d\n", sizeof(&a));//4
    printf("%d\n", sizeof(&a + 1));//4
    printf("%d\n", sizeof(&a[0]));//4
    printf("%d\n", sizeof(&a[0] + 1));//4
    system("pause");
    int a[5];
    int *p = &a;//??
    int *q = a;//??
    system("pause");
    return 0;
}

  

     上面是通过数组的下标访问或指针指针阶引用输出常量字符串。


     也许大家这时候会想,为什么只能是常量字符串呢,int型数组我就不可以了吗?这时候我们可以通过一个循环和指针阶引用去输出。

 

    下面我将数组和指针就以下几点详细地区分(常考于笔试面试简答题中):

 

1指针常用于存放变化性的变量,而数组常常用于存放一种类型的不经常变动的数据。

 

2指针变量自身是,指针存放的是数据的地址,而指针变量本身的地址我们无从而知。而数组名代表的事我们常说的数组首元素的地址,而并非是数组的地址。要说是数组的地址的话,那我们就要对其数组名取地址了(不降级)。

 

3访问数据方式:指针常常是间接访问,我们先找到对应的地址,再通过阶引用或数组下标方式访问到数组。而数组可直接通过下标去寻找,即直接访问。

 

     数组指针与指针数,如int *p[10],[]优先级高于*,表示的是数组中的每个元素都是int*类型的。用画图表示的话,它是10int型大小,每个int型中存放的是int*。而int*q[10]表示的是数组指针,归根结底,不管是什么指针,它都是指针,那么它就存放的是地址,只不过数组指针存放的是数组的指针。用画图表示的话,是地址,则是4个字节大小。这个指针指向了10int型大小的数组。

    接着,我想从传参和接收参数的角度分析数组和指针。

    将一个一维数组、 一级指针传参时,可通过对实参做一份拷贝并传递给被调用的函数,无法把指针变量本身传递给一个函数:

my_printarr1len) 

void my_print(int arr[],int len)或者

void my_print(int *arr,int len)

    二维数组

数组首元素传过去,用数组接收。

void my_print(int  arr[][4],int len)

数组的列不能省略。

     一级指针:

  即对p2做一份拷贝,假设其拷贝名为_p2。那传递到函数内部的就是_p2 而并非p2本身。

    二级指针:

int arr*[4];

test(arr);//数组指针的每一个元素都是的首元素传参

int test(int **q)//而数组指针存的是地址,需要用二级指针来存放地址的地址。