C语言中指针初了解

本文详细介绍了指针在内存中的工作原理,包括定义、使用方法、不同类型指针(如指针变量、野指针、空指针、万能指针)以及与数组(一维、二维和多级)的关系,还涵盖了指针在函数参数传递和返回值中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、指针

是直接访问内存的方式

内存地址:在内存空间中,对每一个字节都分配了一个唯一的编号,用于区别不同的位置。每个字节都有唯一的地址,用来和内存中的其他字节相区别

指针:在内存空间(定义变量)申请空间来存储地址,就叫做指针,也叫做指针变量

指针就是操作内存地址,使用内存地址

1、定义指针变量

指针变量:本质就是一个变量,存放的是一个内存地址

指针变量定义的形式:

指向数据类型     *  指针变量名;

指向数据类型:存储哪种类型数据的地址,指向哪种类型

指针变量:定义一个变量,用于存储地址,如果要存储哪种类型的地址,数据类型就是对应的类型

2、指针的使用

存储地址:

指针变量 = 地址(要求地址的空间能够使用)

变量的地址获取:通过 & 取地址运算符,得到变量的地址

指针变量 = &变量

指针变量访问内容:操作对应地址的数据,通过地址的方式访问数据

用变量名来表示代表变量中的值

用指针来访问变量:

*指针名   访问对应地址(指针存储的地址)的数据空间

int * p;

p = &a;

*p ; // ==== a  表示访问 p存储的地址(即a的地址),对应空间的空间

指针变量赋值地址:通过指针建立与对应内存空间联系

指针 取*:得到建立联系的内存空间的值

指针变量的初始化:

在定义指针变量时,进行赋值,就叫做初始化

类型 *  指针名 = 地址;

野指针:

指针记录的地址不明确(存储的地址不知道,或地址对应空间是否具有操作权限不确定),这种指针叫做野指针

野指针不需要直接进行 取 *

空指针:

指针记录的地址是NULL(地址:0x00),系统规定NULL地址不允许进行操作

只要操作就会报错

空指针通常表示,该指针当前不可用

万能指针:

void *  类型指针变量,可以存储任意类型的地址,也可以把指针赋值给其他的任意类型指针变量

void * 指针,指针存储地址,不能进行 取值操作(取 *),因为指向的类型未知不明确

3、指针的运算

指针 +  / -   整数,表示移动指针 指向 的位置

+:

指针 + 整数n

往地址增大方向,移动 n 个 指向(指针指向,指针存储哪种地址)的数据类型 大小

int * p;

p + 5 ==== >移动  5 * 4

指针 + n == 指针 + n * sizeof(指向类型)

-:

指针 - 整数

往地址减小方向,移动指针指向类型(指针存储哪种类型地址)的大小 * 整数大小

指针 - 整数 * sizeof(指向类型)

指针++:

先使用指针,然后 指针 = 指针 + 1

++指针:

先 指针 = 指针 + 1 ,然后再使用指针

指针--,--指针

指针 - 指针:

获取两个指针之间间隔多少个对应类型的数据

(指针 - 指针) / sizeof(指向类型)

4、指针与一维数组

一维数组是一段连续的空间存储多个数据元素,在数组中相邻的元素,间隔大小为每个元素类型的大小,即  &数组名[元素i] == &数组名[元素i-1] + 类型大小

指针能够进行运算,指针 + 1,移动一个数据类型的大小,即 指针 + 1 == 指针 + 指向类型大小

如果指针变量存储了数组中的元素地址,指针+1 ,就是数组中下一个元素的地址

指针与数组的操作方式:

可以通过指针访问整个数组

只要知道数组的起始地址(第零个元素的地址),就可以遍历整个数组

数组首地址:数组的起始地址,就是第零个元素的地址

int * p = &a[0];

*(p+n) == a[n]

在数组中,数组名 有个特殊作用。数组名就表示  数组的首地址

数组名,地址常量

int a[5];

a == &a[0]

数组首地址(数组名) + n:偏移n个数据元素大小

*(数组名 + n) == 数组名[n]

*(a + 3) == a[3]

基于数组名(常量地址),可以将数组名当做指针进行使用,除了不能赋值运算(a = a+1)

因为数组名可以表示数组首地址,而指针变量也可以存储数组首地址,在访问数组的操作时,指针变量和数组名作用一致,所以

数组名[n]:访问数组的n元素  ====  指针名[n]

int *p,a[5];

p = a;

p + n == a + n//等价

a[n] == *(p+n) == *(a+n) == p[n]

基于指针变量,可以将指针当做数组用,不能越界

字符串与字符数组

字符串:有多个字符组成一个连续且有序的字符序列

"abcdef"------字符串

C程序中,通过字符数组来存储字符串

字符数组通过访问数组中的元素,就是访问字符串(按照字符数组,每个元素单独访问)

如果需要整体访问字符数组中存储的字符串,要求在字符串结束的下一个字符位置存储'\0'

'\0'字符就表示 字符串的结束

字符数组存储字符串:

字符数组初始化存储字符串

char数组名[大小] = "字符串";

注意通常,在进行输入前把数组初始化全为'\0'

输入字符串到字符数组中

scanf("%s",数组名/首地址);

输出打印字符数组中的字符串

printf("%s",数组名);

常量字符串表示:

"acbde"-----常量字符串

在常量字符串中,在最后字符后默认包含'\0'字符

在程序中如果写出常量字符串,则常量字符串表示常量字符串的首地址(第零个字符地址)

如:“abccde”,得到就是字符串的首地址,地址常量

地址,指针类型,都是统一的大小,各个类型之间没有区别

32位机器:4B

64位机器:8B

5、指针与二维数组

二维数组:二维数组中,每个元素是一个一维数组,在元素(一维数组)中,每个成员就是一个值

二维数组:

数据类型数组名[行][列]

行:有多少个一维数组

列:一维数组的元素个数

对于二维数组而言,数组名是整个二维数组的首地址,第零个元素的地址,二维数组的元素都是一维数组,即二维数组数组名表示其中元素,整个一维数组的地址。

int a[3][4];

a == &a[0];//a[0]是整个一维数组

由于a表示整个元素的地址(一维数组的地址),所以进行指针运算时,+1 ,加上 整个一维数组大小

a:&a[0],第零个一维数组的地址

a+1:&a[1],第一个一维数组的地址

a+2:&a[2],第二个一维数组的地址

a[0]:表示二维数组的元素零,第零个一维数组,a[0]是一维数组的数组名,在这个一维数组的首地址  

a[0] == &a[0][0]

a[0]+1 == &a[0][1]

a[1]:第一个一维数组,也是这个一维数组的数组名(首地址)

a[1] == &a[1][0]

a[1]+1 == &a[1][1]

注意:

a+1,表示移动二维数组的一个元素(一维数组)大小

a[0]+1,表示移动一维数组的一个元素(数据类型值)大小

数组指针:

是一个指针,指针用于存储整个数组的地址,指针的指向类型为数组

定义:

数组元素类型   (*  指针变量名)[大小];

int (*p)[4];//定义一个指针变量,指针变量存储 整个数组的地址(int [4])

数组指针和二维数组名是等价的,因为二维数组表示第零个元素(一维数组)的地址

int a[3][4];

int (*p)[4];

p = a;//&a[0]

p+1 == a+1 == &a[1]

*(p+1) == a[1]

*(p+1)+2 == &a[1][2]

*(*(p+1)+2) == a[1][2]

6、多级指针与指针数组

指针数组:

是一个数组,只是每个元素为指针类型

指向类型 * 指针数组名[元素个数];

int * p[5];

定义 包含 5个元素 每个元素为指针(int *)

int a;

p[2] = &a;

多级指针:

一级指针:存储变量的地址

二级指针:存储一级指针的地址:一级指针类型 * 指针名;

三级指针:存储二级指针的地址:二级指针类型 * 指针名;

......

指向类型   * 指针名;

int **p;

int * a[10];

p = a;

p+1 == a+1;

*(p+2) == a[2]

二级指针与指针数组名等价

作业:

1、定义一个字符二维数组,输入要存储‘#’号的个数,然后分别输入存储的位置,其他位置默认存储 ‘ ’空格字符

2、二维数组和数组指针

int a[2][3];

int (*p)[3] = a;

在以下每个表达式中,p = a,求表达式的含义

a[0]

a[0][2]

*p

**p

*a

**a

*p++

**(p+1)

*(p+1)+1

*(*(p+1)+1)

3、定义二维数组,输入数据,然后求每个元素中的最大值

4、字符串的替换,输入一个原字符串,然后输入要替换的起始位置,输入新字符串进行替换

7、指针与函数

指针作为函数的参数:可以表示变量的地址,或者是数组名/数组首地址,作用就是表示参数为地址

把地址作为参数进行传递

返回值类型  函数名 (指针参数1,指针参数2); 接受传递的是地址

调用:

函数名(地址,地址/指针);

如果是数组作为形式参数,会由编译器自动变为对应类型指针

int sumarray(int p[10],int length) p就是指针 int*

指针作为函数返回值:返回一个地址,把指针作为函数的结果返回

函数指针:指针存储是的函数的地址

函数的类型表示:

返回值类型(参数1,参数2,参数3,......);

int (int a,char b);-1

int (int a,int b);-2

int (int c,int d);-3

1和2是不同函数类型,2和3是相同函数类型

函数指针表示:

返回值类型(* 指针变量名)(参数1,参数2,参数3,......)

函数地址:

函数名就是用于表示函数的地址

调用函数:

通过函数指针进行调用

函数指针名(实参);

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值