《C语言笔记:数组和指针并不相同》

一,前言

在初学C编程的时,总是会听见说“数组和指针是相同的”,这是一种非常危险的说法。今天通过对《C专家编程》的学习,重新认识下指针和数组,分析下它们之间“并不相同”的原因。

二,问题引入

下面代码在define.c中定义mango变量,在pointer_arry.c中声明并访问mango变量的值。
当mango的声明和定义一致均为指针或者均为数组时,程序正常以数组下标的形式访问到它某个元素的值。
当mango声明它为一个指针,定义它为一个数组时,程序以数组下标的形式访问它某个元素的值时,发生段错误。
所以,数组和指针并不是相同的。

#include <stdio.h>

#define CORRECT 0

#if CORRECT

// mango 声明和定义一致均为指针
char test[10] = {1,2,3,4,5,6,7,8,9,10};
char *mango = test;

#else
// mango 声明和定义不一致,定义为数组,声明为指针  此时程序出现段错误
char mango[10] = {1,2,3,4,5,6,7,8,9,10};

#endif


#include <stdio.h>

extern char *mango;
// extern char mango[];

int main()
{
    printf("mango[9] = %d \n",mango[9]);
}

三,声明和定义

要想知道为什么当mango 声明和定义不一致(定义为数组,声明为指针)时程序出现段错误,首先需要知道什么是声明,什么是定义。

C语言中的对象必须有且只有一次定义,但它可以有多个声明。这里说的对象指的是函数或者变量。extern 声明只是告诉编译器变量的类型和名字。只有在定义变量的时候才会根据变量的类型给变量分配内存。就是上面的程序一样,在main文件中,声明变量mango为指针类型,这里并没有给变量mango分配内存,它只是告诉编译器存在这么一个变量,在其他地方定义了,可以使用它,在链接的时候会去其它文件中寻找到该变量在内存中的位置。在define.c中便定义了该变量,确定该变量的类型并分配内存。

四,数组和指针的访问

编译器为每个变量(定义时)分配一个地址。这个地址在编译时可知,而且该变量在运行时一直保存于这个地址处。相反,存储于变量中的值只有在运行时才知。声明定义变量a为数组时,a的地址已知,可通过其地址或者地址+偏移值(下标)直接得到其内容。声明定义变量a为指针时,a的地址已知,但这个是指针的地址,通过这个地址只能得到它指向的内容的地址,并不能直接得到内容本身。

4.1 数组的访问

在这里插入图片描述

4.2 指针的访问

在这里插入图片描述

五,数组和指针并不相同

当一个变量被声明为指针时,比如char *a,那么编译器将会认为符号a为一个指针,它指向的对象是一个字符。访问a时,将会以指针的方式访问它。
当一个变量被声明为数组时,比如char a[10],那么编译器将会认为符号a为一个数组。访问a时,将会以数组的方式访问它。

5.1 当声明为指针,定义为数组时

定义变量a为数组时,给数组a分配内存,存放在地址1024处。声明变量a为指针时,将告诉编译器变量a为一个指针,将以指针的形式访问它,它的地址为1024。
在这里插入图片描述

5.2 数组和指针的其他区别

指针数组
保存数据的地址保存数据
间接访问数据,首先取得指针的内容,把它当作地址,然后再从这个地址取数据。如果指针有一个下标 i ,就把指针的内容加上 i 作为地址,再从中取数据。直接访问数据,a[i]只是简单的以a+i为地址取得数据。
通常用于动态数据结构通常用于存储固定数目且数据类型相同的元素
相关的函数为malloc()、free()隐式分配和删除
通常指向匿名数据自身即为数据名
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程界的小学生、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值