C语言指针变量研究

2023-05-24 04:51史宇轩徐洪丽丁颐宁
科技资讯 2023年8期
关键词:数组指针C语言

史宇轩 徐洪丽 丁颐宁

摘要:指針在C语言程序设计中占有重要的地位,指针变量的灵活性是C语言的主要特色之一。指针变量能够方便表示各种复合数据类型,可以使用数组和字符串,同时也可以处理内存地址。文章首先论述了指针和地址的关系,以及指针的定义;其次根据指针的实质化繁为简,总结了3种不同的指针赋值方式;再次,给出了常用的指针运算和注意事项,最后,辅助以举例和练习。指针变量的灵活性也带给程序一定的危险性,因此能否正确理解和使用指针是是否掌握C语言的一个标志。

关键字:地址和指针  指针变量  指针变量赋值   指针变量运算

中图分类号:TP312.1    文献标识码:A

Research of  Pointer Variables in C Language

SHI Yuxuan 1   XU  Hongli 2*    DING Yining

(1.School of Computer Science and Technology, Shangdong University of Technology, Zibo, Shandong Province, 255000 China; 2.School of Information Science and Engineering, Shandong Agricultural University, Taian, Shandong  Province,271018 China; 3. College of Geodesy and Geomatics, Shandong University of Science and Technology, Qingdao, Shandong Province,  266590 China)

Abstract: The pointer occupies an important position in programming in C language, and the flexibility of pointer variables is one of the main features of C language. Pointer variables can easily represent a variety of composite data types, can use arrays and strings, and can also handle memory addresses.  This article firstly discusses the relation between pointers and addresses and the definition of the pointer, then simplifies the complex  according to the essence of pointer and summarizes three different pointer assignment methods, gives commonly used pointer operations and matters needing attention again, and finally gives auxiliary examples and exercises. The flexibility of pointer variables also brings some risks to the program, so whether you can understand and use pointers correctly is a sign of mastery of C language.

Key Words: Address and  pointer; Pointer variable; Pointer variable assignment; Pointer variable operation

指针变量在C语言程序设计中占有重要的地位,已知在程序中定义了一个变量,在对该程序进行编译时,首先要借助编译程序将其转换成目标代码,也就是*.OBJ文件,然后,通过操作系统将目标代码装入特定的可标识的内存区域中。编译系统会根据程序中定义的变量类型,为该变量分配内存单元,该内存单元也就是该变量的地址,其内容为该变量的内容 [1]。因此程序员通过程序所定义对象的名称来访问对象。假定程序员能够知道某程序对象在内存中的存储位置,即存放该对象的首地址,当然也可使用该地址访问对象。C语言能够满足以上的需求,提供解决上述问题必要的技术手段,也就是指针变量。

1 指针的定义

1.1 地址和指针

C语言中,指针实际上就是地址。在计算机中,数据都是存放在存储器中的。通常把存储器中的一个字节称为一个内存单元,为了正确地访问这些内存单元,必须为每个内存单元编号,该编号就是地址。根据该编号(如变量 int a=1;的地址&a)即可以找到该变量的内容,在地址所表示的内存单元中实际存放的数据是该内存单元的内容,需特别注意的是内存单元的地址与内存单元的内容是两个完全不同的概念。可以通过printf(“%d%d”,&a,a);实际做个测试,即:内存储器中的所有字节(byte)都拥有一个编号,该编号即“地址”,它类似于教学楼中的教室号;数据存放在地址所表示的内存单元中,类似于教室中上课的学生;因为通过地址能找到所需的变量单元,通常说地址指向该变量单元。

将地址形象化地称为“指针”,注意区分存储单元的地址和存储单元的内容。例如:VC++为整型变量分配4个字节,对单精度浮点型变量分配4个字节,对字符型变量分配1个字节。地址是一个直接存取的概念,必须通过地址才能找到存储变量值的存储单元,即“地址”指向了变量的存储单元,C语言形象地将地址称为“指针”。因此,一个变量的地址称为该变量的“指针”。图1为按变量地址存取变量的方式称为“直接访问”方式。int i=3,j=6,k;   k=i+j; cout<<k;

1.2   指针变量

int i=3,j=6,k;   int *i_pointer;     i_pointer=&i;    *i_pointer=50;如图2所示:与地址的直接存取不同,指针变量是一种间接存取方式。即先找到變量i_pointer的内容2000,再找到该2000地址下所存储的内容50,因此指针变量是一种间接存取的方式。

1.3  指针变量的定义

指针变量中存储的是地址,而不是实际的数据,它存储的是指向该数据的地址(闲荡于房间号),这是指针变量和普通变量的主要不同。因此,在使用前必须先声明或定义其为指针变量,并说明指针变量中存储的地址指向的数据类型(间接存储)。指针类型基本定义形式为:类型说明符  *变量名;其中,*表示该变量是指针变量(存储地址的),变量名是指针变量名,类型说明符标志了其存储的地址值所指向的数据类型[2]。明确了指针变量所指向的变量的类型,编译器就可根据该类型来读取内存中相应的连续空间。

例如:int *p;//,int是类型说明符 ;*是指针类型说明符;p是变量名

int * arr[8]// 声明一个指向整型数据的指针数组,有8个元素。

int (*arr)[10] // 定义一个数组指针,该指针指向一个 int 类型的一维数组

int **p;       // 定义一个指针 p ,该指针指向一个 int 类型的指针

数组指针:数组指针可以理解为“数组的指针”,是指针,该指针指向数组,即是指向数据的指针,它的长度由数组本身决定。即首先这个变量是一个指针,该指针存放的是地址,类似于int a[5][6] 数组中的 a,a+1 ,a+2 等,是指向行的地址,并没有精确到具体的列值。指针数组:指针数组是“指针的数组”, 是数组,该数组元素为指针类型。

指针变量的定义中需要说明两问题: 1) 用“*”定义该变量为指针变量2)指针变量名;3) 说明该变量的名称,及其间接指向数据的类型。指针变量在使用前必须先初试化。初试化之前不会自动分配内存空间。

2 指针变量的赋值和指针运算

2.1 指针变量的赋值

根据指针变量的定义和含义,指针变量的内容应该是编译后有具体位置的地址。关于地址,语言中,普通变量有地址,数组的名字代表数组的首地址。即 int arr[10];  则a即与第一个元素的地址&arr[0]的值是一样。可以通过printf(”%d%d",arr,&arr[0])测试。即:

int arr[10];  /*定义包含10个整型数据的数组*/

int *p1;    /*定义p1为指向整型变量的指针*/

P1=arr; /*把数组arr的首地址赋给指针变量p*/

P1=&arr[0];  /* 把arr[0]元素的地址赋给指针变量p1。即p1指向数组arr的第0号元素。*/

因此指针变量的赋值有以下三种基本形式:

指针的3种赋值方式

Int a=1,*p; P=&a; // a为普通变量

Int a[10],*p;P=a ;//为数组 程序1为示例

P2=p1;// p1已经按照上述两种方式赋值

注意:“*”出现在不同的位置有不同的意义。出现在类型声明中,它是类型说明符,除此之外,出现在表达式中,它是运算说明符,是指针取内容运算符* [3],表示该指针变量间接所指的内容。

2.2  指针运算

常用的指针运算有”*”间接访问内存,单目运算符。++/--自增或自减运算符,单目运算符[4]。另外还用常用的关系运算符:>,<,>=,<=,!=。基础必备知识:

*++p 相当于  *(++p) 或者 a[++i], 先对p做加运算,再做*运算。

*p++ 相当于  *(p++)  或a[i++],先对 p进行取内容“*”运算,在使 向下移动一位。

(*p)++  先取*p的值,再将数值自加。++(*p)  先将*p值自加,再取*的值。因此:

P+i和a+i都表示a[i]的地址,即它们都指向数组中第i号元素,即指向a[i]。

*(P+i)和*(a+i)都表示P+i和a+i所指向对象的内容即a[i]。

指向数组元素的指针,即允许指针变量带下标,如p[i]与*(p+i)等价。

假如p=a+5,则p[2]就相当于*(p+2),即p[7],p[-3]就相当于*(p-3),即p[2]。

等价关系  p+i --- a+i  即从当前p指向地址往后移i个元素的地址。

p=a; *(p+5)---*(a+5)---a[5] ---p[5]   这几种方式是a[5]的不同表示方法。

注意:*和&、++、--都是一元运算,它们的优先级比所有的算术运算符都高。*其结合性为自右至左 。 *p++等价于*(p++)。

两指针变量之间的运算:指针变量不指向同一数组,它们之间的运算没有意義,即仅仅当两指针变量指向同一数组时,运算才有意义[5]。一般情况下,两个指针变量表示同一个数组中的元素,它们可以进行关系运算,运算结果表示它们所指数组元素的地址之间的关系[6]。例如: p1=p2表示p1和p2指向同一数组元素;p1>p2表示p1处于高地址位置;p1<p2表示p1处于低地址位置。但是p1+p2是没有真实意义的。

3 举例和练习

例题:输入两个整数,采用指针方式从小到大排序。

# include <stdio.h>

void main()

{   int i,j,k;  int t;

int *p=&i,*q=&j;

*p=2;*q=1;

if  (*p>*q)

{    t=*p;       *p=*q;      *q=t;  }

printf("*p=%d,*q=%d\n",*p,*q);

4  总结

指针在C语言程序设计中占有重要的地位,与其它语言相比,指针变量的灵活性是C语言的主要特色之一。指针极大地丰富了C语言的功能,但是凡事有两面性,指针变量的灵活性也带给程序一定的危险性,因此能否正确理解和使用指针是能够否掌握C语言的一个标志。

参考文献:

[1] 王铖. 一些C库函数的实现[D].吉林大学 2021:1-2

[2] 徐洪丽 语言程序设计[M].  北京师范大学出版社 2019: 199-200

[3] 李琨,贾立伟,石晓明.C程序设计语言中文件读取问题探析[J].电脑编程技巧与维护,2022(02):23-25.

[4] 尹慧,段华琼.基于C语言的图书管理系统的设计与实现[J].信息与电脑(理论版),2021,33(23):116-118

[5]  Baltasar Garcia Perez‐Schofield,Matías Garcia Rivera,Francisco Ortin,Maria J. Lado. Learning memory

management with C‐Sim: A C‐based visual tool[J]. Computer Applications in Engineering Education,2019(5):27-28.

[6] 岳珊.C语言程序设计过程中指针概念的理解及使用[J].信息与电脑(理论版),2020,32(15):111-113

猜你喜欢
数组指针C语言
JAVA稀疏矩阵算法
基于Visual Studio Code的C语言程序设计实践教学探索
JAVA玩转数学之二维数组排序
基于C语言的计算机软件编程
为什么表的指针都按照顺时针方向转动
Excel数组公式在林业多条件求和中的应用
高职高专院校C语言程序设计教学改革探索
寻找勾股数组的历程
基于改进Hough变换和BP网络的指针仪表识别
论子函数在C语言数据格式输出中的应用