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

【C语言】善于利用指针(二)

💗个人主页💗
⭐个人专栏——C语言初步学习⭐
💫点击关注🤩一起学习C语言💯💫

目录

  • 导读:
  • 1. 字符指针
    • 1.1 字符串的引用方式
    • 1.2 有趣的面试题
  • 2. 数组指针
    • 2.1 一维数组指针的定义
    • 2.2 一维数组指针的使用
    • 2.3 二维数组指针的地址
    • 2.4 二维数组指针的使用

导读:

前面我们学习了善于利用指针一,主要讲解了指针的定义、基本用法和一些简单的运算使用,算是指针的初步学习了。
今天我们来学习指针的进阶。
后面还有第三部分的讲解,点击关注,掌握第一信息

1. 字符指针

在前面学习指针的类型中,我们知道有一种指针类型为字符指针char*
一般使用:

int main()
{
	char ch = 'w';
	char* pc = &ch;
	*pc = 'w';
	return 0;
}

1.1 字符串的引用方式

在C程序中,字符串是存放在字符数组中的。我们可以用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。

int main()
{
	char* pstr = "I love China!";
	//这里是把一个字符串放到pstr指针变量里了吗?
	printf("%s\n", pstr);
	return 0;
}

运行结果
特别容易让同学以为是把字符串 I love China! 放到字符指针pstr 里了,但是本质是把字符串 I love China! 首字符的地址放到了pstr中。
在这里插入图片描述
注意:

char * pstr = "I love China!";

等价于

char * pstr;//定义一个char*型变量
pstr = "I love China!";
//把字符串第一个元素的地址赋给字符指针变量pstr

1.2 有趣的面试题

int main()
{
	char str1[] = "hello world.";
	char str2[] = "hello world.";
	const char* str3 = "hello world.";
	const char* str4 = "hello world.";
	if (str1 == str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");
	if (str3 == str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");
	return 0;
}

我们来看输出结果并思考是为什么
在这里插入图片描述
我们进入调试看一下:
在这里插入图片描述

  • 这里str3和str4指向的是一个同一个常量字符串。
  • C/C++会把常量字符串存储到单独的一个内存区域。
  • 当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。
  • 但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
  • 所以str1和str2不同,str3和str4不同。

2. 数组指针

我们在之前提到了数组指针,今天我们再进一步的了解数组指针的使用

2.1 一维数组指针的定义

数组指针:能够指向数组的指针。
数组指针的定义方式与指针的定义方式类似,只不过需要在变量名字之前添加一个数组类型的修饰符。

  int *p1[10];//一维数组指针
  int (*p2)[10];//二维数组指针

p2先和*结合,说明p2是一个指针变量,然后指向的是一个大小为10个整型的数组。所以p2是一个指针,指向一个数组,叫数组指针。

这里要注意:[]的优先级要高于 * 号的,所以必须加上()来保证p先和结合。

2.2 一维数组指针的使用

  1. 可以通过数组指针进行数组的遍历和修改。
int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int(*ptr)[5] = &arr;
	for (int i = 0; i < 5; i++) 
	{
		(*ptr)[i] *= 2;
	}
	printf("%d\n",arr[2]);
	// 输出6,数组第三个元素已经被修改为原来的两倍
}

在这里插入图片描述

  1. 通过数组指针数组的传递和返回。
void print_arr(int(*ptr)[5], int len) 
{
    for (int i = 0; i < len; i++) 
    {
        printf("%d ", (*ptr)[i]);
    }
}
int main() 
{
    int arr[5] = { 1, 2, 3, 4, 5 };
    int(*ptr)[5] = &arr;
    print_arr(ptr, 5); 
    // 输出1 2 3 4 5
    return 0;
}

在这里插入图片描述

2.3 二维数组指针的地址

假设二维数组的起始地址为2000,一个整型占4个字节,arr+1的值应该是2000+4x4=2016,arr+2的值为2032
在这里插入图片描述

表示形式含义
arr二维数组名,指向一维数组arr[0],即0行起始地址2000
*(arr+0) arr[0],*arr0行0列元素地址2000
arr+1,&arr[1]1行起始地址2016
arr[1],*(arr+1)1行0列元素arr[1][0]的地址2016
*(arr+1)+2,&arr[1][2],arr[1]+2,1行2列元素arr[1][2]的地址2024
* ( arr[1]+2), * ( *(arr+1)+2), arr[1][2]1行2列元素arr[1][2]的值是元素值,为7

2.4 二维数组指针的使用

传递数组指针给函数:

void print_arr(int (*p)[4], int row) 
{
    for (int i = 0; i < row; i++) 
    {
        for (int j = 0; j < 4; j++) 
        {
            printf("%d ", *(*(p+i)+j));
        }
        printf("\n");
    }
}

int main() 
{
    int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    print_arr(arr, 3);  
    // 传递数组指针arr给函数print_arr
    return 0;
}

在这里插入图片描述

相关文章:

  • SpringCloud(二)Docker、Spring AMQP、ElasticSearch
  • 逐步解决Could not find artifact com:ojdbc8:jar:12
  • Ubuntu安装samba服务器
  • 讲讲springboot的@Async
  • 王杰国庆作业day6
  • 打开MySQL数据库
  • 解决WPF+Avalonia在openKylin系统下默认字体问题
  • 【visual studio 小技巧】项目属性->生成->事件
  • C++笔记之不同buffer数量下的生产者-消费者机制
  • Qt扩展-QCustomPlot 用户交互
  • 学习开发一个RISC-V上的操作系统(汪辰老师) — unrecognized opcode `csrr t0,mhartid‘报错问题
  • 代码随想录算法训练营第42天|动态规划:01背包理论基础、动态规划:01背包理论基础(滚动数组)、416. 分割等和子集
  • OpenGLES:绘制一个混色旋转的3D圆柱
  • java导出word(含图片、表格)
  • FFmpeg:打印音/视频信息(Meta信息)
  • B树和B+树的介绍和对比,以及MySQL为何选择B+树
  • AS环境,版本问题,android开发布局知识
  • ROS2 库包设置和使用 Catch2 进行单元测试
  • 【Java-LangChain:使用 ChatGPT API 搭建系统-2】语言模型,提问范式与 Token
  • 新款UI动态壁纸头像潮图小程序源码
  • 媒体:“西北大学副校长范代娣成陕西首富”系乌龙,但她的人生如同开挂
  • 寒武纪陈天石:公司的产品力获得了行业客户广泛认可,市场有望迎来新增量需求
  • 香港暂停进口美国北达科他州一地区禽肉及禽类产品
  • 印巴开始互袭军事目标,专家:冲突“螺旋式升级”后果或不可控
  • 图集|俄罗斯举行纪念苏联伟大卫国战争胜利80周年阅兵式
  • 罕见沙尘再度入川,官方:沙尘传输高度达到平流层,远超以往