深度理解C语言三——指针的进阶(数组指针,指针数组)

简介: 深度理解C语言三——指针的进阶(数组指针,指针数组)

前言


我们前面对指针有了初步的学习,本篇文章我们来对指针进行较为深入的学习。


一、字符指针


在指针的类型中有一种指针类型为字符指针 char* ;

一般情况下我们就是把一个字符的地址放入字符指针中,但我们这里介绍一下另一种用法:

int main()
{
    const char* p = "hello world";//这里是把一个字符串放到指针变量里了吗?
    printf("%c\n", *p);
    return 0;
}

显然是不可能把一个字符串放到指针变量里的,指针变量这里只有四个字节,根本放不下,我们来打印一下看一看到底放的是啥。

我们这里其实是把字符串首字符的地址给了p,并没有把整个字符串给p,但是如果想打印整个字符串该怎么打印呢?只需要把%c换成%s,*p换成p就可以了,我只需要知道你的起始地址,就能打印出你全部的内容。


二、数组指针


数组指针是指针?还是数组?

答案是:指针。

我们前面一起学习过:

整形指针: int * p; 能够指向整形数据的指针。

浮点型指针: float * p; 能够指向浮点型数据的指针。

那数组指针应该是:能够指向数组的指针。

那么数组指针如何定义呢?

解释:

int (*p)[10]    //解释:p先和*结合,说明p是一个指针变量,然后指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

那么数组指针应该怎么用呢?这里我们先知道一个概念:数组的地址

我们&arr取出的是数组的地址,注意:数组的地址 和 数组首元素的地址意义是不一样的,但他们在数值上是一样的。我们来看一段代码。


我们可以看出,两个地址数值上是相等的,但是我们分别给这两个地址+1,结果却不一样。&arr+1是向后跳过一个数组,这个数组10个元素,就是向后跳过40个字节。&arr[0]+1是向后跳过一个元素,就是向后跳过四个字节。讲到这里我们就理解了数组的地址的意思了。数组指针存放的是数组的地址,即&arr。

我们再来看一下数组指针怎么用。我们举个例子用数组指针来打印数组中的元素。请看下面代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h> 
void printf1(int (*p)[5]) {              2.实参传过来整个数组的地址,形参用数组指针来接收。
    for (int i = 0; i <= 4; i++)
    {
        printf("%d ", *(*p + i));        3.*p拿到整个数组,即数组名,即数组首元素地址,(*p+i)拿到数组每个元素的地址,再*(*p + i)拿到数组的每个元素。
    }
}
int main()
{
    int arr[5] = { 0,1,2,3,4,};
    printf1(&arr);                  1.我们把整个数组的元素传进去
 return 0; 
}


我们可以发现,这样做虽然用到了数组指针,但这个算法很麻烦。我们完全没有必要用这种方式来打印数组中的元素,所以数组指针很少用在一维数组中,这里只是通过这个例子来学习理解

数组指针的用法。

我们再来用二维数组举例来学习一下数组指针的用法。还是用打印数组的元素来举例

(注意:二维数组的数组名表示首元素地址时表示的是第一行的地址。)

#include <stdio.h>
void printf1(int (*p)[2]) {             //2.用数组指针来接受
    for (int i = 0; i <= 1; i++)
    {
        for(int j=0;j<=1;j++)
        {
            printf("%d ", *(*(p+i)+j));    //3.p+i相当于指向第i行,*(p+i)相当于拿到了第i行的数组名,*(p+i)+j相当于指向第i行第j列的某个元素,也就是找到了它的地址。 *(*(p+i)+j)相当于通过它的地址找到了第i行第j列的某个元素
        }
    }
}
int main()
{
    int arr[2][2] = { 0,1,2,3,};     
    printf1(&arr);                  //1.传过去整个数组的地址
    return 0;
}


这里重点理解学习一下数组指针是如何使用的。这里只是通过这个例子来学习理解数组指针的用法。


三、指针数组


先看一下下面这三个

int arr[10]={0};     //存放整形数据的数组
char arr[10]={0};    //存放字符数据的数组
float arr[10]={0};   //存放浮点型数据的数组


那么指针数组就是一个存放指针的数组。(指针存放的是地址,而指针本身也要存放起来。)

int* arr1[10]; //整形指针的数组
char *arr2[4]; //字符指针的数组
char **arr3[5];//二级字符指针的数组


这个具体怎么用呢?请看下面代码:

int main()
{
    int a = 2;
    int b = 3;
    int* p1 = &a;
    int* p2 = &b;
    int* arr[2] = { p1,p2, };
    for (int i = 0; i <= 1; i++)
    {
        printf("%d ", * (arr[i]);     //arr[i]拿到地址,再解引用拿到元素 
    }
    return 0;
}


模拟二维数组

我们还可以用这个来模拟一个二维数组,请看代码:


#include <stdio.h>
int main()
{
    int arr1[3] = { 0,1,2 };
    int arr2[3] = { 3,4,5 };
    int arr3[3] = { 6,7,8 };
    int* arr[3] = { arr1,arr2,arr3};     //数组名表示首元素地址,所以可以放进指针数组
    for (int i = 0; i <= 2; i++)
    {
        for (int j = 0; j <= 2; j++)
        {
            printf("%d", *(arr[i] + j));   //arr[i]拿到第i个数组的首元素地址,+j指向第i个数组中的第j个元素,再解引用表示通过地址找到了这个元素。
        }
        printf("\n");
    }
    return 0;
}


运行结果为:

这样我们就模拟出了一个3行3列的二维数组。


总结


本篇文章学习了指针的一些较为深的一些知识,希望大家多去理解和学习。由于指针的内容较多,下篇文章继续来学习指针的进阶,本篇文章就先学习到这里。

本篇文章内容结束,感谢大家观看。如果意见或建议,可以在评论区留言,您的点赞是我更新的动力。我们下篇文章再见。

目录
相关文章
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
86 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
56 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
45 7
|
1月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
98 6
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
72 5
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
161 13
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
139 3
|
2月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
2月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
44 1