7.27学习日志——数组指针总结

int a[10] 定义一个整型数组 里面有10个元素
a      数组名,同时也为首元素地址  +1 +4字节
&a      数组地址                      +1 +40字节
&a[0] 数组首元素的地址            +1 +4字节

int a[4][3]
a            数组名,同时也为首行地址    +1 +12
&a            数组地址                    +1 +48
a[0]        首行首元素地址                +1 +4
&a[0]        首行地址                    +1 +12
&a[0][0]    首元素地址                    +1 +4

--------------------------------------------------------------

指针
不管什么类型的指针
sizeof(int *)        四字节
sizeof(char *)        四字节
sizeof(long *)        四字节
sizeof(float *)        四字节

int a = 1;
int *p = &a; 或 p = &a;
p+1 +4字节

指针 + 数组
int a[10] = {1,2,3,4,5,6,7,8,9,10}  数组名a为常指针
int *p = a;
a[i] *(a+1)    *(p+1) 三个是等价的
-----------------------------------------------------------------------
指针数组的定义
指针数组:指针数组可以说成是”指针的数组”
首先这个变量是一个数组,其次,”指针”修饰这个数组,
意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。

char *arr[4] = {"hello", "world", "shannxi", "xian"};
这就相当与定义char *p1 = “hello”,char *p1 = “world”,char *p3 = “shannxi”, char *p4 = “xian”,这是四个指针,每个指针存放一个字符串首地址,然后用arr[4]这个数组分别存放这四个指针,就形成了指针数组。

arr为指针数组的首地址 也是hello的地址
*arr        %s输出的是 hello
*arr + 1     %s输出的是 ello
*(arr + 1)    %s输出的是 world
arr[0]        %s输出的是 hello
arr[1]        %s输出的是 world
所以对于数组指针而言  *(arr + 1)  arr[1] 也是等价的

-------------------------------------------------------
数组指针:数组指针可以说成是”数组的指针”,
首先这个变量是一个指针,其次,”数组”修饰这个指针,
意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。 
int (*pa)[4]; 此时pa的步长为4*4=16个字节 

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4] = a;  //定义一个数组指针 步长为16
a[i][j] ;*(*(p+i)+j);(*(p+i))[j]  //这三个是等价的

-------------------------------------------------------------------------
指针的指针 
如果不通过函数的参数传递的话
    char *ptr = (char *)malloc(sizeof(char) * 64);
就可以了,但是用了的话:
void A(char **str)
{
    *str = (char *)malloc(sizeof(char) * 64);
}
int main()
{
    char *ptr = NULL;
    A(&ptr);
    strcpy(ptr,"hello");
}


那么为什么要用到指针的指针呢?
printf("%s ",ptr)  -->(null)
printf("%s ",*ptr) -->segment fault
printf("%p ",&ptr) -->0xbfd26f00
printf("%p ",ptr)  -->0x8c3b008c
如果A(ptr); 把null传递给了形参 没意义
如果A(&ptr);把地址传给了形参,这时候的地址是指针的地址,而本来指针就是存放内存地址的,所以这时候就是指针的指针,形参要用**p接!!!
----------------------------------------------------------------

int main()
{
    char *str[] = {"hello","world","ni","hao"};
    char **p;
    int i;
    for(i = 0; i < 4; i++)
    {
        p = str + i;      //p是指针的指针,存放的是指针的地址,
                          //str为指针数组存放的就是指针的地址,所以可以赋值
        printf("%s \n",*p);
    }
    return 0;
}

---------------------------------------------------------------
函数指针的定义
void (*p)(); 

int add(int x,int y);
int (*q)(int,int);
q = add;
q(1,2);


总结一下,指针和数组最重要的就是对地址的操作,就是通过指针或者是数组的地址赋值来操作内存中存放的数据!
要分清楚什么时候调用的是地址,什么时候是取值!
‘*’在定义时:表示后面的变量是一个指针
‘*’在使用时:表示取值,即取地址的值


 

猜你喜欢

转载自blog.csdn.net/sinat_39440759/article/details/81254048
今日推荐