指针(2)加速赶来~

嗨~友友们好,我是林林。

接下来是指针(2),不要走开,精彩马上就来~


目录

一、数组名

二、arr和&arr的区别

三、指针访问数组

四、一维数组传参

五、冒泡排序

六、二级指针

七、指针数组

八、指针数组模拟二维数组

九、写在最后 


一、数组名

数组名就是数组首元素(第⼀个元素)的地址。但有两个例外:

(1)sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的大小, 单位是字节;

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    printf("%d\n", sizeof(arr));//注意:结果为40
    return 0;
}

(2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)。

二、arr和&arr的区别

(1)arr表示数组第一个元素的地址,arr+1跳过4个字节(这里以int类型为例);

(2)&arr表示整个数组的地址,&arr+1跳过(4*sz)个字节;(仍以int为例,sz是指数组的长度)。

sz= sizeof(arr) / sizeof(arr[0]);

三、指针访问数组

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    sz = sizeof(arr) / sizeof(arr[0]);
    int* p = arr;//首元素的地址
    //输入
    for(int i = 0 ; i < sz ; i ++)
    {
        scanf("%d",p + i);//p+i表示的是地址
      //scanf("%d",arr + i);//arr地址存入了p中,arr==p
    }
    //输出
    for(int j = 0 ; j < sz; j ++)
    {
        printf("%d ",*(p + j));//*(p+j)表示的是数组元素
      //printf("%d ",arr[j]);//之前学到的用下标访问数组
      //printf("%d ",p[j]);//p == arr
    }
    return 0;
}

因此:p+i == arr+i; *(p+j) == arr[j] == p[j]  (这里很重要!!)

四、一维数组传参

(1)本质上数组传参传递的是数组首元素的地址。因此不能将arr传入数组再计算元素个数。(在函数内部我们写 sizeof(arr) 计算的是⼀个地址的大小(单位字节)而不是数组的大小(单位字节)。正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。)

(2)⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

void test(int arr[])//参数写成数组形式,本质上还是指针
{
    printf("%d\n", sizeof(arr));
}
void test(int* arr)//参数写成指针形式 
{
    printf("%d\n", sizeof(arr));//计算⼀个指针变量的⼤⼩ 
}
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    test(arr);
    return 0;
}

五、冒泡排序

两两相邻元素进行比较

void bubble_sort(int arr[], int sz)//参数接收数组元素个数 
{
    int i = 0;
    for(i=0; i<sz-1; i++)//假设有sz个数,只需要比较sz-1次
    {
        int j = 0;
        for(j=0; j<sz-i-1; j++)
        {
            if(arr[j] > arr[j+1])
            {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;     //交换位置
            }
        }
    }
}

int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    int sz = sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr, sz);
    //依次打印元素
    int i = 0;
    for(i=0; i<sz; i++)
    {
    printf("%d ", arr[i]);
    }
    return 0;
}

 这样减少了不必要的比较:

void bubble_sort(int arr[], int sz)//参数接收数组元素个数 
{
     int i = 0;
     for(i=0; i<sz-1; i++)
     {
     int flag = 1;//假设这⼀趟已经有序了 
     int j = 0;
     for(j=0; j<sz-i-1; j++)
     {
         if(arr[j] > arr[j+1])
         {
             flag = 0;//发⽣交换就说明,无序 
             int tmp = arr[j];
             arr[j] = arr[j+1];
             arr[j+1] = tmp;
         }
     }
     if(flag == 1)//这⼀趟没交换就说明已经有序,后续不用排序了 
     break;
     }
}
int main()
{
     int arr[] = {3,1,7,5,8,9,0,2,4,6};
     int sz = sizeof(arr)/sizeof(arr[0]);
     bubble_sort(arr, sz);
     int i = 0;
     for(i=0; i<sz; i++)
     {
     printf("%d ", arr[i]);
     }
     return 0;
}

六、二级指针

#include <stdio.h>
int main()
{
    int a = 0 ; 
    int * p = &a;
    int * *pp = &p;
    return 0;
}

**pp:*pp 代表指向的是p(指针变量)的地址;**pp 是对二级指针解引用。

一级指针的类型为:int * ;二级指针类型为int **。(这里只是举一个例子,也可能是char* 、char**)

七、指针数组

指针数组就是存放指针(地址)的数组,本质上是数组。指针数组的每个元素是地址,⼜可以指向⼀块区域。

八、指针数组模拟二维数组

#include <stdio.h>
int main()
{
    int arr1[] = {1,2,3,4,5};
    int arr2[] = {2,3,4,5,6};
    int arr3[] = {3,4,5,6,7};
    //数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中 
    int* parr[3] = {arr1, arr2, arr3};
    int i = 0;
    int j = 0;
    for(i=0; i<3; i++)   //共3个数组
    {
        for(j=0; j<5; j++)  //每个数组有5个元素
        {
           printf("%d ", parr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

这里解释一下parr[i][j] :根据前面的总结 parr[i] == *(parr+i)  (得到每一个整形数组) ,parr[i][j] == (*(parr+i))[j]  (每个整形数组的元素)。

上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每一行并非是连续的。

九、写在最后 

友友们~指针开头难,一定要多看多学多总结,相信我们一定可以学会的,加油!!

我是林林,拜拜~

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值