指针
本文将讲述C语言中关于指针的相关知识。
关于地址和指针
在C语言中,将地址形象地称为”指针”。一个变量的地址称为变量的”指针”。一个专门用来存放另一个变量的地址的变量(即指针),则称它为”指针变量”。
变量的指针和指向变量的指针变量
指针变量的定义
定义 指针变量 的一般形式:类型名 *
指针变量名,*
指针变量名2…;
如: int *p,*t;
指针变量的引用
指针变量中只能存放地址(指针),与指针相关的两个运算符是”&”(取地址运算)和”*”(指针运算符)
指针变量作为函数参数
指针类型数据可以作为函数参数来进行传递,作用:将一个变量的地址传送到另一个函数中,参与该函数的运算。形参指针变量的值的改变不能使实参指针变量的值发生改变。
关于*和&的谜题
假设有一个int类型的变量a,pa是指向它的指针,那么*
&a和&*
pa分别是什么意思呢?*
&a可以理解为*
(&a),&a表示取变量a的地址(等价于pa),*
(&a)表示取这个地址上的数据(等价于*pa)。即*&a仍等价于a
。
&*pa可以理解为&(*pa),*
pa表示取得pa指向的数据(等价于a),&(*pa)表示数据的地址(等价于&a)。即&*pa等价于pa。
数组与指针
指向数组元素的指针
C语言规定数组名代表数组的首地址,也就是数组中第0号元素的地址。
定义指向数组元素的指针变量的方法,与定义指向变量的指针变量相同。
通过指针引用数组元素
如果指针变量P以指向数组中的一个元素,则P+1指向同一数组中的下一个元素。
用数组名作为函数的参数
●当数组名作为参数被传递时,若形参数组中各元素发生了变化,则原实参数组各元素的值也随之变化。
●如果用数组元素作为实参,情况就与用变量作为实参时一样,是”值传递”方式。
指向多维数组的指针和指针变量
多维数组可以看作是一维数组的延伸,多维数组的内存单元也是连续的内存单元。C语言实际上是把多维数组当成一维数组来处理。
字符串与指针
字符串的表示形式
●用字符数组存放一个字符串,然后输出该字符串。
●用字符指针指向一个字符串,用字符指针指向字符串中的字符。
字符串指针作为函数参数
将一个字符串从一个函数传递到另一个函数,可以用地址传递的办法,即用字符数组名作为参数或指向字符串的指针变量作为参数,进行传递。
字符指针变量和字符数组的区别
●字符数组是由若干个元素组成的,每个元素中存放一个字符,而字符指针变量中存放的是地址,绝不可能将字符串的内容存放到字符指针变量中。
●赋值方式不同
●字符数组可以在定义时对整体赋初值,但在赋值语句中不能完成整体赋值。而字符指针变量既可以在定义时赋初值,也可以在赋值语句中完成。
●编译时不同
●在程序中指针变量的值可以改变。而数组名虽然代表了地址,但其值固定,不可改变。
指向函数的指针
指针变量可以指向一个函数,编译时,一个函数将被分配给一个入口地址,这个入口地址就称为该函数的指针。因此,可以通过使用一个指向函数的指针变量调用此函数。
说明:
●指向函数的指针变量的一般定义形式为: 数据类型(*
指针变量名)();
●在给函数指针变量赋值时,只需给出函数名而不必给出参数。
●用函数指针变量调用函数时,只需将(*
S)代替函数名即可(S为已定义的指向函数的指针变量名),在(*
S)之后的括号中根据需要写上实参。
●对指向函数的指针变量,做自增自减或算术运算等都没有意义。
指针数组和指向指针的指针
指针数组的概念
若在一个数组中,其元素均为指针类型数据,这样的数组称为指针数组。
一维指针数组的定义形式为: 类型名 *
数组名[数组长度]
指向指针的指针
指向指针数据的指针变量,简称为指向指针的指针,通常称为二级指针。
定义一个指向指针数据的指针变量的形式: 类型名 **
a
C语言空指针NULL以及void指针
空指针NULL
形式: char str = NULL;
一般对没有初始化的指针赋值为NULL,意为零。
空指针是不指向任何数据的指针,是无效指针。很多库函数对传入的指针做了判断,如果是空指针就不做任何操作。其实NULL是stdio.h中定义的一个宏,具体内容为 #define NULL ((void)0) ,NULL指向了地址为0的内存。
void指针
void * 含义:表示指针指向未知的数据类型,它指向数据后一般在使用时还需强制类型转换。
二维数组指针(指向二维数组的指针)
若有以下二维数组a:
1 | int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}}; |
概念上是一个矩阵,但在内存中它线性连续分布。
C语言允许把二维数组分解为一维数组来处理,即数组a可分解为三个一维数组a[0],a[1],a[2]
每个一维数组包含了若干元素,
1 | 如a[0]包含 a[0][0] , a[0][1] , a[0][2] , a[0][3] |
假设数组a中第0个元素地址为1000,那么每个一维数组的首地址如图:
定义指向a的指针变量p: int (*p)[4] = a
指针的总结
指针(Pointer)就是内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本数据的地址,也可以存放数组、函数及其他指针变量的地址。
常见指针变量的定义:
定义 | 含义 |
---|---|
int * p; |
p可以指向int型的数据,也可以指向类似int arr[n]的数组 |
int ** p; |
p为二级指针,指向int*类型的数据 |
int * p[n]; |
p为指针数组。[]优先级高于* ,应理解为int * (p[n]) |
int (* p)[n]; |
p为二维数组指针 |
int * p(); |
p是一个函数,它的返回类型为int * |
int (* p)(); |
p是一个函数指针,指向原型为 int fun() 的函数 |
版权声明
Scholar’s Blog by scholargeek is licensed under a Creative Commons BY-NC-ND 4.0 International License.
由董仕麟创作并维护的scholargeek博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于Scholar’s Blog博客,版权所有,侵权必究。
本文永久链接:https://scholargeek.github.io/2018/02/14/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A07/