首页 > 其他分享 >鹏哥C语言79-81---野指针+指针运算

鹏哥C语言79-81---野指针+指针运算

时间:2024-10-16 18:21:36浏览次数:3  
标签:arr return int 鹏哥 C语言 vp ++ 指针

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

//----------------------------------------------------------------------------------------------------------3. 野指针
// 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
//---------------------------------------------------------------------------------------------3.1 野指针成因
//-------------------------------------------------1.没有初始化

int main()
{
    int* p;
    //p没有初始化,没有明确指向
    //一个局部变量如果不初始化的话,放的是随机值0xcccccccc

    *p = 10; //非法访问内存 这里的p就是野指针

    return 0;
}

//-------------------------------------------------2. 指针越界访问

int main()
{
    int arr[10] = { 0 };
    int* p = arr;// &arr[0]
    int i = 0;
    for (i = 0; i <= 10; i++) //当指针指向的范围超出数组arr的范围时,p就是野指针
    {
        *p = i;
        p++;
    }

    return 0;
}

//-------------------------------------------------3. 指针指向的空间释放

int* test()
{
    int a = 10;
    return &a;
}

int main()
{
    int* p = test();
    //p是野指针,局部变量 a 在函数调用结束后就销毁了,但是 a 的地址被保存到了 p 里,
    //根据p 里保存的地址,不能再访问到局部变量 a, 所以 p 就成了野指针

    return 0;
}

//---------------------------------------------------------------------------------------------3.2 如何规避野指针
(1). 指针初始化
(2). 小心指针越界
(3). 指针指向空间释放即使置NULL
(4). 避免返回局部变量的地址
(5). 指针使用之前检查有效性

int main()
{
    int a = 0;
    int* p = &a; 
    *p = 20;

    int* p1 = NULL; //初始化空指针 0 
    *p1 = 100; // 错误 ×××××××××× 空指针不能直接访问
    
    //空指针怎么用?
    int* p2 = NULL;
    if (p2 != NULL)
    {
        *p2 = 100;
    }

    return 0;
}
int* test()
{
    int a = 10;
    return &a;
}

int main()
{
    int* p = test();
    if (p != NULL)
    {
        printf("%d\n",*p); // 10 
        //函数调用结束后存储局部变量 a 的那块空间被释放了,
        //但是内存中这块空间依旧在操作系统中,如果没有被覆盖,里边的内容依旧存在
    }

    return 0;
}

//-----------------------------------------------------------------------------------------------------------4. 指针运算
1 指针+-整数
2 指针-指针 
3 指针的关系运算//----------------------------------------------------------------------------------------4.1 指针+-整数
//---------------------------------------------------------例一

#define N_VALUES 5
int main()
{
    float values[N_VALUES];
    float* vp;
    //指针+-整数;指针的关系运算
    for (vp = &values[0]; vp < &values[N_VALUES];)
    {
        *vp++ = 0; //  先*vp=0, 后vp++

        //*vp++;  先 *vp,然后地址vp++;
        // (*vp)++; 对vp指向的对象进行++,也就是地址里的内容++。
    }
    return 0;
}

//---------------------------------------------------------例二
//让数组内每个元素都为1

int main()
{
    int arr[10] = { 0 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    //--------------------方法1:通过数组下标
    for (i = 0; i < sz; i++)
    {
        arr[i] = 1;
    }
    //--------------------方法2:通过指针
    int* p = arr;
    for (i = 0; i < sz; i++)
    {
        *p = 1;
        p++;
    }
    //--------------------方法3:通过指针优化版
    int* p = arr;
    for (i = 0; i < sz; i++)
    {
        *(p+i) = 1;
    }

    return 0;
}

//-------------------------------------------------------------------------------------4.2 指针-指针 
  |指针-指针|  得到的是两个指针之间元素的个数
 不是所有的指针都能相减,指向同一块空间的指针相减才有意义

int main()
{
    // 指向同一块空间的指针相减才有意义
    int arr[10] = { 0 };
    printf("%d\n", &arr[9] - &arr[0]);// 9 
    printf("%d\n", &arr[0] - &arr[9]);// -9 

    //两者不在同一块空间内,相减没意义
    int arr1[5] = { 0 };
    char arr2[10] = { 0 };
    printf("%d\n", &arr1[4] - &arr1[0]); 

    return 0;
}

//指针相减的用法

//--------------------------------------版本1:地址++
int my_strlen(char* str)
{
    int count = 0;
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}

//--------------------------------------版本2:递归
int my_strlen(char* str)
{

}

//--------------------------------------版本3:指针-指针
int my_strlen(char* str)
{
    char* start = str;
    while (*str != '\0')
    {
        str++;
    }
    return (str - start);
}

// 自己实现 strlen 函数的作用
int main()
{
    //char arr[10] = "abcdef";
    int len = my_strlen("abcdef"); //传过去的是字符串的首地址
    printf("%d\n", len); //6

    return 0;
}

//-----------------------------------------------------------------------------------------4.3 指针的关系运算
(比较大小)

#define N_VALUES 5
int main()
{
    float values[N_VALUES]; // 有五个元素的数组
    float* vp;

    for (vp = &values[N_VALUES]; vp > &values[0];) //指针相比较
    {
        *--vp = 0;  // vp--, *vp=0
    }

    //简化版,不推荐(可能不符合标准)
    for (vp = &values[N_VALUES-1]; vp > &values[0] ; vp--) 
    {
        *vp = 0; 
    }
    //标准规定
    //允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,
    // 但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

    return 0;
}

标签:arr,return,int,鹏哥,C语言,vp,++,指针
From: https://blog.csdn.net/most_wanted_/article/details/142988628

相关文章

  • 对带有指针类型的切片进行循环时避坑
    func(sp*scrapePool)sync(targets[]*Target){//加锁 sp.mtx.Lock() defersp.mtx.Unlock() var(//target标记 uniqueTargets=map[uint64]struct{}{}//采集周期 interval=time.Duration(sp.config.ScrapeInterval)//采集超时时间 timeout......
  • c语言分支和循环(上)
    1.if语句if语句后面不加分号,默认情况下if和else语句后面只能跟一条语句,如果要使用多条语句,可以用{}将想要多条表达的式子放进去#include<stdio.h>intmain(){intnum=0;//输入scanf("%d",&num);//一定别忘了取地址//判断和输出if(num%2==1)//......
  • C语言手撕实战代码_线索二叉树_先序中序线索二叉树_树的先根遍历_后根遍历_树的度_孩
    文章目录1.设计算法构造一棵先序线索二叉树2.先序线索二叉树的先序遍历算法3.设计算法构造一棵中序线索二叉树4.遍历中序线索二叉树5.树的先根遍历和后根遍历6.树T的叶子结点个数7.计算一棵以孩子兄弟表示的树T的度,该算法的时间复杂度为O(n)8.计算树孩子兄弟链表表示的T......
  • C语言中的“宏”以及宏的使用
    在C语言中,宏是一种预处理器指令,主要通过 #define 来定义。宏可以在编译时进行文本替换,使代码更加简洁和可读。如有问题,请指正!以下是C语言宏的几个主要应用场景:1.常量定义使用宏定义常量,可以避免在代码中出现魔法数字,使代码更加易于维护。#definePI3.14159floatra......
  • 在 C 语言中通过指针访问结构体内存
    在C语言中,指针是用于引用内存地址的变量,通过指针可以有效地访问和操作内存。即使未显式创建结构体实例,只要指向的内存区域足够大且对齐方式正确,指针也能够按照特定结构体的布局访问数据。以下是这个机制的详细解读。1.指针与内存布局指针的类型(如Block*)告诉编译器如何解释......
  • 【优选算法篇】双指针的华丽探戈:深入C++算法殿堂的优雅追寻
    文章目录C++双指针详解:进阶题解与思维分析前言第一章:有效三角形的个数1.1有效三角形的个数示例1:示例2:解法一(暴力求解)解法二(排序+双指针)易错点提示代码解读第二章:和为s的两个数字2.1和为s的两个数字示例1:解法一(暴力解法)解法二(双指针-对撞指针)第三章:三......
  • 实验2 C语言分支与循环基础应用编程-1
    实验一:#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));cnt=0;while(cnt......
  • C语言中的指针与内存管理:两种情况分析
    在C语言中,指针的使用和内存管理是非常重要的概念。在本文中,我们将分析两种情况:一种是通过指针修改结构体内容,另一种是错误地尝试通过指针分配新的内存。我们将详细探讨这两种情况中的内存管理问题和如何避免常见的错误。第一例:通过指针修改结构体内容以下是第一段代码:#includ......
  • 数据结构(c语言版)-为什么想起来很简单的代码,写起来那么费劲呢?
    作为一个代码小垃圾,三行五行的基本语句都写不出来。课上,双链表的插入写起来都那么费劲,真糟糕。思路很简单,为什么代码不会写?需要对基本语句再熟悉。为什么会考虑不到保存指针(指针覆盖)的情况?因为在思考数据元素插入链表问题时,使用的是全知视角(上帝视角),“偷看答案”了。但是,对于每......
  • C语言程序设计现代方法_读书笔记
    C语言程序设计现代方法第2章C语言基本概念(P10)在C语言中,函数仅仅是一系列组合在一起并且赋予了名字的语句。(P14)一旦变量被赋值,就可以用它来辅助计算其他变量的值。(P17)C语言的一个通用原则:在任何需要数值的地方,都可以使用具有相同类型的表达式。(P19)在C语言中,标识符可......