首页 > 其他分享 >指针(二):数组指针巧妙玩法

指针(二):数组指针巧妙玩法

时间:2024-10-20 20:19:27浏览次数:3  
标签:arr int 玩法 地址 数组 printf 指针

目录

数组名的理解

在介绍数组指针之前先通过一段代码了解一下数组名的本质是什么。

#include<stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5 };
	int* p1 = &arr[0];
	int* p = arr;
	printf("%p\n", p1);
	printf("%p", p);
	return 0;
}

第一行代码我们取出数组第一个元素的地址放在p1里面,第二行将数组名直接赋值给p,如图,以地址的形式打印出来的地址一模一样,说明数组名本质上就是数组首元素的地址。
同时也说明我们调用函数时以数组为参数传参时传的也就是数组首元素地址。
在这里插入图片描述
但是在一些特殊情况下的数组名不代表首元素的地址。
如:
sizeof(数组名):sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节。
&数组名:这里取地址取的是整个数组的地址。
除了这两种情况,其他的地方使用数组名都是数组首元素地址。
这个时候就会有人好奇去尝试打印整个数组的地址,如下列带代码:

int main()
{
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 printf("&arr[0] = %p\n", &arr[0]);
 printf("arr = %p\n", arr);
 printf("&arr = %p\n", &arr);
 return 0;
}

发现三个打印的地址一模一样,那数组整个地址与数组首元素地址区别是什么?

数组地址与数组首元素地址区别

#include <stdio.h>
int main()
{
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 printf("&arr[0] = %p\n", &arr[0]);
 printf("&arr[0]+1 = %p\n", &arr[0]+1);
 printf("arr = %p\n", arr);
 printf("arr+1 = %p\n", arr+1);
 printf("&arr = %p\n", &arr);
 printf("&arr+1 = %p\n", &arr+1);
 return 0;
}

在这里插入图片描述
上述代码中printf两行为一组,每一组代码都是取出来一个地址给地址加1。
可以看出来前两组代码的值变化都是4个字节(原因在上一篇指针(一)里面介绍过),而最后一组变化范围很大。
原因就是最后一组取出来的是整个数组的地址,让地址加1就是加整个数组的大小的地址,这段代码中arr的大小是40个字节,所以让整个数组的地址加1也就是加40个字节,但是取数组地址并用printf打印也是打印数组首元素的地址。

指针访问数组

用指针的形式来输入和输出数组:

int main()
{
	int arr[5] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		scanf("%d", arr + i);//arr数组首元素地址,循环一次加1
	}
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(arr+i));//每循环一次地址加1并解引用
	}
	return 0;
}

运行结果如图:
在这里插入图片描述
这只是指针的一种描写形式,还有很多形式与它等价,代码与结构如下图所示:
在这里插入图片描述

冒泡排序

冒泡排序本质上就是相邻两个地址之间进行比较然后进行排序。

void bubble_sort(int arr[], int sz)//参数接收数组元素个数{
 int i = 0;
 for(i=0; i<sz-1; i++)
 {
 int flag = 1;//数组是否有序标志位
 int j = 0;
 for(j=0; j<sz-i-1; j++)
 {
 if(arr[j] > arr[j+1])
 {
 flag = 0;//发⽣交换就说明,⽆序
 int tmp = arr[j];
 arr[j] = arr[j+1];
 arr[j+1] = tmp;
 }
 }
 if(flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了 
 {
 break;
 }
}
int main()
{
 int arr[] = {3,1,7,5,8,9,0,2,4,6};
 int sz = sizeof(arr)/sizeof(arr[0]);
 bubble_sort(arr, sz);
 int i = 0;
 for(i=0; i<sz; i++)
 {
 printf("%d ", arr[i]);
 }
 return 0;
}

二级指针

在我们取变量地址时会创建一个指针变量来存放这个地址,有变量就会有地址,二级指针就是用来存放指针变量地址的变量。

int main()
{
	int a = 0;
	int* p = &a;//一级指针
	int** p = &p;//二级指针
	return 0;
}

那么二级指针怎么找到变量a呢?
对它进行两次解引用就好了:第一次解引用找到p,找到p后再对p进行解引用就找到了a。

指针数组

整形数组是代表数组的每个元素都是整形,那指针数组也就是说每个数组元素都是一个指针变量。

int* arr[5]={a,b,c,d,e};//这里a,b,c,d,e都是一个整形类型的指针变量

指针数组模拟二维数组

int main()
{
	int arr1[3] = { 1,2,3 };
	int arr2[3] = { 4,5,6 };
	int arr3[3] = { 7,8,9 };
	int* arr4[3] = { arr1,arr2,arr3 };
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d", arr4[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

标签:arr,int,玩法,地址,数组,printf,指针
From: https://blog.csdn.net/2401_88035751/article/details/143098041

相关文章

  • C语言深入理解指针笔记(3)
    1.字符指针变量 我们已经了解的指针变量类型有:整形指针变量:int*pint:存放的是整型变量的地址浮点型指针变量:float*pf:存放的是浮点型变量的地址类比可知:char*pc:字符型指针变量:存放的是字符型变量的地址,指向字符型的数据 首先,字符型指针变量的使用有两种方法:......
  • 第5节:初识数组
    5.初识数组1.数组的概念数组(Array)是C语言中用于存储相同类型数据的集合。数组中所有元素的类型相同,并且它们在内存中是连续存储的。数组的大小在定义时必须指定,并且一旦定义,大小就不能更改。数组的索引是从0开始的,也就是说,第一个元素的索引为0,第二个元素的索引为1,以此......
  • 鸿蒙开发 四十九 数组
    1、数组的创建方式数组:接口范型的形式提供,接口的源码是:interfaceArray<T>,实际开发中数组用得非常多,创建数组的方式有:1、语法格式:let数组名:Array<数组类型>=[],实例:letarr1:Array<IObject>=[],这里申明IObject的数组,2,new关键字创建数组,语法格式:let数组名字:Arra......
  • 六,数组笔记及相关练习题大全
    Java编程基础:数组详解在Java编程中,数组是一块连续固定大小的内存空间,用于存储相同类型的多个元素。数组提供了索引的概念,允许通过索引访问和操作数组中的元素。本文将详细探讨Java中数组的定义、初始化、使用和示例。数组的定义和初始化数组在定义时需要指定数据类型和数组名。......
  • 【C语言】指针进阶【万字详细版】
    ㊙️小明博客主页:➡️敲键盘的小明㊙️✅关注小明了解更多知识☝️文章目录前言一、字符指针二、指针数组三、数组指针3.1数组指针的定义3.2数组名和&数组名3.3数组指针的使用四、数组参数、指针参数4.1—维数组传参4.2二维数组传参4.3一级指针传参4.4二级指针......
  • 轮转数组——力扣189题
    力扣189题轮转数组,本身很简单,但是反复提交很多次都没有成功,实在是让人难以启齿,分析应该还是概念不清晰导致的,自以为理解得很清楚,实际确实模棱两可。把数组后几个移动到前面的位置上去,按照我最开始的想法,不过就是切片,把后半部分切下来,形成的两个半个数组再加起来不就是了吗?在py......
  • 用C++实现自己的智能指针:深入探讨内存管理与RAII模式
    解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界C++中的内存管理一直以来是程序员的一个难点,尤其是在处理动态内存分配时。智能指针(如std::unique_ptr和std::shared_ptr)通过RAII(资源获取即初始化)的设计理念,极大地简化了动态内存的管理,减少了内存泄漏的风险。然......
  • 提取并排序数组中的偶数
    题目:提取并排序数组中的偶数题目描述:给定一个整数n和一个包含n个整数的数组,编写一个程序提取数组中的所有偶数,并按升序排序后输出。输入格式:第一行包含一个整数 n (1≤ n ≤100,000),表示数组的元素个数。第二行包含 n 个整数,表示数组中的元素。每个整数的绝对......
  • 65.C指针---sizeof()函数和strlen()函数常见考
    #include<stdio.h>#include<string.h>intmain(){inta[]={1,2,3,4};printf("%d\n",sizeof(a));printf("%d\n",sizeof(a+0));printf("%d\n",sizeof(*a));printf("%d\n",s......
  • 第7讲:数组
    文章目录1.数组的概念2.⼀维数组的创建和初始化3.一维数组的使用4.一维数组在内存中的存储6.⼆维数组的创建7.二维数组的初始化8.二维数组的使用9.二维数组在内存中的存储10.C99中的变长数组11.数组练习1.数组的概念2.⼀维数组的创建和初始化3.⼀维数......