C语言指针与数组关系详解及操作示例

拾光
拾光
发布时间:2026-10-16| 6人浏览过
原创

深入解析C语言指针与数组的关系,通过代码示例演示数组名作为首地址的特性、指针的加减运算规则以及内存地址的十六进制打印方法,帮助开发者理解底层内存寻址机制。

指针与数组的基础概念

在C语言中,理解指针与数组的关系是掌握内存管理的关键。首先需要明确一个核心事实:数组名实际上是该数组第一个元素的地址。

在进行相关操作时,需掌握以下基本工具:

  • &:取址操作符,用于获取变量的内存地址。
  • %p:printf中的格式说明符,专门用于打印指针(地址),通常显示为十六进制数值。

第1步:声明并初始化指向数组的指针

若要使指针指向数组中的元素,可以通过两种方式实现等效赋值。假设有一个字符数组a和字符指针p:

// 语句1:直接利用数组名作为地址
char *p;
p = a;

// 语句2:显式取数组第一个元素的地址
p = &a[0];

以上两种写法在语义上是等价的,p最终都指向了数组a的首元素内存位置。

第2步:执行指针算术运算

当指针指向数组元素时,可以对指针进行加减运算。这与普通整数加法有本质区别:

  1. 步进规则:p + n并不意味着地址值单纯增加n,而是指向当前元素往后数第n个同类型元素的地址。偏移量实际为 n * sizeof(数据类型)。
  2. 间接访问:这种通过指针偏移而非下标索引来访问元素的方法称为“指针法”,它与标准的下标法a[n]在效果上是一致的。

代码实战与地址验证

通过具体的代码示例,可以直观地观察指针与数组在内存中的表现。

例一:通过指针修改变量值

在使用scanf读取输入时,必须传递变量的地址(使用&)。我们可以选择直接传入变量地址,或者通过已指向该变量的指针进行写入。

#include<stdio.h>
int main()
{
    int a;
    int *p = &a;

    printf("请输入一个整数:");
    scanf("%d", &a); // 方式1:直接传址

    printf("a=%d\n", a);

    printf("请重新输入一个整数:");
    scanf("%d", p);    // 方式2:通过指针p写入,p等价于&a

    printf("a=%d\n", a);
    return 0;
}

例二:字符串输入与地址打印

对于字符数组,数组名可直接作为地址参数传递给scanf。结合%p格式化输出,可以验证数组名与首元素地址的一致性。

#include<stdio.h>
int main()
{
    char str[120];
    printf("请输入内容:");
    scanf("%s", str); // str即为&str[0]

    // 验证数组名 str 与 &str[0] 是否相同
    printf("str的地址是:%p\n", str);
    printf("&str[0]的地址是:%p\n", &str[0]);

    return 0;
}

例三:不同数据类型的内存间距分析

不同类型的数据在内存中占用的字节数不同,因此相邻元素地址之间的差值也不同。以下代码展示了char、int、float和double数组元素的地址间隔:

#include<stdio.h>
int main()
{
    char a[] = "fishc";
    int b[5] = {1, 2, 3, 4, 5};
    float c[5] = {1.1f, 2.2f, 3.3f, 4.4f, 5.5f};
    double d[5] = {1.1, 2.2, 3.3, 4.4, 5.5};

    // 观察 char 类型,间隔通常为 1 字节
    printf("a[0]->%p, a[1]->%p, a[2]->%p\n", &a[0], &a[1], &a[2]);
    
    // 观察 int 类型,间隔通常为 4 字节
    printf("b[0]->%p, b[1]->%p, b[2]->%p\n", &b[0], &b[1], &b[2]);
    
    // 观察 float 类型,间隔通常为 4 字节
    printf("c[0]->%p, c[1]->%p, c[2]->%p\n", &c[0], &c[1], &c[2]);
    
    // 观察 double 类型,间隔通常为 8 字节
    printf("d[0]->%p, d[1]->%p, d[2]->%p\n", &d[0], &d[1], &d[2]);

    return 0;
}

例四:指针遍历数组

可以将指针直接赋值为数组名,然后通过解引用和指针自增(或偏移)来访问数组元素。这展示了*p与*(p+1)等同于b[0]与b[1]。

#include<stdio.h>
#include<string.h>
int main()
{
    char *str = "i love fishc.com!";
    int i, length;
    
    length = strlen(str);
    for(i = 0; i < length; i++)
    {
        printf("%c", str[i]); // 使用下标访问
    }
    printf("\n");

    // 若使用指针法访问:* (str + i)
    
    return 0;
}

例五:混合查看指针运算与地址分布

结合指针运算和解引用,进一步对比数组名与指针变量的行为一致性。

#include<stdio.h>
int main()
{
    int b[5] = {1, 2, 3, 4, 5};
    int *p = b; // p指向数组b首元素

    // 指针解引用与偏移
    printf("*p=%d, *(p+1)=%d, *(p+2)=%d\n", *p, *(p+1), *(p+2));
    printf("*b=%d, *(b+1)=%d, *(b+2)=%d\n", *b, *(b+1), *(b+2));

    // 再次确认地址结构
    printf("b[0]->%p, b[1]->%p\n", &b[0], &b[1]);

    return 0;
}

总结

通过上述步骤和代码验证,我们明确了C语言中“数组名即首地址”的本质,掌握了利用%p观察内存布局的方法,以及指针算术运算如何根据数据类型自动调整步进大小。理解这些概念是编写高效C语言程序的基础。

以上就是C语言指针与数组关系的详细内容,更多关于C语言指针教程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。