C语言指针

您所在的位置:网站首页 指针工作原理是什么 C语言指针

C语言指针

2024-07-17 02:24| 来源: 网络整理| 查看: 265

前言

       本篇博客主要是学习C语言指针的作用和一些使用场景,内容基本是自己对于C语言的理解和笔记,如有错误请及时指出,不保证是百分百正确的理解,希望大家互勉。本篇博客大部分是自己收集和整理,如有侵权请联系我删除。

如果觉得有用点赞关注收藏三连,多谢支持

本博客内容原创,创作不易,转载请注明 ———————————————— ————————————————

一.认识指针 1.指针的基本作用 表示一些复杂的数据结构快速的传递数据 (1)使用指针传递大容量的参数,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用 (2)使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计  使函数返回一个以上的值 (1)将模块内的公有部分返回,让主函数持有模块的“句柄”,便于程序对指定对象的操作  直接访问物理地址下的数据 (1)访问硬件指定内存下的数据,如设备ID号等 (2)将复杂格式的数据转换为字节,方便通信与存储  能够方便的处理字符串是理解面向对象语言中引用的基础可以有效地表达一些复杂的数据结构,比如系统地动态分配内存、消息机制、任务调度、灵活矩阵定时等等。传递参数 2.指针的基本概念(理解)

(1)指针就是地址,地址就是指针。地址就是内存单元的编号,是从0开始的非负整数。

        没有内存就没有指针,指针必须指向一块在程序中申请过的内存空间,这个指针才能使用,而不是野指针;

        其实内存空间就相当于一个房间,每个房间都有门牌号,而指针就是房卡,房卡上写着门牌号, 你拿着房卡啥都干不了 必须打开门进去,才能对房间里的东西进行操作

(2)在C语言中,每个变量的最终存放的地方就是芯片的地址,每个地址就相当于一个编号,而指针的作用就是直接指向该地址,获取地址上的值。对于一个内存单元来说,单元的地址即为指针,其中存放的数据才是该单元的内容。

(3)在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针。

(4)一个指针是一个地址,是一个常量。而一个指针变量却可以被赋予不同的指针值,是变量。但常把指针变量简称为指针。

(5) 既然指针变量的值是一个地址, 那么这个地址不仅可以是变量的地址, 也可以是其它数据结构的地址。指针变量存放一个数组或者函数的首地址,就可以找到改数组或者函数,因为内存存储都是连续存放的。

(6)一种数据类型或数据结构往往都占有一组连续的内存单元。 用“地址”这个概念并不能很好地描述一种数据类型或数据结构,而“指针”虽然实际上也是一个地址,但它却是一个数据结构的首地址,它是“指向”一个数据结构的。

3.指针的定义

        指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是0,则这个指针为空指针 定义一个指针变量:

4.指针类型说明  int p; //这是一个普通的整型变量 int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针 int p[3]; //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组 int *p[3]; //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组 int (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P 是一个指向由整型数据组成的数组的指针 int **p; //首先从P 开始,先与*结合,说是P 是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与int 结合,说明该指针所指向的元素是整型数据.由于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针. int p(int); //从P 处起,先与()结合,说明P 是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数,然后再与外面的int 结合,说明函数的返回值是一个整型数据 Int (*p)(int); //从P 处开始,先与指针结合,说明P 是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P 是一个指向有一个整型参数且返回类型为整型的函数的指针 int *(*p(int))[3]; //可以先跳过,不看这个类型,过于复杂从P 开始,先与()结合,说明P 是一个函数,然后进入()里面,与int 结合,说明函数有一个整型变量参数,然后再与外面的*结合,说明函数返回的是一个指针,,然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组,然后再与*结合,说明数组里的元素是指针,然后再与int 结合,说明指针指向的内容是整型数据.所以P 是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数. 二.变量的指针和指向变量的指针变量 1.指针变量的说明

一个指针变量 无论它指向的数据类型占几个字节,它自己本身只占四个字节(32位机)

指针变量是存放地址的变量

指针和指针变量是两个不同的概念

(1)变量的指针就是变量的地址。

(2)存放变量地址的变量是指针变量。

        在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个变量的地址或称为某变量的指针。

但是要注意:通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样。

        指针的本质就是一个操作受限的非负整数,它不能进行乘和除,只能进行加减。(相加在两个独立的指针没有意义,一般只用于数组间)。

2.定义一个指针变量

对指针变量的定义包括三个内容:

(1)指针类型说明,即定义变量为一个指针变量;

(2)指针变量名;

(3)变量值(指针)所指向的变量的数据类型。

指针变量的一般形式为:

类型说明符 *变量名;

其中, *表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指

针变量所指向的变量的数据类型。

例如: int *p1;

表示p1是一个指针变量, 它的值是某个整型变量的地址。 或者说p1指向一个整型变量。

至于p1究竟指向哪一个整型变量,应由向p1赋予的地址来决定。

再如: int *p2; /*p2是指向整型变量的指针变量*/ float *p3; /*p3是指向浮点变量的指针变量*/ char *p4; /*p4是指向字符变量的指针变量*/ 应该注意的是,一个指针变量只能指向同类型的变量,如P3 只能指向浮点变量,不能 时而指向一个浮点变量,时而又指向一个字符变量。

示例:

int i; //这就相当于申请了一个int类型房间, int *p; //这就相当与得到了一张能打开int类型房间的房卡 p = &i; //这相当于把房间的门牌号写到房卡上 *p = 1; //相当于先打开门进去了 再把1放入房间 p--;// 这相当于你去了这个房间的下一个房间

int* p;//p是变量的名字,int*表示p变量存放的是int类型变量的地址

//        int* p; 不表示定义了一个名字叫做*p的变量

//        int* p; 应该这样理解:p是变量名,p变量的数据类型是int * 类型

//         所谓int * 类型 就是存放int变量地址的类型

        int i=1;        p=&i;        前一个成立,后一个才生效,才能进行指针之间的赋值。

/****************************************************************************

1.p保存了i的地址,因此p指向i;

2.p不是i,i也不是p,更准确的说:修改p的值不影响i的值,修改i的值也不会影响p的值,

3.如果一个指针变量指向了某个普通变量,则

*指针变量 就完全等同于 普通变量

例子: 如果p是个指针变量,并且p存放了普通变量i的地址 则p指向了普通变量i *p就完全等同于i 或者说: 在所有出现*p的地方都可以替换成i 在所有出现i的地方都可以替换成*p *p 就是以p的内容为地址的变量

 

 

3.指针变量的引用

(1)指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。

(2)未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机。(俗称野指针)

(3)指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误。在C语言中,变量的地址是由编译系统分配的,对用户完全透明,用户不知道变量的具体地址。

两个有关的运算符:

1) &:取地址运算符。

2) *:指针运算符(或称“间接访问” 运算符) 。

C语言中提供了地址运算符&来表示变量的地址。

运算符的一般形式为:

&变量名;*变量名;

如&a表示变量a的地址, &b表示变量b的地址。变量本身必须预先说明。

指针的赋值方式:

指针只有赋值地址之后,才可以进行对于的运算操作,否则无效

(1)指针变量初始化的方法 int a; int *p=&a; (2)赋值语句的方法 int a; int *p; p=&a; 不允许把一个数赋予指针变量,故下面的赋值是错误的: int *p; p=1000; 被赋值的指针变量前不能再加“ *”说明符,如写为*p=&a 也是错误的。

        在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误 同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告

 4.指针的间接访问

        通过指针访问它所指向的一个变量是以间接访问的形式进行的,所以比直接访问一个变量要费时间,而且不直观,因为通过指针要访问哪一个变量,取决于指针的值(即指向)

例如:"*p2=*p1;"实际上就是"j=i;",前者不仅速度慢而且目的不明。

 但由于指针是变量,我们可以通过改变它们的指向,以间接访问不同的变量

指针变量可出现在表达式中, 设 int x,y, *px=&x; 指针变量px指向整数x,则*px可出现在x能出现的任何地方。例如: y=*px+5; /*表示把x的内容加5并赋给y*/ y=++*px; /*px的内容加上1之后赋给y, ++*px相当于++(*px)*/ y=*px++; /*相当于y=*px; px++ 或 y=*(px++) */ 直接上例子说明: main() { int a,b; int *pointer_1, *pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1, *pointer_2); }

对程序的说明:

1) 在开头处虽然定义了两个指针变量pointer_1和pointer_2, 担它们并未指向任何一个

整型变量。只是提供两个指针变量,规定它们可以指向整型变量。程序第6、 7行的作

用就是使pointer_1指向a, pointer_2指向b。

2) 最后一行的*pointer_1和*pointer_2就是变量a和b。 最后两个printf函数作用是相

同的。

3) 程序中有两处出现*pointer_1和*pointer_2,请区分它们的不同含义。

4) 程序第6、 7行的“pointer_1=&a”和 “pointer_2=&b”不能写成“*pointer_1=&a”和

“*pointer_2=&b”。

问题考虑:

请对下面再的关于“ &”和“*”的问题进行考虑:

1) 如果已经执行了“ pointer_1=&a; ”语句,则&*pointer_1是什么含义?         *pointer_1 已经取过地址,则就相当于变量a         &*pointer_1 = &a  地址,地址下有赋值,所以等于100

2) *&a含义是什么?         &a = pointer_1 ; 反过来就是 *pointer_1 的值即为变量a的值

3) (pointer_1)++和pointer_1++的区别?

1) &*pointer_1 其实就是取pointer_1 指向的地址,即a的地址,等价于 &a. 2) *&a 取a地址上的值,即a的值,为100; 3) 这两个是一样的,都是取pointer_1指向的地址,然后地址加1 int main() { int a=100; int *pointer_1; pointer_1=&a; printf("%d\n",&a); printf("%d\n",&*pointer_1); printf("%d\n",*&a); printf("%d %d\n",(pointer_1)++,pointer_1++); printf("%d\n",pointer_1); //地址执行了加2,int占4字节,所以地址加8 } 5.指针变量作为函数形参

        函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将

一个变量的地址传送到另一个函数中。        

void swap(int *p1,int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b);//输入两个数的时候注意要输入,隔开 pointer_1=&a;pointer_2=&b; if(a


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3