当前位置: 首页 > news >正文

C 语言 第五章 指针(6)

目录

指针与数组

一维数组与指针

数组的指针变量

使用指针访问数组的元素

&数组名

 数组指针 vs 指针数组

数组指针:

指针数组:

指针数组的使用

格式:

举例:

字符串数组的表示

举例1:

方式1:使用二维字符数组

方式2:使用字符指针数组

遍历字符指针数组:


指针与数组



  • 指针运算如果只是对单个变量操作其意义和作用不是很明显,
  • 在前面我们提到指针的很多操作都是和数组有关的,
  • 在一个连续存储空间中能发挥巨大作用,所以在此将指针在数组中的应用作为专题。

一维数组与指针


数组的指针变量


int a[10]={2,4,6,8,10,12,14,16,18,20};
int* p; //定义p为指向整型变量的指针变量
p = &a[0]; //把a[0]元素的地址赋给指针变量p

如下几个写法是等价的:
 

int* p = &a[0];
int* p = a; //a不代表整个数组,所以这里不是将数组a赋给p,而代表数组元素a[0]的首地址。

使用指针访问数组的元素


如果指针变量p的初值为&a[0],则: 

  •  p+i和a+i就是数组元素a[i]的地址。或者说,它们指向a数组序号为i的元素。
  •  (p+i)或 (a+i)是p+i或a+i所指向的数组元素的值,即a[i]的值。

代码示例:

 #include "stdio.h"

void initArr(int arr[], int len) {

// 数组作为参数传递时,在函数内部不能通过数组名计算长度,需要调用时,把长度传递过来

for (int i = 0; i < len; ++i) {

arr[i] = i + 1; //1,2,3,4,5

    }

}

int main() {

//声明一个数组 ,写一个函数,在函数中对数组进行初始化赋值操作

int arr[5]; initArr(arr, 5); //数组在作为参数传递时,数组名降级为首元素的位置

for (int i = 0; i < sizeof(arr)/sizeof(int); ++i) {

printf("%d\t", arr[i]); //1,2,3,4,5 } return 0; }

#include "stdio.h"int main() {// 数组指针变量int arr[5] = {[0]: 1, [1]: 2, [2]: 3, [3]: 4, [4]: 5};// 声明数组指针变量int* p1 = arr; // 数组名,默认是数组中首元素的位置int* p2 = &arr[0]; // 数组中的元素进行访问// 传统做法for (int i = 0; i < sizeof(arr) / sizeof(int); ++i) {printf("%d\t", arr[i]);}// 通过指针操作数组,找最大值int a[5] = {[0]: 33, [1]: 12, [2]: 25, [3]: 9, [4]: 18};int* p = a; int max = a[0];for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {if (max < *(p + i)) {max = *(p + i);}} printf("最大值%d", max);return 0;}

&数组名

int a[5] = {1,2,3,4,5};
printf("%p\n", a);  //000000000034fa50
printf("%p\n", &a); //000000000034fa50

发现,数组名 和 &数组名 打印的地址是一样的。
 
举例:

#include <stdio.h>int main() {
int a[5] = {1,2,3,4,5};
printf("a = %p\n", a);       //000000cade5ff750  a表示a[0]元素的地址
printf("&a= %p\n", &a);     //000000cade5ff750  &a表示a数组的地址
printf("a+1 = %p\n", a + 1); //000000cade5ff754  a + 1:表示a[1]元素的地址
printf("&a+1= %p\n", &a + 1); //000000cade5ff764return 0;
}

注:&a理解为 数组的地址,而不要理解为数组首元素a[0]的地址。

本例中&a数组的地址+1,跳过整个数组的大小,所以&a+1相对于&a的差值是20。
因为地址是16进制的,764 - 750 = 14,16进制的14等于20。
 

 数组指针 vs 指针数组


数组指针:


当指针变量里存放一个数组的首地址时,此指针变量称为指向数组的指针变量,简称数组指针。
数组指针是指针?还是数组?

答案是:指针。
  • 整型指针:int* pint; 能够指向整型数据的指针。
  • 浮点型指针:float* pf; 能够指向浮点型数据的指针。
  • 数组指针:能够指向数组的指针。
     

指针数组:


定义:
数组是用来存放一系列相同类型的数据,当然数组也可以用来存放指针,这种用来存放指针的数组被称为指针数组,它要求存放在数组中指针的数据类型必须一致。

问题:指针数组是指针还是数组?

答案:是数组。是存放指针的数组。

指针数组的使用


格式:
数据类型* 指针数组名[大小];


举例:

int* arr[5];

注:arr是一个数组,有5个元素,每个元素是一个整型指针,需要使用下标来区分。

元素类型

       |  int *  |  arr[0]  |
       |  int *  |  arr[1]  |
arr   |  int *  |  arr[2]  |
       |  int *  |  arr[3]  |
       |  int *  |  arr[4]  |

举例:
int main() {  int a = 1;  int b = 2;  int c = 3;  int d = 4;  int e = 5;  int* pa = &a;  int* pb = &b;  int* pc = &c;  int* pd = &d;  int* pe = &e;  int* arr[] = {pa, pb, pc, pd, pe}; //定义一个int类型的指针数组  for(int i = 0; i < 5; i++){  printf("%d ", *arr[i]);  }  return 0;  
}  

字符串数组的表示


如果一个数组的每个成员都是一个字符串,则构成了字符串数组。

字符串数组有两种表示方式

                          ① 二维字符数组;

                          ② 字符指针数组。
 

举例1:

方式1:使用二维字符数组
char fruit[5][7]={"Apple","orange","Grape","Pear","Peach"};  
char weekdays[7][10] = {  "Monday",  "Tuesday",  "wednesday",  "Thursday",  "Friday",  "Saturday",  "Sunday"  
};  
  • 字符串数组,一共包含7个字符串,所以第一维的长度是7。其中,最长的字符串的长度是10(含结尾的终止符 \0 ),所以第二维的长度统一设为10。
  • 思考:数组的第二维,长度统一定为10,有点浪费空间,因为大多数成员的长度都小于10。解决方法就是把数组的第二维,从字符数组改成字符指针。
     
方式2:使用字符指针数组
char* weekdays[7] = {  "Monday",  "Tuesday",  "wednesday",  "Thursday",  "Friday",  "Saturday",  "Sunday"  
};  

上述字符串数组,其实是一个一维数组,成员是7个字符指针,每个指针指向一个字符串(字符数组)。

遍历字符指针数组:
for (int i = 0; i < 7; i++) {  printf("%s\n", weekdays[i]);  
}

相关文章:

  • 网工_IP协议
  • 【算法基础】冒泡排序算法 - JAVA
  • 【质量管理】现代TRIZ问题识别中的功能分析——组件分析
  • 从零开始讲DDR(9)——AXI 接口MIG 使用(2)
  • 文章五《卷积神经网络(CNN)与图像处理》
  • 第 6 篇:AVL 树与 SB 树:不同维度的平衡探索 (对比项)
  • 【质量管理】现代TRIZ问题识别中的功能分析——相互接触分析
  • 滑动窗口leetcode 209和76
  • PostgreSQL自定义函数
  • 特殊运算符详解:身份运算符、成员运算符与三目运算符
  • Ghost-Downloader-3开源下载软件,使用 Python 构建的跨平台 Fluent-Design AI-boost 多线程下载器
  • 使用mybatis实例类和MySQL表的字段不一致怎么办
  • 文件操作--文件下载读取漏洞
  • Fedora升级Google Chrome出现GPG check FAILED问题解决办法
  • 【Linux】关于虚拟机
  • 【AI提示词】奥卡姆剃刀思维模型专家
  • Semantic Kernel 快速入门
  • 神州趣味地名-基于天地图和LeafLet的趣味地名探索
  • C++ 的 lambda 表达式
  • 自制qrcode二维码生成扫码美化
  • 国铁集团:全国铁路旅客发送量连续3天同比增幅超10%
  • 国内锂矿“双雄”开局业绩PK:从巨亏中崛起,或深陷泥淖谋求多元转型
  • 金科股份:因信披违规,公司及董事长、总裁、财务负责人等收到行政监管措施决定书
  • 戴上XR头盔,五一假期在上海也能体验“登陆月球”
  • 永辉超市回应顾客结算时被“反向抹零”:整改并补偿
  • “网约摩托”在部分县城上线:起步价五六元,专家建议纳入监管