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;
}

总结

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

相关文章
|
1天前
|
C语言
c语言指针总结
c语言指针总结
15 1
|
1天前
|
C语言
C语言(指针详解)重点笔记:指针易错点,都是精华
C语言(指针详解)重点笔记:指针易错点,都是精华
3 0
|
1天前
|
C语言
每天一道C语言编程(数组操作)
每天一道C语言编程(数组操作)
5 0
|
1天前
|
C语言
每天一道C语言编程(第一弹~):数组
每天一道C语言编程(第一弹~):数组
9 0
|
1天前
|
存储 C语言
C语言指针讲解(适用于初学者)
C语言指针讲解(适用于初学者)
6 0
|
1天前
|
机器学习/深度学习 C语言
C语言三维数组的创建
该代码片段展示了如何在C语言中创建一个动态的3D数组。由于`n`在编译时未知,不能直接声明为`int f[n][n][n]`。正确的方法是使用`malloc`进行动态内存分配。首先分配`n`个`int **`,然后对每一层分配`n`个`int *`,最后每个元素分配`n`个`int`。之后可以使用这个3D数组,并在完成后正确释放内存。
11 2
|
1天前
|
搜索推荐 C语言
详解指针进阶2
详解指针进阶2
|
1天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
1天前
|
存储 C语言
C语言进阶---------作业复习
C语言进阶---------作业复习

热门文章

最新文章