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=&num;
//空指针不可以*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会进行安全检查,其他编译器未必
使用没有初始化的指针,程序一般会崩溃
不可以打印空指针的内容

posted @   千年风雅丶  阅读(351)  评论(0编辑  收藏  举报
编辑推荐:
· 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训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示