首页 > 其他分享 >C语言零基础入门-指针-04

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

时间:2022-10-18 16:00:23浏览次数:50  
标签:04 int 元素 C语言 地址 数组 printf 指针

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字节啊)

存储如下图:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数组_02

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

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("%d\n",*p);
printf("%d\n",*p2);

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

01.2.2 栗子

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

分析:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_二维数组_04

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

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

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数据_06

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



#include<stdio.h>

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

int *p = a;

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

}

运行结果:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_二维数组_08

程序解释:

  • 数组元素我们换成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}
};

在内存中的存储如下图:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数据_10

需要注意的是:

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

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("%d\n",*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("%d\n",*p);
printf("%d\n",*(p+3));
printf("%d\n",*(p+11));

}

结果:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数据_12

分析:

  • 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) );
}
}

结果:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数据_14

分析:

  • 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) );
}
}

结果:

C语言零基础入门-指针-04_二维数组

C语言零基础入门-指针-04_数组_16

分析:

  • 因为二维数组在内存中也是像一维数组那样每个元素按行顺序排放,所以,每次 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. 结束

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

C语言零基础入门-指针-04_数据_17


标签:04,int,元素,C语言,地址,数组,printf,指针
From: https://blog.51cto.com/xiaoxiaojieya/5766921

相关文章