C语言进阶教程(再论指针和数组 (1))

简介: C语言进阶教程(再论指针和数组 (1))

前言

本篇文章我们再来一起讨论指针和数组的使用,很多同学在一块都有比较大的欠缺,所以这里专门用一篇文章来进行讲解。


一、数组首元素的地址和数组的地址

在 C 语言中,数组的首元素的地址和数组本身的地址是有区别的。

数组是由一系列连续的元素组成的,可以将其视为相同数据类型的元素在内存中的连续存储空间。数组名代表了整个数组的首地址。

在C语言中,arr、&arr、&arr[0]都涉及数组的地址和指针的概念。

arr:arr是数组的名称,它代表整个数组的首地址。在大多数情况下,将数组名arr视为指向数组第一个元素的指针。由于数组元素在内存中是连续存储的,因此arr可以被隐式转换为指向首元素的指针。

&arr:&arr是取整个数组的地址的表达式。它返回的是数组的指针,指针类型为指向该数组的指针。这意味着&arr表示整个数组在内存中的位置。

&arr[0]:&arr[0]是取数组第一个元素的地址的表达式。也就是说,它返回的是数组中第一个元素的指针。与arr相同,&arr[0]也可以被视为指向首元素的指针。

下面是一个示例代码,展示了arr、&arr和&arr[0]的使用:

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

输出结果示例:

arr: 0x7ffeed06b3b0
&arr: 0x7ffeed06b3b0
&arr[0]: 0x7ffeed06b3b0

在示例代码中,我们声明了一个包含5个整数的数组arr,并使用printf函数分别打印了arr、&arr和&arr[0]的地址。

注意到,arr、&arr和&arr[0]都打印出了相同的地址,即数组的首地址。这是因为数组在内存中是连续存储的,所以它们都代表了同一个地址,即数组的首地址。


二、数组名和指针常量一样吗

数组名和指针常量不是完全相同的东西,尽管它们在某些情况下可以具有相似的行为。

数组名:数组名不是指针常量。在大多数情况下,将数组名视为指向数组第一个元素的指针。这意味着数组名可以被隐式转换为指向首元素的指针。然而,数组名是一个常量表达式,它代表整个数组的首地址,并且不允许进行赋值操作。

指针常量:指针常量是一个具有固定值的指针,不能为其赋予新的地址值。指针常量在声明时被初始化,并且在其生命周期内不能更改。指针常量使用const关键字进行声明,表明指针指向的内存地址是常量,不可修改。

虽然数组名和指针常量在某些情况下可以互相替代使用,但它们是不同的概念。数组名代表整个数组的首地址,可以用作指针,但不具备指针常量的不可修改性质。指针常量是一个不可更改的指针,它指向一个固定的内存地址。

需要注意的是,虽然数组名和指针常量不同,但在很多上下文中,它们可以交替使用,例如作为函数参数、数组下标访问等。这是由于C语言在许多情况下会自动将数组名转换为指针,以便使用数组的元素。


三、数组名进行加1意义是什么结果又是什么

在这种情况下,arr + 1 的意义是将指针 arr 增加一个数组元素的大小,然后得到指向数组第二个元素的指针。结果是一个指向数组第二个元素的指针。

具体来说,假设 arr 是一个 int 类型的数组,每个 int 类型占用 4 个字节。那么,arr + 1 会使指针的值增加 4 个字节的偏移量,指向数组的下一个元素。

以下是一个示例代码,展示了 arr 和 arr + 1 的结果:

#include <stdio.h>
int main(void) {
    int arr[5] = {1, 2, 3, 4, 5};
    printf("arr: %p\n", arr);
    printf("arr + 1: %p\n", arr + 1);
    return 0;
}
arr: 0x7ffeed06b3b0
arr + 1: 0x7ffeed06b3b4
易错点:

这里说了数组名可以当作指针常量,那么我们就不能对数组名进行自加操作。

这是一个错误的例子:

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

总结

本篇文章就介绍到这里,下一篇文章我们继续讲解指针和数组的知识。

目录
打赏
0
2
2
2
14
分享
相关文章
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
196 9
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
65 7
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
124 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
72 1
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
239 3
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。

热门文章

最新文章