《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() 隐式分配和删除
通常指向匿名数据 自身即为数据名

猜你喜欢

转载自blog.csdn.net/qq_40709487/article/details/127505173
今日推荐