C/C++实践笔记 019指针深入理解与最佳实践
1.C语言最强悍的功能——指针
没有赋值,野指针
指针的最大意义是间接赋值
2.内存
取地址在CPU的寄存器产生,不占内存
地址计算机总线,地址作为常量不消耗内存
p是一个变量,间接赋值,存储不同的地址
3.内存与指针
内存中每个字节都有一个编号——地址
*p根据地址赋值,根据类型解析
double *p;
sizeof(p);//四个字节,任何类型的地址都一样
sizeof(*p);//8,根据地址往前读8个字节,double类型
类型决定了步长,决定了解析方式
4.间接赋值
#include<stdlib.h> #include<stdio.h> void change(int num)//传值副本机制,改变的不是原来的 { num = 3; printf("\nchange=%d", num); } void changep(int *p)//传址,副本机制新建一个指针变量存储&num { *p = 3; } void main() { int num = 10; changep(&num);//&num没有实体 printf("\n%d", num); getchar(); //传值和传址都有副本机制,传值拷贝的是数据,传址拷贝的是地址 }
5.空类型指针
void *p;//合法,因为内存大小明确,任何类型地址都一样
但void *p不能间接取值和赋值,非法的间接寻址,因为不知道类型大小,可以*((double *)p)强制转换一下
6.空指针
double *p=NULL; //指针没有存储地址,有地址了可以p=# //空指针不可以*p=1取地址
空指针标记指针是否存储地址
7.指针的声明以及double、typedef
double * p1,p2; //4,8 指针sizeof大小为4,double的sizeof大小为8 #define double*后和它一样 //typedef后是4,4
8.银行报表
数据映射
#define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> //指针可以用于不允许改变原来数据的情况下,实现排序 void main() { int num1; int num2; scanf("%d,%d", &num1, &num2); int *p1 = &num1; int *p2 = &num2; if (*p1 < *p2) { int *ptemp = p1; p1 = p2; p2 = ptemp; } printf("%d,%d", *p1, *p2); system("pause"); }
指针数组
void sec(const int *p) //报表,const在X左边,限定数据只能读不可写 { }
指针数组法冒泡排序,不改变原来的数据:
#include<stdlib.h> #include<stdio.h> int a[8] = { 1,8,2,7,3,6,4,5 }; const int * p[8] = { &a[0],&a[1],a + 2,a + 3,a + 4,a + 5,a + 6,a + 7 }; void main() { printf("原来数组的数据\n"); for (int i = 0; i < 8; i++) { printf("%d\n", a[i]); } printf("原来的指针数组指向数据\n"); for (int i = 0; i < 8; i++) { printf("%d\n", *p[i]); } for (int i = 0; i < 8 - 1; i++) { for (int j = 0; j < 8 - 1 - i; j++) { if (*p[j] > *p[j + 1]) { int * ptemp = p[j]; p[j] = p[j + 1]; p[j + 1] = ptemp; } } } printf("排序后数组的数据\n"); for (int i = 0; i < 8; i++) { printf("%d\n", a[i]); } printf("排序后指针数组指向数据\n"); for (int i = 0; i < 8; i++) { printf("%d\n", *p[i]); } system("pause"); }
9.地址输入
scanf 不需要带0x,必须大写
10.桌面绘图
11.打印指针以及地址
%x按照十六进制打印
%p按照地址打印
%p显示地址的位数,32位,8个十六进制位,2^4=16,8*4=32位
%p显示地址的位数,64位,16个十六进制位,4位表示16,16*4=64个二进制位
12.扩展scanf初始化指针
#define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> int main() { int num1 = 100; int num2 = 200; printf("%p,%p", &num1, &num2);//打印指针 int *p = NULL;//指针初始化 scanf("%p", &p);//扫描初始化一个指针,根据指针的地址初始化指针 printf("%p,%d", p, *p);//打印指针以及指针指向的内容 //指针不可以乱指,否则会出现程序崩溃 system("pause"); }
13.扩展野指针与空指针
指针一定要初始化,没有初始化的指针叫野指针,指向不确定的内存地址
VS2013会进行安全检查,其他编译器未必
使用没有初始化的指针,程序一般会崩溃
不可以打印空指针的内容
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人