C语言菜鸟学习(数组与指针)

数组与指针

数组名有两个含义:

    1. 代表整个整组
    2. 代表首元素的地址  

数组名看作是指针:首元素的地址 (&数组名[0])

数组元素与普通变量是一样的,数组元素也有自己的地址。

数组元素也有左值和右值,并且数组元素间的地址是相邻的。

数组名可以代表首元素的地址.

a => &a[0], 当数组名a当作指针来用时

数组名是保存第一个元素的地址的指针!!!

例如:

int a[4] = {0};
int*p = &a[2];
*p = 100;
输出 a: 0 0 100 0


int a[4] = {1,2,3,4};
int*p = a;// int *p = &a[0]
*p = 100;
printf("a[0] = %d\n", a[0]);//100

 指针与数组的偏移(区别)

数组基地址编号:X
1. int a[10] = {1,2,3,4,5,6,7,8,9};
    printf("a = %p, a+1 = %p, &a + 1 = %p\n", a, a+1, &a+1);

    a : 看作是指针  &a[0]     地址编号 :X
    a+1 : a看作是指针 &a[0]   地址编号 :X+4

    &a[0] + 1 ==> &a[1]   在原先的基础上 往后挪了1个int  
    ==> typeof(&a[0]) ==> typeof(a[0])* ==>int*

    &a+1: a 代表整个整组   地址编号 :X+40
    &a + 1  ==> 在原先的基础上 往后挪了1个int[10] 
    typeof(&a) ==> typeof(a)* ==>int[10]*

2. int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
    printf("a = %p, a+1 = %p, &a[0] + 1 = %p, &a + 1 = %p\n", a, a+1, &a[0]+1, &a + 1);

    a : 看作是指针   &a[0]   地址编号 :X
    a+1 : a看作是指针  &a[0]+1 ==> &a[1]   地址编号 :X+16

    typeof(&a[0]) ==> typeof(a[0])* ==>int[4]*
    typeof(&a[0]+1) ==>int[4]*

    &a[0]+1 ==> &a[1]    地址编号 :X+16
    &a + 1  : a 代表整个数组  &a+1  加了 1个int[4][3]   地址编号 :X+48 

    typeof(&a)  ==> typeof(a)*==> int[4][3]*   

多维数组与指针

  1. 数组名可以看作是指向第一个元素的指针,并且在数值上为第一个元素的地址。 数组名a, 如果把a当指针  a => &a[0]
  2. C语言所有数组都是一维数组!
int a[3][4];
    a 里面有 3个元素, 每个元素都是一个int[4] 类型的对象
    a 里面有3个数组,分别对应 a[0] a[1] a[2]
    
    a[0],a[1],a[2]  都是该数组的数组名

eg:

int a[3][4];
表达式                    表达式的含义及类型                        表达式的值
a                        数组名                                                首元素的编号  &a[0]
                    1. 看作是指针:首元素的地址 &a[0]        在数值上:&a[0]=>&a[0][0]=>a=>&a
                        typeof(a) ==>typeof(&a[0])                    假设编号:X
                            typeof(a[0])*=>int[4]*
                    2. 代表整个数组
                        typeof(a) => int[4][3]
                             
&a[0]                取第一行的地址                                第一行的地址  &a[0]    
                    取a[0]这个元素的地址                           在数值上:&a[0]=>&a[0][0]=>a=>&a
                    typeof(&a[0])==>typeof(a[0])*               假设编号:X
                                ==> int[4]* (默认代表数组)
                                
                    a[0]:代表整个数组  typeof(a[0])==>int[4]
                    a[0]:看作是指针 &a[0][0],typeof(&a[0][0])==>int*                
                    
a[0]                相当于一个一维数组的数组名                        
                                   &a[0][0]                                          在数值上:&a[0]=>&a[0][0]=>a=>&a
                                                                                              假设编号:X
                    1. a[0]:代表整个数组  typeof(a[0])==>int[4]
                    2. a[0]:看作是指针 &a[0][0],typeof(&a[0][0])==>int*             

&a[0][0]          a[0][0] 这个元素的地址 &a[0][0]                                       
                    typeof(&a[0][0]) ==> int*                在数值上:&a[0]=>&a[0][0]=>a=>&a
                                                                            假设编号:X

a+1                取第二行的地址                                  第一行的地址  &a[1]    
                    取a[1]这个元素的地址                  在数值上:&a[1]=>&a[1][0]=>a+1    
                    a : 看作是指针                              假设编号:X+16
                    a+1 ==> &a[0] + 1
                        ==> &a[1]
                            
&a[1]            

&a+1       a数组整个挪动 int[4][3]个字节之后,

                       一个int[4][3]数组的首地址                                  假设编号:X+48                                                                                                                                      
                typeof(&a+1) ==> int[4][3]*
                
a[1]+2            a[1][2] 这个元素的地址                                &a[1][2]
                a[1] 看作是指针  &a[1][0]                                  数值上: X + 24
                    typeof(&a[1][0]) ==> int*
                a[1] + 2 ==> &a[1][2]
                typeof(a[1]+2) ==> typeof(&a[1][2])
                            ==> int*
                        
*(a+1)+2       a[1][2] 这个元素的地址                                &a[1][2]
             typeof(*(a+1)+2) ==>typeof(&a[1][2])==>int*        数值上: X + 24
                *(a+1)+2
            ==> *(&a[0] + 1) + 2
            ==> *(&a[1])+2
            ==> a[1]+2
            ==> &a[1][0] + 2 ==> &a[1][2]
        
*(a[1]+2)     代表 a[1][2]这个元素                             输出:a[1][2]元素的值
            *(a[1]+2)
            ==> *(&a[1][0] + 2)
            ==> *(&a[1][2])
            ==> a[1][2]


*(*(a+1)+2)   代表 a[1][2]这个元素                             输出:a[1][2]元素的值
            *(*(a+1)+2)
            ==> *(*(&a[0]+1)+2)
            ==> *(*(&a[1])+2)
            ==> *(a[1]+2)
            ==> *(&a[1][0]+2)
            ==> *&a[1][2]
            ==> a[1][2]

 

结论

a[N][M] (0 <= i < N, 0 <= j < M)
​
a+i ==> &a[i]
​
*(a+i) ==> a[i]
*(a+i)+j ==> a[i]+j ==> &a[i][j]
*(*(a+i)+j) ==> a[i][j]
​
a[i] + j ==> &a[i][j]
*((a[i])+j) ==> a[i][j]
​

数组指针和指针数组

数组指针

  • 本质上是一个指针,指向的对象是一个数组

int a[4];
// 定义一个指针变量p,保存a的地址
    typeof(a) *p;
==> int[4] *p = &a;
==> int(*p)[4] = &a;// 此时 p就是一个数组指针
typeof(p) ==> int[4]*
p+1 ==> 加了一个 int[4]
​
    *(*p+1) = 100;
*(a+1) ==> *(&a[0] + 1) ==>*&a[1] ==> a[1]
​
// *p <==> 代表p所指向的对象  *p <===> a
 //(*p)[1] = 100;// ==> a[1] = 100
*p <===> *(p+0) <==> p[0] <==> a
// (*p)[1] = 100;// ==> p[0][1] = 100 ==> a[1] = 100
​
================================
#include <stdio.h>

int main()
{
    int a[4] = {1,2,3,4};
​
    // 定义一个指针变量p,保存a的地址
    //typeof(a) *p = &a;
    int (*p)[4] = &a;// typeof(p) ==> int[4]*
    //(*p)[1] = 100;// 因为p保存的是整个数组a的地址,此时 *p 就是数组名
    //(*p)[1] = 100;// a[1] = 100
    //p[0][1] = 100;// p指向一块空间, 看作数组名, 里面每个元素都是int[4]
    //printf("%d\n", sizeof((*p)+1));//
    //*((*p)+1) = 100;
    *(p[0]+1) = 100;
    //*(*p+1) = 100;
​
    for(int i = 0; i < 4; i++)
        printf("%d ", a[i]);
    printf("\n"); 
​
}
================================
#include <stdio.h>
int main()
{
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
​
    int(*p)[4] = a;// p = &a[0];
​
    //*p <==> *(p+0) <==> a[0] <==> p[0]
​
    printf("%d\n", p[0][0]);
    printf("%d\n", (*(p+2))[2]);//  (*(p+2))[2] ==> (*(&a[2]))[2]  ==> a[2][3]
    printf("%d\n", *(p[1]+2));// *(p[1]+2) ==> *(a[1]+2) ==> *(&a[1][0] + 2) ==> a[1][2]
    printf("%d\n", *(*(p+2)+2)); 
}
​
===========================================
#include <stdio.h>
​
int main()
{
  
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
​
    //定义一个指针变量p,保存a的地址
    int (*p)[3][4] = &a;// int[4][3]*
​
    printf("sizeof(*p) = %ld\n", sizeof(*p));
    printf("sizeof((*p)[0]) = %ld\n", sizeof((*p)[0]));
​
}    

指针数组

  • 本质上是一个数组:里面的元素类型都是指针类型

int a[4] = {1,2,3,4}; 
​
int *p[4];// p 就是一个数组, 数组中有4个int*的元素
​
typeof(p) ==> int*[4]
sizeof(p) ==> 32
    
p[0] = a;// p[0] = &a[0]
*p[0] <==> a[0] 
*p  <==> *&p[0] <==> p[0]
​
**p <==> a[0]

 练习

  • 最后附上一个leedcode上练习的数组题

628. 三个数的最大乘积

给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

示例 1:

输入:nums = [1,2,3]
输出:6

示例 2:

输入:nums = [1,2,3,4]
输出:24

示例 3:

输入:nums = [-1,-2,-3]
输出:-6

提示:

  • 3 <= nums.length <= 104
  • -1000 <= nums[i] <= 1000
int maximumProduct(int* nums, int numsSize) {
    int a,b,c;
    int count=0;
    int mul=1;
    int a_fu=INT_MAX;
    int b_fu=INT_MAX;
    int c_fu=INT_MAX;
    a=b=c=INT_MIN;
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]<0)
        count++;
        if(nums[i]>=a)
        {
            c=b;
            b=a;
            a=nums[i];
        }
        else if(nums[i]>=b&&nums[i]<=a)
        {
            c=b;
            b=nums[i];
        }
        else if(nums[i]>=c&&nums[i]<=b)
        {
             c=nums[i];
        }
    }
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]<0&&nums[i]<=a_fu)
        {
            c_fu==b_fu;
            b_fu=a_fu;
            a_fu=nums[i];
        }
        else if(nums[i]<0&&nums[i]>a_fu&&nums[i]<=b_fu)
        {
            c_fu=b_fu;
            b_fu=nums[i];
        }
        else if(nums[i]<0&&nums[i]>b_fu&&nums[i]<=c_fu)
        c_fu=nums[i];
    }
    if(b_fu!=INT_MAX&&count!=numsSize)
    {
        if(a*a_fu*b_fu>a*b*c)
        mul=a*a_fu*b_fu;
        else mul=a*b*c;
    }
    else
    mul=a*b*c;
    return mul;
}

代码还是有些许的冗长,还有待提升~~~

  • 28
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值