当前位置: 首页 > article >正文

2025_1_29 C语言学习中关于指针

1. 指针

指针就是存储的变量的地址,指针变量就是指针的变量。

1.1 空指针

当定义一个指针没有明确指向内容时,就可以将他设置为空指针

int* p = NULL;

这样对空指针的操作就会使程序崩溃而不会导致出现未定义行为,因为程序崩溃是宏观的,被察觉的,未定义行为是不被察觉的。
所以在操作一个不明确指针的时候,最好对它进行判空处理。

if (p == NULL){
	//为空的处理
}

1.2 野指针

只要指针指向的内存区域是未知的,那么该指针就是野指针。
因为指向的内存区域未知,那么操作该指针就会导致未定义行为

1.3 指针的传参

C语言函数的传参都是值传递的
这意味着当调用函数时,传递给函数的是实际参数的副本,而不是参数本身。因此,函数内部对参数的修改不会影响外部的实际参数。
那为什么指针作为参数传递时就会直接改变其指向的内容呢?
那是因为指针作为实参传递给函数的形参,这个形参是实参的拷贝,但是实参的形参都指向的是同一个地址空间。 相当于:

int a = 10;
int* p1 = &a;
int* p2 = &a;

p1和p2是两个不同的指针变量,但存储的内容是一样的。
即对指向那片内存空间的指针做出解引用改变的操作就会发生数值的改变。

void swap(int* a, int* b) {
	int tmp = *a; 
	*a = *b;
	*b = tmp;
}

void swap_ptr(int* a, int* b) {
	int* tmp = a;
	a = b;
	b = tmp;
}
void swap_ptr_pro(int** pa, int** pb) {
	int* tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
int main() {
	int a = 10, b = 20;
	swap(&a, &b);//改变
	printf("%d %d\n", a, b);
	int* pa = &a, * pb = &b;
	swap_ptr(pa, pb);//不改变
	printf("%d %d\n", *pa, *pb);
	a = 10, b = 20;
	swap_ptr_pro(&pa, &pb);//改变
	printf("%d %d\n", *pa, *pb);
	printf("%d %d", a, b);
	return 0;
}

上述代码swap函数就可以交换a和b的值,但是swap_ptr就不行,因为它交换的指针变量,而不是指向的值,交换指针变量是不会有结果的,因为他只是拷贝。
第三个函数swap_ptr_pro更是重量级,我在第二个函数中想通过交换两个指针变量来实现数值的交换,相当于

int* pa = a;
int* pb = b;
//转化为
int* pa = b;
int* pb = a;

这样直接printf(“%d %d\n”, *pa, *pb);就可以交换两个值,但是第二个函数交换的只是拷贝,不能实现,所以第三个函数我直接传二级指针,直接对一级指针pa,pb做修改。*pa就相当于pa的地址,这次我的形参是int ** a, int ** b.和&pa,&pb指向的是同一块内存,所以可以直接修改pa和pb,以实现交换 *pa和 *pb的值。

但是

printf("%d %d\n", *pa, *pb);
printf("%d %d", a, b);

这两句运行出来结果不一样,为啥?
在这里插入图片描述
这是因为我只交换了*pa和 *pb的值,而不是a和b的值。
交换a,b的值需要pa和pb
交换 *pa和 *pb的值需要&pa,&pb。

2.数组名于指针的关系

数组名可以看作是不可改变指向的指针,数组名可以看作是指向首元素的指针

只有两种情况下数组名才不代表首元素地址:
1:sizeof(arr) 这种情况下计算的是数组一共占用多少字节
2:&arr 和 arr相区别,arr代表的是数组的首元素地址,&arr代表数组的地址

2.1 数组指针和指针数组

数组指针:本质是一个指针,是一个指向数组变量的指针

int arr[4];
int(*p)[4] = &arr;

指针数组:本质是一个数组,是一个存储指针变量的数组,即数组存储的元素是指针变量

int* p[3] = {&a, &b, &c};

2.2常量指针和指针常量

int main() {
	int a = 10;
	const int* p1 = &a;
	int* const p2 = &a;
	int const* p3 = &a;
	return 0;
	}

const int * p1 = &a;

  • 含义:p1 是一个指向 const int 的指针。
  • 解释:p1 指向的值是 const 的,即不能通过 p1 修改它所指向的值。

int * const p2 = &a;

  • 含义:p2 是一个指向 int 的常量指针。
  • 解释:p2 本身是 const 的,即不能修改 p2 指向的地址,但可以通过 p2 修改它所指向的值。

int const * p3 = &a;

  • 含义:p3 是一个指向 const int 的指针。
  • 解释:p3 指向的值是 const 的,即不能通过 p3 修改它所指向的值。

const右边是只有指针变量,就限制的是这个指针变量,即这个指针变量不能再指向其他的值
const右边还有int或者,那么限制的就是指针变量指向的值,即指针指向的值不能修改


http://www.kler.cn/a/524851.html

相关文章:

  • 【Valgrind】安装报错: 报错有未满足的依赖关系: libc6,libc6-dbg
  • 【C语言】main函数解析
  • 二进制安卓清单 binary AndroidManifest - XCTF apk 逆向-2
  • Linux线程安全
  • [MySQL]事务的理论、属性与常见操作
  • 新增文章功能
  • 前端拖拽相关功能详解,一篇文章总结前端关于拖拽的应用场景和实现方式(含源码)
  • 【AI论文】Omni-RGPT:通过标记令牌统一图像和视频的区域级理解
  • 单机伪分布Hadoop详细配置
  • 萌新学 Python 之数值处理函数 round 四舍五入、abs 绝对值、pow 幂次方、divmod 元组商和余数
  • 利用飞书机器人进行 - ArXiv自动化检索推荐
  • Java基础知识总结(二十六)--Arrays
  • SpringBoot中@Valid与@Validated使用场景详解
  • 生成模型:扩散模型(DDPM, DDIM, 条件生成)
  • 2025年01月29日Github流行趋势
  • 【hot100】刷题记录(6)-轮转数组
  • [ASR]faster-whisper报错Could not locate cudnn_ops64_9.dll
  • AI编译器之——为什么大模型需要Relax?
  • 房屋租赁系统如何借助智能化手段提升管理效率与租客体验
  • 剑指 Offer II 008. 和大于等于 target 的最短子数组
  • 【2024年华为OD机试】(A卷,200分)- 查找树中元素 (JavaScriptJava PythonC/C++)
  • 10.3 LangChain实战指南:解锁大模型应用的10大核心场景与架构设计
  • 【C语言练习题】计算16位二进制数所表示的有符号整数
  • 万物皆有联系:驼鸟和布什
  • Github 2025-01-29 C开源项目日报 Top10
  • TPA注意力机制详解及代码复现