3.8day06
创始人
2024-06-01 16:02:43
0

指针和内存单元

指针: 地址。

内存单元: 计算机中内存最小的存储单位。——内存单元。大小一个字节。 每一个内存单元都有一个唯一的编号(数)。

称这个内存单元的编号为 “地址”。

指针变量:存地址的变量。

指针定义和使用:

int a = 10;

int *p = &a;int* p;--- windows;int *p ---Linux int * p ;

int a, *p, *q, b;

*p = 250;指针的 解引用。 间接引用。

*p : 将p变量的内容取出,当成地址看待,找到该地址对应的内存空间。

如果做左值: 存数据到空间中。

如果做右值: 取出空间中的内容。

任意“指针”类型大小:

指针的大小与类型 无关。 只与当前使用的平台架构有关。 32位:4字节。 64位: 8字节。

野指针:

1) 没有一个有效的地址空间的指针。

int *p;

*p = 1000;

2)p变量有一个值,但该值不是可访问的内存区域。

int *p = 10;

*p = 2000;

【杜绝野指针】

空指针:

int *p = NULL; #define NULL ((void *)0)

*p 时 p所对应的存储空间一定是一个 无效的访问区域。

但是,野指针和有效指针变量保存的都是数值,为了标志此指针变量没有指向任何变量(空闲可用),C语言中,可以把NULL赋值给此指针,这样就标志此指针为空指针,没有任何指针。

万能指针/泛型指针(void *):

可以接收任意一种变量地址。但是,在使用的时候【必须】借助“强转”具体化数据类型。

char ch = 'R';

void *p; // 万能指针、泛型指针

p = &ch;

printf("%c\n", *(char *)p);//*与()的优先级相同,计算的时候从右向左依次执行

const关键字:

修饰变量:

const int a = 20;

int *p = &a;

*p = 650;

printf("%d\n",a);

修饰指针:

const int *p;

可以修改 p

不可以修改 *p。

int const *p;

同上。

int * const p;

可以修改 *p

不可以修改 p。

const int *const p;

不可以修改 p。

不可以修改 *p。

总结:const 向右修饰,被修饰的部分即为只读。

常用:在函数形参内,用来限制指针所对应的内存空间为只读。

指针和数组:

数组名:

【数组名是地址常量】 --- 不可以被赋值。 ++ / -- / += / -= / %= / /= (带有副作用的运算符)

指针是变量。可以用数组名给指针赋值。 ++ --

取数组元素:

int arr[] = {1,3, 5, 7, 8};

int *p = arr;

arr[i] == *(arr+0) == p[0] == *(p+0)

指针和数组区别:

1. 指针是变量。数组名为常量。

2. sizeof(指针) ===》 4字节 / 8字节

sizeof(数组) ===》 数组的实际字节数。

指针++ 操作数组:

int arr[] = { 1, 2, 4, 5, 6, 7, 8, 9, 0 };

int *p = arr;

for (size_t i = 0; i < n; i++)

{

printf("%d ", *p);

p++; // p = p+1; 一次加过一个int大小。 一个元素。

}

p的值会随着循环不断变化。打印结束后,p指向一块无效地址空间(野指针)。

指针加减运算:

数据类型对指针的作用:

1)间接引用:

决定了从指针存储的地址开始,向后读取的字节数。 (与指针本身存储空间无关。)

2)加减运算:

决定了指针进行 +1/-1 操作向后加过的 字节数。

指针 * / % : error!!!

指针 +- 整数:

1) 普通指针变量+-整数

char *p; 打印 p 、 p+1 偏过 1 字节。

short*p; 打印 p 、 p+1 偏过 2 字节。

int *p; 打印 p 、 p+1 偏过 4 字节。

2)在数组中+- 整数

short arr[] = {1, 3, 5, 8};

int *p = arr;

p+3;// 向右(后)偏过 3 个元素

p-2;// 向前(左)偏过 2 个元素

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
#include 
#include // 指针在数组中 +- 整数
int main0601(void)
{int a[] = { 1, 2, 4, 5, 6, 7, 8, 9, 0 };//int *p = a; // a == &a[0];int *p = &a[5];printf("p-2 = %p\n", p - 2);//010FFD34printf("&a[3] = %p\n", &a[3]);//010FFD34system("pause");return EXIT_SUCCESS;
}// &数组名 +1
int main0602(void)
{short a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };printf("a = %p\n", a);//0133FD64printf("&a[0] = %p\n", &a[0]);//0133FD64printf("a+1 = %p\n", a+1);//0133FD68printf("&a   = %p\n", &a);//0133FD64printf("&a+1 = %p\n", &a + 1);//0133FDD8     &a+1 是+一整个数组的大小system("pause");return EXIT_SUCCESS;
}// 指针加减指针
int main0603(void)
{int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int *p = a;for (size_t i = 0; i < 10; i++){printf("%d ", *p);p++;}printf("p - a = %d\n", p - a);system("pause");return EXIT_SUCCESS;
}

3)&数组名 + 1

加一个数组的大小(数组元素个数 X(乘) sizeof(数组元素类型))

printf("&a+1 = %p\n", &a + 1);//0133FDD8 &a+1 是+一整个数组的大小

指针 +- 指针:

指针 + 指针: error!!!不允许的

指针 - 指针:

1) 普通变量来说, 语法允许。无实际意义。【了解】

2) 数组来说:偏移过的元素个数。

#include int main()
{int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };int *p2 = &a[2]; //第2个元素地址int *p1 = &a[1]; //第1个元素地址printf("p1 = %p, p2 = %p\n", p1, p2);int n1 = p2 - p1; //n1 = 1int n2 = (int)p2 - (int)p1; //n2 = 4printf("n1 = %d, n2 = %d\n", n1, n2);return 0;
}

指针实现 strlen 函数:

char str[] = "hello";

char *p = str;

while (*p != '\0')

{

p++;

}

p-str; 即为 数组有效元素的个数。

指针比较运算:

1) 普通变量来说, 语法允许。无实际意义。

2) 数组来说:地址之间可以进行比较大小。

可以得到,元素存储的先后顺序。

3) int *p;

p = NULL;// 这两行等价于: int *p = NULL;

if (p != NULL)

printf(" p is not NULL");

else

printf(" p is NULL");

指针数组:

一个存储地址的数组。数组内部所有元素都是地址。

1)

int a = 10;

int b = 20;

int c = 30;

int *arr[] = {&a, &b, &c}; // 数组元素为 整型变量 地址

2)

int a[] = { 10 };

int b[] = { 20 };

int c[] = { 30 };

int *arr[] = { a, b, c }; // 数组元素为 数组 地址。

指针数组本质,是一个二级指针。

二维数组, 也是一个二级指针。

多级指针:

int a = 0;

int *p = &a; 一级指针是 变量的地址。

int **pp = &p;二级指针是 一级指针的地址。

int ***ppp = &pp;三级指针是 二级指针的地址。

int ****pppp = &ppp;四级指针是 三级指针的地址。【了解】

......

多级指针,不能 跳跃定义!

对应关系:

ppp == &pp;三级指针

*ppp == pp == &p; 二级指针

**ppp == *pp == p == &a一级指针

***ppp == **pp == *p == a普通整型变量

*p : 将p变量的内容取出,当成地址看待,找到该地址对应的内存空间。

如果做左值: 存数据到空间中。

如果做右值: 取出空间中的内容。

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...