【C语言】深入理解指针(一)

news2024/11/17 5:25:37

指针1

  • 1.内存和地址
  • 2.指针变量和地址
    • 2.1取地址操作符(&)
    • 2.2指针变量和将引用操作符
    • 2.3解引用操作符
    • 2.4指针变量的大小
  • 3.指针变量类型的意义
    • 3.1指针变量类型
    • 3.2void*指针
  • 4.const修饰指针
  • 5.指针运算
    • 5.1 指针+- 整数
    • 5.2指针-指针
    • 3.指针的关系运算
  • 6.野指针
    • 6.1指针未初始化
    • 6.2指针越界访问
    • 6.3指针指向的空间释放
  • 7.assert断言
  • 8.指针的使用和传值调用
    • 8.1srtlen的模拟实现
    • 8.2传值调用和传址调用

1.内存和地址

1.内存
我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何高效的管理呢?
其实也是把内存划分为⼀个个的内存单元,每个内存单元的大小取1个字节
计算机中常见的单位(补充):
一个比特位可以存储⼀个2进制的位1或者0

bit - ⽐特位
Byte - 字节
KB
MB
GB
TB
PB

1Byte = 8bit
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB

⼀个字节空间里面能放8个比特位
内存单元的编号 == 地址 == 指针
编址:CPU和内存之间有⼀组线,叫做地址总线

2.指针变量和地址

2.1取地址操作符(&)

理解了内存和地址的关系,我们再回到C语⾔,在C语⾔中创建变量其实就是向内存申请空间,比如
在这里插入图片描述
比如,上述的代码就是创建了整型变量a,内存中申请4个字节,⽤于存放整数10,其中每个字节都有地址,上图中4个字节的地址分别是
在这里插入图片描述
结论:&a取出的是a所占4个字节中地址较小的字节的地址。

2.2指针变量和将引用操作符

int a = 10;
int * pa = &a;

这里pa左边写的是== int*== , * 是在说明pa是指针变量,而前面的 int 是在说明pa指向的是整型(int) 类型的对象

2.3解引用操作符

我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针) 指向的对象,这里使用的⼀个操作符叫解引用操作符(*)

#include <stdio.h>
int main()
{
    int a = 100;
    int* pa = &a;
    *pa = 0;
    return 0;
}

上⾯代码中第6⾏就使⽤了解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到指向的空间,pa其实就是a变量了;所以pa = 0,这个操作符是把a改成了0.

2.4指针变量的大小

结论:
• 32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。

3.指针变量类型的意义

3.1指针变量类型

结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。
指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)

3.2void*指针

在指针类型中有⼀种特殊的类型是 void* 类型的,可以理解为⽆具体类型的指针(或者叫泛型指针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算

⼀般 void* 类型的指针是使⽤在函数参数的部分,⽤来接收不同类型数据的地址,这样的设计可以
实现泛型编程的效果。使得⼀个函数来处理多种类型的数据,

4.const修饰指针

const * p,修饰的是指针指向的内容(限制p),保证指针指向的内容不能改变。但是指针变量本⾝可以改变,可以指向别的变量地址。
• * const p,修饰的是指针变量本⾝(p),p中的地址不能改变,只能是某一个变量的地址,但是
p 所指向的内容可以改,改变值

5.指针运算

指针的基本运算有三种,分别是:
• 指针± 整数
• 指针-指针
• 指针的关系运算

5.1 指针± 整数

因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸⽠就能找到后⾯的所有元素

#include <stdio.h>
//指针+- 整数 
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p = &arr[0];
    int i = 0;
    int sz = sizeof(arr)/sizeof(arr[0]);
    for(i=0; i<sz; i++)
    {
        printf("%d ", *(p+i));//p+i 这⾥就是指针+整数 
    }
    return 0;
}

5.2指针-指针

指针-指针的绝对值是指针和指针之间元素的个数,前提条件是指向同一块空间
一定注意

charp=chars;
char **p=&s;(s为指针)

在这里插入图片描述

//指针-指针 
#include <stdio.h>
int my_strlen(char *s)
{
    char *p = s;
    while(*p != '\0' )
        p++;
    return p-s;
}
int main()
{
    printf("%d\n", my_strlen("abc"));
    return 0;
}

5

3.指针的关系运算

//指针的关系运算 
#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p = &arr[0];
    int sz = sizeof(arr)/sizeof(arr[0]);
    while(p<arr+sz) //指针的⼤⼩⽐较 
    {
        printf("%d ", *p);
        p++;
    }
    return 0;
}

(p<arr+sz) 等价&arr[sz]

6.野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

6.1指针未初始化

#include <stdio.h>
int main()
{ 
    int *p;//局部变量指针未初始化,默认为随机值 
    *p = 20;
    return 0;
}

6.2指针越界访问

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

6.3指针指向的空间释放

#include <stdio.h>
int* test()
{
    int n = 100;
    return &n;//函数栈帧使用完销毁
}
int main()
{
    int*p = test();//但p还能找到这块空间
    printf("%d\n", *p);
    return 0;
}

如何避免野指针
1.指针初始化
2.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性

7.assert断言

assert.h 头⽂件定义了宏== assert()== ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报错终⽌运⾏。这个宏常常被称为“断⾔”

在这里插入图片描述

8.指针的使用和传值调用

8.1srtlen的模拟实现

库函数strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数。

size_t strlen ( const char * str );

参数str接收⼀个字符串的起始地址,然后开始统计字符串中 \0 之前的字符个数,最终返回⻓度。

int my_strlen(const char * str)
{
 	int count = 0;
 	assert(str);
	 while(*str)
	{
	 	count++;
 		str++;
 	}
	return count;
}
int main()
{
 	int len = my_strlen("abcdef");
	 printf("%d\n", len);
	return 0;
}
注:为了编译器不警告,int=size_t  这是返回值类型

8.2传值调用和传址调用

传值调用 实参传递给形参的时候,形参会单独创建⼀份临时空间来接收实参,对形参的修改不影响实

传址调⽤传址调⽤,可以让函数和主调函数之间建⽴真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采⽤传值调⽤如果函数内部要修改主调函数中的变量的值,就需要传址调⽤

#include <stdio.h>
void Swap2(int*px, int*py)
{
    int tmp = 0;
    tmp = *px;
    *px = *py;
    *py = tmp;
}
int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d", &a, &b);
    printf("交换前:a=%d b=%d\n", a, b);
    Swap2(&a, &b);
    printf("交换后:a=%d b=%d\n", a, b);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2076111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《高等代数》最大公因式典型例题

说明&#xff1a;此内容用于本人复习巩固&#xff0c;如果也能帮助到大家那就更加有意义了。 注&#xff1a;这道题主要从 1)公因式整除多项式的线性组合 2)最大公因式能够被其它公因式整除 3)如果两个多项式互相整除&#xff0c;那就说明这两个多项式相等 这三个知识点出…

Hadoop的HA配置与实现(ZooKeeper)

目录 一、Hadoop的HA架构二、配置实现Hadoop的HA三、效果 一、Hadoop的HA架构 集群规划 112&#xff1a;NameNode1 ResourceManager1 JournalNode1 113&#xff1a;NameNode2 ResourceManager2 JournalNode2 114&#xff1a;DataNode1 NodeManager1 115&#xff1a;DataNode2 N…

如何快速建30个文件夹

文件夹的快速新建只能通过专门的软件来实现&#xff0c;快速建30个&#xff0c;我们可以使用批处理命令&#xff0c;也可以用第三方软件&#xff0c;批处理的命令&#xff0c;需要我们熟悉如何编写&#xff0c;而第三方软件的话不需要那么多的知识&#xff0c;直接在软件上一键…

货运搬家小程序app定制开发过程中需要的主要功能介绍

货运搬家小程序是一个集成了物流服务全过程的数字化解决方案&#xff0c;它通过移动平台提供注册与登录、货物管理、车辆管理、路线规划、货物分配、订单管理、实时追踪、评价与反馈、价格透明等功能。 具体的功能&#xff1a; 注册与登录用户可以通过小程序注册账号并登录&am…

inflight 守恒算法的实现和仿真

前面介绍过&#xff0c;只要某条流的 inflt 在 bdp 之外再增加一个相等的余量 I&#xff0c;即 inflt bdp I&#xff0c;比如 I 2&#xff0c;I 3&#xff0c;…&#xff0c;就一定会收敛到公平&#xff0c;且不会占据过多 buffer&#xff0c;因此 rtt 不会膨胀&#xff0c…

html+css网页设计 动漫 海贼王14个页面

htmlcss网页设计 动漫 海贼王14个页面 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#x…

开放式耳机对耳朵好吗?开放式耳机哪个品牌好?

许多人在选择开放式耳机时并不了解如何选购。对开放式耳机也不是很了解&#xff0c;所以我在这里做个简单的科普和分享。今天跟大家聊聊开放式耳机会伤害耳朵吗&#xff1f;开放式耳机有什么好处&#xff1f;等等&#xff0c;下面一起来看看吧~ 开放式耳机是什么意思&#xff1…

如何有效激活微信陌生客户:加好友后的沟通策略!

在当今这个数字化时代&#xff0c;微信已成为我们与客户建立联系的重要桥梁。对于许多企业和个人而言&#xff0c;成功添加陌生客户到微信列表只是第一步&#xff0c;真正的挑战在于如何有效激活这些潜在客户&#xff0c;转化为实际交易或长期关系。 下面分享一些沟通策略&…

oracle ONS configuration failed NoserversAvailable:Subscription time out导致应用起不来

java.lang.IllegalArgumentException:ONS configuration failed Caused by: oracle.ons.NoserversAvailable:Subscription time out ##已部署到服务器解决方案&#xff1a; 修改这个2个jar包后缀 ##在项目工程里面&#xff0c;<artifactId>ojdbc8</artifactId> m…

具有强制函数的物理信息神经网络

图片由 agsandrew 在 iStock 上发布 一、说明 在物理学、数学、经济学、工程学和许多其他领域&#xff0c;微分方程根据变量的导数来描述函数。简而言之&#xff0c;当涉及一个变量相对于其他变量的变化率时&#xff0c;你可能会找到一个微分方程。许多示例描述了这些关系。微分…

debian12 - install and config telnet

文章目录 debian12 - install and config telnet概述笔记配置文件END debian12 - install and config telnet 概述 前面实验&#xff0c;在xinetd中指定telnet服务&#xff0c;查看状态时&#xff0c;看到telnet服务bind失败。 直接从其他计算机来连telnet又是正常的&#xf…

随记-部署flink-1.16.3、jdk-11.0.19、zookeeper-3.4.13、kafka_2.12-2.2.2

一、部署flink-1.16.3、jdk-11.0.19、zookeeper-3.4.13、kafka_2.12-2.2.2 #软件下载 https://archive.apache.org/dist/kafka/2.2.2/kafka_2.12-2.2.2.tgz https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz https://archive.apache.org/…

Clustering-Guided Class Activation for WeaklySupervised Semantic Segmentation

pdf&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber10381698 code&#xff1a;https://github.com/DCVL-WSSS/ClusterCAM 摘要&#xff1a; 基于transformer的弱监督语义分割(WSSS)方法利用其捕获全局上下文的强大能力得到了积极的研究。然而&am…

day8JS-作用域

1. 变量的作用域(变量函数) 作用域是变量的可作用范围&#xff0c;变量只有在自己的作用域下才会生效。 函数会产生作用域&#xff0c;在函数内定义的变量只能在函数内使用。 2. 作用域分类 局部作用域&#xff1a; 函数内定义的变量和形参的作用域就是局部作用域&#xff1b;这…

【Hot100】LeetCode—207. 课程表

目录 1- 思路有向图记录入度数组出度列表 2- 实现⭐207. 课程表——题解思路 3- ACM 实现 题目连接&#xff1a;207. 课程表 1- 思路 有向图记录入度数组出度列表 根据输入① 构造遍历构造入度数组② 构造出度列表根据入度数组为 0 的数 加入到 队列中&#xff0c;进行处理 2…

在线拼图用什么软件?5款顶级照片拼接工具

照片拼接在一起用什么软件&#xff1f;当你想全景展现山西应县木塔的震撼之美时&#xff0c;5款精选照片拼接软件能帮你解锁全新视角。 这座千年古塔&#xff0c;巍峨耸立&#xff0c;细节之处尽显匠心独运。而通过拼接技术&#xff0c;每一块木构的精致、每一层塔檐的飞翘都能…

OpenBayes 教程上新 | 青岛小哥焦恩俊版二郎神来袭,MuseV + MuseTalk 分分钟实现高质量数字人制作!

使用传统的数字人训练方案生成一个高质量的数字人&#xff0c;常常需要大量的时间和算力资源&#xff0c;同时对训练素材的要求也较高&#xff0c;如果想要达到良好的唇形一致效果&#xff0c;通常需要数小时乃至更久。 MuseV 和 MuseTalk 的出现为数字人领域带来了新的突破&a…

【Canvas与桌面】十字网格黑灰背景(1920x1080)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>十字网格黑灰背景(1920x1080)</title><style type"te…

iphone被锁定怎么解锁?iPhone密码锁解锁办法分享

在忙碌的生活中&#xff0c;有时我们可能会遇到一些“小插曲”&#xff0c;比如苹果手机被锁定&#xff0c;iPhone被锁定是一个常见的问题&#xff0c;可能是由于忘记密码、多次输入错误密码或设备被远程锁定等原因造成的。 本文将介绍解锁被锁定的iPhone的方法以及注意事项&a…

【网络安全】IDOR之请求包分析

未经许可,不得转载。 文章目录 正文正文 某在线游戏平台,在开始测试时,我访问了 /profile 页面(个人资料页面),然后查看 Burp 历史记录,想查看有多少隐藏的请求。 可以看到一个HTTP 的 OPTIONS 方法的请求包: 从图中看到,该请求包含两个参数:player_id_or_name(用…