c语言怎么换行_C语言零基础入门-指针-04

d989cde61cb849dd5a224884da862636.png

C语言零基础入门-指针-04

本节要点:
1,指向一维数组的指针。
2,指向二维数组的指针。
3,指针的输出练习。

01. 指向一维数组的指针

有意思的来了,指针指向数组的情况非常常见,同样也是一个难点。

接下来我将从一个简单的栗子来说明指针指向数组时的内存情况。

01.1 数组存储的回顾。

当我们定义如下的一维数组的时候:

int a[5] = {1,2,3,4,5};

计算机会在地址空间中寻找连续的,可以存放下长度为5的,整形变量。也就是需要找一块连续的内存,这块内存长度为:5*4=20字节。

(为什么是20字节?因为这个数组有5个元素,每个元素都是int类型,int类型占4字节啊)

存储如下图:

4126d88032d584e0e7a95fabd30706d0.png

在讲数组之前,上面的需要多少多少的内存空间都是理论推理出来的,现在学过指针之后,我们就可以使用指针来验证一下了。

01.2 利用指针说明数组的内存空间

01.2.1 知识点

开始之前大家要知道一个小知识点:我们之前使用数组作为实参传递数据的时候,我说过可以直接把数组名字作为实参就可以了。

其实数组名还有一个重要的含义,就是:数组名其实就是这个数组存储空间的首地址。

所以,之前我们传递参数的时候,其实就是把数组的首地址传递给子函数了,当时没说指针,因此就没细说。

下边了验证一下。

验证程序:

#include<stdio.h>

void main(){
    int a[5] = {1,2,3,4,5};

    int *p = a;

    printf("%d",*p);

}
  • 这一段代码执行结束发现会输出数组中的第一个元素 1。
  • 所以说,数组名就是整个数组的起始地址。
  • 因此当把a的地址给指针p的时候,a前边不用加取地址符&。

另一种获取数组地址方法:

这种方法被叫做通用方法

#include<stdio.h>

void main(){
    int a[5] = {1,2,3,4,5};

    int *p = &a[0];
    int *p2 = &a[3];

    printf("%dn",*p);
    printf("%dn",*p2);

}
  • 这里如果指定获取某一个元素的地址的时候,就需要在前边加上取地址符号&了。(因为数组名代表数组首地址是一个特殊的定义)

01.2.2 栗子

刚才我们已经学会获取到数组的首元素指针了,接下来,我将会教大家怎么使用首元素指针来遍历到数组的全部元素。

分析:

e9eb1e2ded63340c9fddc04250545aa8.png
  • 目前,指针p指向的就是数组第一个元素的地址。

然后在数组中想让指针往后移动一个元素的地址很简单,只用 p+1就可以了,如下图:

3d6bb4d3c9ce75a272f0f4c477cafa5b.png

用程序验证一下:(这里的数组元素换了)

#include<stdio.h>

void main(){
    int a[5] = {5,4,3,2,1};

    int *p = a;

    printf("%d,%d,%d,%d,%dn", *p,*(p+1),*(p+2),*(p+3),*(p+4));

}

运行结果:

0939a40c78a1f59215444cc346248401.png

程序解释:

  • 数组元素我们换成5,4,3,2,1了。
  • 首先p指向数组a的首地址,*p获得p指向的地址中的数据。
  • 于是 p+1 就是把数组指针向后移动至第二个数据的地址。
  • 在使用 *(p+1) 获得p+1所指向的地址中的数据,第二个数据是4。

02. 指向二维数组的指针

02.1 二维数组内存分配

当我们定义了如下的二维数组之后:

int a[4][3] = {
        {9,6,3},
        {8,5,2},
        {7,4,1},
        {7,5,3}
    };

在内存中的存储如下图:

96e58b189a943133c49cebd4f7afb65b.png

需要注意的是:

  • 二维数组在内存中存储的时候,是把二维数组按行拆开,然后每一行顺序,依次的存储在计算机中的连续位置。

02.2 二维指针的定义

这里的定义就与一维数组有些不一样了。这个时候不能用数组名代表数组的初始地址了。所以我们可以用与前边一维数组定义相同的通用方法。

#include<stdio.h>

void main(){
    int a[4][3] = {
        {9,6,3},
        {8,5,2},
        {7,4,1},
        {7,5,3}
    };

    int *p = &a[0][0];

    printf("%dn",*p);
}
  • 这里p指向了二维数组的第一个元素9。
  • 此时输出的就是第一个元素9。

02.3 二维数组遍历

  • 在一维数组的遍历中,我们可以将指向首地址的指针p每次+1,就可以指向数组中的每一个元素了。

但是有人说,二维数组有行与列两个维度,要怎么处理啊?我们细看二维数组的存储图,你会发现:

管他几维的数组,其实在内存中存储的时候都只有一个维度,那就是把多维数组按行拆开后,依次顺序存放在计算机啊。

  • 所以:二维数组也可以用+1的方式,遍历所有元素。

栗子:

#include<stdio.h>

void main(){
    int a[4][3] = {
        {9,6,3},
        {8,5,2},
        {7,4,1},
        {7,5,3}
    };
    int *p = &a[0][0];

    printf("%dn",*p);
    printf("%dn",*(p+3));
    printf("%dn",*(p+11));

}

结果:

fd90452ec77ffc14a69552f4c7ab0949.png

分析:

  • p是指向第一个元素的,*p获得第一个元素 9。
  • p+3就是把地址指针向后移动3个,然后就指到数据8所对应的地址上了。
  • p+11就是把地址指针向后移动11个,然后就指到数据3所对应的地址上了。

03. 指针的输出练习

03.1 一维数组的输出练习

#include<stdio.h>

void main(){
    int a[9] = {2,3,4,5,6,7,8,9,0};

    int *p = &a[0];

    for(int i=0;i<9;i++){
        printf("%d ", *(p+i) );
    }
}

结果:

8f747614ada29acff9a589e2dbfc602b.png

分析:

  • p指向数组a的第一个元素的地址,也就是首地址。
  • 然后p每次都+i,表示地址p每次向后移动的数据位数。

03.2 二维数组的输出练习

#include<stdio.h>

void main(){
    int a[4][3] = {
        {9,6,3},
        {8,5,2},
        {7,4,1},
        {7,5,3}
    };
    int *p = &a[0][0];

    for(int i=0;i<12;i++){
        printf("%d ", *(p +i) );
    }
}

结果:

88ec489a1a4d9f888b8e7be7c3e1428d.png

分析:

  • 因为二维数组在内存中也是像一维数组那样每个元素按行顺序排放,所以,每次 p往后移动一个数据的位置,就可以遍历所有的元素了。

有人说,为什么没有换行啊?

  • 数据都得到了,换行还会困难吗?

03.2.1 加入换行

我们只需要每输出三个数据,就换一个行不就完了嘛。

#include<stdio.h>

void main(){
    int a[4][3] = {
        {9,6,3},
        {8,5,2},
        {7,4,1},
        {7,5,3}
    };
    int *p = &a[0][0];

    for(int i=0;i<12;i++){
        printf("%d ", *(p +i) );
        if((i+1)%3 ==0){
            printf("n");
        }
    }
}
  • (i+1)%3 ==0的时候,就是意味着输出了三个元素了,所以要输出一下换行符。
  • 为什么要这样写自己去分析,因为已经很简单的。(我甚至连换行的程序都不想写的,想让大家自己写出来的。)

04. 结束

大致还有一次课,就会讲完指针了。

8be6ba0662fe959c56e96915e277c9ae.gif
公众号:小小猿笔记
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值