C语言指针基础

本文详细讲解了C语言指针的基础概念,包括指针定义、类型与所指类型、内存区域、运算与注意事项。通过实例演示了指针在内存管理和数据操作中的关键作用,以及常见的错误和解决方案,特别介绍了万能指针和不同类型的指针。

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

C语言指针基础

什么是指针

指针就是一个地址,那么如何获取地址?用的是&:即取地址符

  • 指针是一个整数
  • 获取指针: *

指针变量

  • 用来存放地址,也就是存放一个特定的整数(这个的整数可以表示地址)
  • 如何产生一个指针变量
    • 类型* 变量名;
  • 指针变量的两个重要概念
    • 指针的类型: 去掉变量名
    • 指针所指向的类型:去掉变量名和*号
    • 用指针的时候需要保持上述两个类型的一致
int* p;
//类型: int*
//所指向的类型: int  --->本质就是指针所操作数据类型	
  • 不同类型的指针变量
    • 所有类型指针占用的字节数都是相同 32位系统下都是4个字节
    • 特殊的指针类型: void* (可以转化为任意类型)
  • 专门用来初始化指针变量的东西:NULL
    • NULL 即 (void*)0
    • 防止悬浮指针
    • 防止野指针
  • 指针变量获取当前地址中的值: *指针变量

指针的运算

  • *指针变量: 指针变量所指向的内存存储的值
  • p+n或者p-n操作:实质是内存字节偏移,和指向内存存储的数据类型有关
    • 求偏移量:p+sizeof(指针所指向的类型)*n
    • 对于一个指针变量来说,不会单独的去偏移,一般要指向一段内存做偏移(例如对数组做偏移)
    • p++ 和p-- 也算p+n
    • 对于不同类型的指针之间是没有什么算术运算的

内存的四区

在这里插入图片描述

#include <stdio.h>
void print() 
{
	static int num = 1;		//放入全局区的静态变量,这个代码运行的时候只执行一次
	//不做初始化默认为0
	num++;
	printf("%d\n", num);
}
int main()
{
	print();		//num=2;
	print();		//num=3;
	return 0;
}

关于指针容易出错的地方

#include<stdio.h>
int main() 
{
	//NULL 即 (void*)0
	int* p = NULL;	//0存放在常量区
	//*p = 1234;		//不能修改0所在的内存 会出现写入访问权限冲突
	//printf("%d", *p);	
#include<stdio.h>
int main()
{
	char* str = "ILoveyou";  //解析: 把这段内存的首地址赋值给指针变量str
	char* pchar;
	puts(str);
	pchar = "ILoveyou";
	//*pchar = 'M';		   //写入访问权限冲突。
	//字符串位于常量区,不能被修改
	puts(pchar);
	return 0;
}
#include<stdio.h>
int main()
{
	//数组位于栈区
	char array[10] = "ILoveyou";//将字符串放入数组中
	pchar = &array[0];
	*pchar = 'M';//位于栈区的数据可以被改变
	puts(array);
}
#include <stdio.h>
char* returnPoint() 
{
	//函数调用完,内存会被系统回收(清除所有数据)
	//所以不允许返回局部变量地址
	char array[10] = "ILoveyou";
	//%s 打印方式:从首地址开始,打印到\0
	char* p = &array[0];
	return p;
	//解决方法:把数据存到栈区,返回堆区这段内存的首地址
}
int main() 
{
	int* result = returnPoint();
	puts(result);
	puts(result);
	puts(result);
	puts(result);
	//因为函数被调用完后,数据会被回收,所以就读取不到指针所指向的地址中的数据
	return 0;
}

万能指针

  • 什么是万能指针
    • 万能指针就是void* 类型的指针变量
    • 万能指针在访问数据的时候必须做强制类型类型
    • 万能指针应用: 统一接口(统一函数传参)
#include <stdio.h>
int main() 
{
	int num = 10;
	void* pVoid = &num;    //解析方式: pVoid=&num; 不是*pVoid=&num;
	printf("%d\n", *(int*)pVoid);
	double dNum = 1.11;
	pVoid = &dNum;
	printf("%.3lf\n", *(double*)pVoid);
	//万能指针使用的时候要强制转换为目标类型(就指向数据类型的指针)
	return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值