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

c语言指针4

文章目录

  • 一、字符指针
    • 1.1字符指针的创建
    • 1.2字符数组的地址和使用
    • 1.3例题分析
  • 二、数组指针
    • 2.1什么是数组指针?
    • 2.2数组指针的初始化
  • 三、二维数组传参的本质


提示:以下是本篇文章正文内容,下面案例可供参考

一、字符指针

在c语言中,我们把存放字符变量的地址的变量,称为字符指针

1.1字符指针的创建

int main()
{char ch = 'c';char* p = &ch;return 0;
}

代码分析
在这里我们创建一个字符型变量ch,存储字符c,取出字符型变量的地址放入变量p中,此时p的类型就是字符型指针变量。

1.2字符数组的地址和使用

int main()
{char arr[] = "abcdef";char* p = arr;return 0;
}

代码分析
在这里我们创建了一个字符数组,数组中存放一个字符串,通过小编前面所讲述的内容,除了&arr和sizeof(arr),其他时候的数组名都代表数组首元素的地址,因为数组在内存中是连续存放的,取出数组首元素的地址也就是取出数组的地址。

通过上面我们是否可以采取下面方法使用呢

char* p = "abcdef";
在这里我们是不是直接将abcdef 赋值给字符指针p,答案是错误的,abcdef也是和数组一样的,它只是把字符a也就是首元素的地址给了字符指针变量p的。与数组相比,它是把字符串的首元素赋值给p。那么两者是否存在不同。接下来我们对他进行解引用打开vs调试一下。

在这里插入图片描述
错误分析
在这里出错的原因是p1中存放的是数组的地址,而p2中存放的则是常量字符串的地址。数组的内容是可变的,而常量字符串的内容是不可变的。因此对p2的解引用是错误的。此外数组创建需要开辟一份空间,这份空间是存储在栈区的,而常量字符串是不可变的,就是因为它是不可变的,所以我们把他放在代码段中,想要用的话直接从代码段中去拿。

1.3例题分析

#include <stdio.h>
int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";const char *str3 = "hello bit.";const char *str4 = "hello bit.";if(str1 ==str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if(str3 ==str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}

在这里插入图片描述
分析
这⾥str3和str4指向的是⼀个同⼀个常量字符串。C/C++会把常量字符串存储到单独的⼀个内存区域,当⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。但是⽤相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。
在这里插入图片描述


二、数组指针

2.1什么是数组指针?

在前面内容我们学习了很多类型的指针,整型指针(存放整型变量的地址),字符指针(存放字符变量的地址)等等,那么什么是数组指针呢?没错数组也有它的地址,存放数组的地址就是数组指针。讲到数组,这里需要区分一下数组指针和指针数组。

定义3个整型数组

int arr1[5] = {1,2,3,4,5};
int arr2[5] = {2,3,4,5,6};
int arr3[5] = {3,4,5,6,7};


指针数组
什么叫指针数组呢?指针数组是一个数组,存放指针的数组

int* arr[3] = {arr1,arr2,arr3};

在这里我们把三个整型的数组名放入arr中,数组名是地址,所以arr数组中的三个元素都是指针,指针变量的类型是int*类型的。所以如上面代码所写,[ ]的优先级高于*的优先级,所以arr先与[ ]结合代表arr是一个数组,数组中有三个元素,元素的类型是int*类型的。

数组指针
数组指针是一个指针,存放数组的地址。

int (*p)[5] = &arr1;

在这里我们把整个数组的地址取出来,地址是指针,指针指向的是一个数组,数组元素有5个,元素的类型是int,所以先将p与*结合括起来,代表p是一个指针,然后p再与[ ]结合说明指针变量p指向的是一个数组,里面的5表示指向的这个数组有5个元素,int表示指向的数组内的元素是int类型。

2.2数组指针的初始化

数组指针变量就是存放数组的地址,那么给数组指针进行赋值,那么就要给出数组的地址,数组的地址怎么求呢?也就是我们前面所写的 &数组名。

int arr[10] = {0};
&arr;//得到的就是数组的地址

如果需要存放整个数组的地址,那么就需要将它存入数组指针当中

int(*p)[10] = &arr;

三、二维数组传参的本质

在过去我们学习二维数组进行传参的时候是直接写数组形式的

在这里插入图片描述

那么二维数组传参是否可以写成其他形式的呢?在二维数组中,我们讲到过二维数组由许多个一维数组组成,也就是说二维数组可以看成每个元素是一维数组的数组。所以二维数组首元素就是第一行,也就是一个一维数组。根据数组名就是数组首元素的地址,所以二维数组的数组名就是第一行的地址,因为第一行是一维数组,所以二维数组首元素地址的类型是数组指针,所以二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址。

二维数组传参写成指针的形式

#include <stdio.h>
void print(int (*p)[5], int x, int y)
{int i = 0;for (i = 0; i < x; i++){int j = 0;for (j = 0; j < y; j++){printf("%d ",*((*p+i)+j));}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };print(arr, 3, 5);return 0;
}

代码分析
在这里二维数组传参也就是把第一行数组传参进去,也就是一维数组的地址,数组元素类型是int,元素个数有5个,所以传参进行接收的形参类型是int (p)[5],后面((*p+i)+j)解读是:&和*是可以相互抵消的,p就是&arr的地址,*p则就是arr数组名也就是数组首元素的地址,arr数组首元素就是一维数组,所以通过解引用p+i可以访问1到3行的地址,再通过下标访问1到3行内的元素。


http://www.mrgr.cn/news/28933.html

相关文章:

  • 使用python-Spark使用的场景案例具体代码分析
  • golang使用etcd版本问题
  • 【菜笔cf刷题日常-1400】C. RationalLee(贪心)
  • PICO+Unity MR空间锚点
  • 大数据相关技术的基本概念?
  • 模型压缩概览
  • (十五)、把自己的镜像推送到 DockerHub
  • UE(C++API)
  • [Redis] Redis中的set和zset类型
  • Oracle 19c异常恢复—ORA-01209/ORA-65088---惜分飞
  • 代码随想录:动态规划4-5
  • 安徽省建设工程企业资质管理新动向
  • 阿里OSS对象存储服务,实现图片上传回显
  • 2019-2023(CSP-J)选择题真题解析
  • 【Android】使用Room数据库解决本地持久化
  • 每日一题——第九十八题
  • 【 html+css 绚丽Loading 】000051 方寸轮回矩
  • java138-异常处理_java 138错误
  • 2022高教社杯全国大学生数学建模竞赛C题 问题二(1) Python代码
  • 2022高教社杯全国大学生数学建模竞赛C题 问题一(1) Python代码
  • linux 操作系统下的 declare 命令介绍和使用案例
  • 【零散技术】详解Odoo17邮件发送(一)
  • 【乐企】基础版本开票代码接口声明
  • 【Git】将本地项目上传到git | 在IDEA的提交记录中更改 提交的用户名
  • vue MVC设计模式与MVVM设计模式
  • 牛客周赛 Round 60(下)