C语言指针学习笔记

简介: C语言指针学习笔记

指针归纳

2.1:指针的自述

2.1.1:指针的告白

首先,理解一下下面几个定义:

内存的地址:

在程序运行时,操作系统要为代码和程序所需的数据分配特定的内存空间,在程序运

行过程中:对数据的访问就是对数据所分配的内存空间的访问,为了便于管理内存,每个

储存单元都有一个唯一的编号,这些单元的编号称为内存单元的地址,就像门牌号一样。

变量的地址:

在 C 语言程序定义一个变量,根据变量类型的不同,系统会为其分配一定字节数的存

储空间,所分配的存储空间的第一个存储单元的地址即为该变量的地址。

直接寻址与间接寻址:

直接寻址:在执行 scanf(“%d”,&a)时,若从键盘输入 6,则 6 将被送往例如起始地址

为 20 的 21,22,23 四字节的内存空间中,在执行 printf(“%d”,a);语句时,系统根据变量

名和地址的对应关系找到地址 20,然后从 20 开始的四个字节中取出整数 6. 间接寻址:定义一个特殊的变量 p,这个变量可以存放变量 a 的地址,如果通过变量 p

存取 a 的值的过程:首先找到存放变量 p 的地址,然后在这个地址里找到 a 的地址,再从 a

的地址里找到 a 的值。

实质:变量的地址就是指针

C 语言允许定义专门用来存放地址的特殊变量,称为指针变量。一个变量的地址称为

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


2.1.2:指针变量的定义和初始化

1.指针变量的定义

C 语言规定所有变量都必须先定义再使用,指针亦如此

cbec93e3487a49228255d67d7f41439d.png

注意:一个指针变量只能指向同一数据类型的变量,原因:不同数据类型的数据需要存储

的字节数可能是不同的。


2.指针变量的初始化

说明:

和普通变量一样,如果指针变量是非静态局部变量且未初始化,那么它的值是不确定的。

指针变量初始化的一般格式

82c0413212ab4b69a874c22c41ee8155.png

注意:

1》用于初始化的变量必须已定义且类型一致

2》可以使用已初始化的指针变量给另一个相同数据类型的指针变量做初始值。

bfd26bacca07479f9652ee31bc29c173.png

3》不能用 0 以外的常量作为指针变量的初值,可以初始化为一个空指针

72e881d11e5841a3ae4577e035b620a7.png

和普通变量一样,对于外部或静态指针变量若未初始化,则自动被初始化未 NULL,

它的值为零

局部指针变量若未初始化,则它的值是不确定的,因而指向了一个不确定的单元,若

这时引用指针变量,可能会产生不可预料的后果(影响操作系统的工作)。

4》不能用一个自动(auto)型的变量的地址去初始化一个 static 型的指针

46aebe33cf7a4533a117e1ca4c80022d.png

5》void *类型指针表示无类型指针,可以指向任意类型的数据(在被任意类型数据指

向时需要强制转化),无需强制类型转换


2.1.3:指针的运算

指针运算的实质就是地址的运算;

1.指针的赋值运算

(1)将变量的地址赋值给指针变量,使指针指向该变量

88efe16d08c346ae85d8b84bf26eb902.png

**(2)指针变量间的赋值

类型一致的指针变量可以相互赋值

例如:

int a=&c;

int b=NULL;

b=a;

2.通过取内容运算符,访问目标变量

p=a;//将变量 a 的值赋给以 p 的值为地址的存储区域

c=pb;//将 pb 内存区域里的数据赋给 c

3.指针的加减运算

(1).在指针变量指向数组的第一个元素,n 为一个整数,则 p+n 表示指向下标为 n 的元素

改变 nsizeof(指针的数据类型)个字节的距离

(2).两个指针变量在一定条件下,可以减法运算

当两个指针变量 p 和 q 指向同一个数组,则 p-q 的绝对值表示 p 所指数组元素与去所值数

组元素之间相差的元素个数,为 1 表示相邻,除数组外,其他减法无意义

4.指针的关系运算

只有相同类型的指针才能进行关系运算;另外指针变量还可以和数值 0 进行关系运算的相

等或不等的运算,和其他的不能


2.1.4:一级指针的说明

1.一维数组与指针

实际上,数组名就是一个指针,是数组在内存中的起始地址(数组的指针),即第 0 号元

素的地址,是一个地址常量(指针常量)。数组元素的指针是指数组元素在内存里的地址

案例:

int a[10];

int *p=a;

已知 p 是指向一个 int 型的指针,而 a 是一个数组名。为什么能把数组名赋给一个指针变量

呢?原因是数组名 a 是数组在内存分配到的空间的首地址。在这里,a 是一个指向数组 a 的

第一个元素的指针。或者说,a 也是一个指向 int 类型的指针,与 p 属于同一类型。只不过,

a 是一个指针常量,它的值是不可改变的,而 p 是指针变量。

*p=a[0]=p[0]

*(p+1)=a[1]=p[1]; *(p+2)=a[2]=p[2]; (p+3)=a[3]=p[3]; (p+4)=a[4]=p[4];

注意:

(1)数组名 a 是指针常量,不能作为指针变量使用,像 a++就不行

(2)在使用数组引用数组元素时,系统不做下标越界检查。所以需要注意指针访问越界

(3)p++相当于(p++)。因为和++同优先级(p++)表示先取“*p”,再使 p 加

1。

引用一维数组的方法:

(1)下标法,a[i],简单直观

(2)用指针访问各元素“*P”,效率高,其他不介绍

牢记:数组名是一个常指针,它的值是无法改变


2.二维数组与指针

首先,理解一下二维数组:就是一个一维数组的元素又是一个一维数组

形如:int a[2][3]={{1,2,3},{1,2,3}};

所以在一维数组里理解,a 在这里是指向一维数组的指针常量

形如:int()[4];

这样 a 则代表第 0 行的首地址

(1)&a[i]和 a+i 表示第 i 行的首地址,

(2)该行的其他元素地址可以用数组名加序号就行。如:(a[i]+1),(a[i]+2);//???

注意:

(1):a+i、&a[i]、(a+i)、&a[i][0];的值相等,但含义不同

(2):a+i 和&a[i]表示第 i 行的首地址,指向行

(3):a[i]、*(a+i)、&a[i][0]表示第 i 行第零列元素地址,指向列

区分二维数组的三种表现形式:

a[i][j], *(a[i]+j), ((a+i)+j)。

也可以定义一个一维数组的指针变量

形如:

int a[2][4]={0};

int (*p)[4]=a;//定义 p 为指向一个有 4 个 int 元素的一维数组的指针变量

注意:这里的 p 为指向一维数组的行指针

2.指针形式的字符串操作

字符指针定义格式

char *指针变量名

char *from=“zhaokexue”

Printf(“%s”from);


3.区分指针数组和数组指针

指针数组:是相同类型指针变量的集合,即数组的每一个元素都使指针且具有相同的存

储类别,并指向相同的数据类型

Char p[5]={“sgvfgh”,”sdgsdhhs”};//[]的优先级比的高

数组指针:

指向数组的指针

int a[10];

int *p=a;

p 是指向数组的指针


4.指向结构体变量的指针变量

18c0ad39848e4904ad231d26d36527e1.png


2.1.5:指针与函数

(1):指针作为函数参数

1》函数实参形参都为指针变量

使用原因:早期的使用值传递方式,形参值的改变无法回传给实参。

而使用指针作实参和形参,实现了“址传递”可以将在改变形参的值的同时改变实参

2e0d7d804f8a4964ab5e969dc3fb087f.png

划线部分实参做地址


(2):区分指针函数和函数指针

指针函数:函数的返回值为指针的函数

定义格式:

int *p(int *,int *)

{

函数体部分;

}

函数指针:指向函数的指针

解释:在 C 程序在编译时,每个函数都有一个入口地址(函数名),其值是函数的首条命

令的地址。把一个函数名赋值给指针变量,该指针变量就是指向函数的指针,此后通过指

针调用函数,就如同用指针引用普通变量一样。

函数指针有两个用途:(1):调用函数(2):做函数的参数。

C++程序实例:

int swap(int *p1,int *p2,int *p3)

int (*p)(int *

,int *

, int *)(swap);// 此为函数指针声明加初始化(C++中)

c 程序实例:

int max(int x,int y)

{

}

int (*ptr)(int x,int y);//声明函数指针

Ptr=max;//将函数的入口地址赋值给指针变量 ptr

注意:要赋给函数指针的函数应该和函数指针所指的函数类型一致


2.1.6:二级指针的说明

指针的表现形式是地址,核心是指向关系指针,运算符“*”的作用是按照指向关系访问所

指向的对象.如果存在 A 指向 B 的指向关系,则 A 是 B 的地址,“*A”表示通过这个指向关

系间接访问 B.如果 B 的值也是一个指针,它指向 C,则 B 是 C 的地址,“*B”表示间接访

问 C 如果 C 是整型、实型或者结构体等类型的变量或者是存放这些类型的数据的数组元素,

则 B(即 C 的地址)是普通的指针,称为 一级指针,用于存放一级指针的变量称为 一级指针

变量。

A(即 B 的地址)是指向指针的指针,称为 二级指针,用于存放二级指针的变量称为 二

级指针变量.根据 B 的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针

2ce26809136b48d495f2828d888c4cf0.png


二级指针的分类

(1)指向指针变量的指针

在如上的 A 指向 B、B 指向 C 的指向关系中,如果 A、B、C 都是变量,即 C 是普通变

量,B 是一级指针变量,其中存放着 C 的地址,A 是二级指针变量,其中存放着 B 的地址,

则这 3 个变量分别在内存中占据各自的存储单元,它们之间的相互关系下图所示,相互之

间的前后位置关系并不重要.此时,B 是一级指针变量,B 的值(即 C 的地址)是一级指针数

据;A 是二级指针变量,A 的值(即 B 的地址)是二级指针数据.


(2)指向数组的指针

在 C 语言中,数组与其它变量在使用上有很大的不同.无论是字符型、整型、实型变

量,还是结构体类型或者指针类型的变量,语句中出现变量名都代表对该变量所在内存单元

的访问,变量名代表整个变量在内存中的存储单元,可以向该变量赋值,也可以从中取出数

据使用.但是定义一个数组之后,数组名并不代表整个数组所占据的内存单元,而是代表数

组首元素的地址


相关文章
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
236 1
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
381 7
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
10月前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
179 0
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
1316 9
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
1130 13
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
364 7
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
389 11
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
723 3