C语言-指针_01

指针基础

1. 概述

地址编号:计算机为了存储数据,每一个程序在 32位 机中 占4G最小操作单位一个字节,每一个字节都有其对应的地址,该地址就是 地址编号

指针:地址编号这个数据 的 数据类型

指针变量:存储地址编号的 变量,其 数据类型为 指针

在这里插入图片描述

注意:

在32位平台下, 地址总线是32位的, 所以地址是32位编号, 所以指针变量是32位的, 即4个字节。
在64位平台下, 地址总线是64位的, 所以地址是64位编号, 所以指针变量是64位的, 即8个字节。

代码:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    printf("char * 大小为:%ld\n",sizeof(char *));
    printf("short * 大小为:%ld\n",sizeof(short *));
    printf("int * 大小为:%ld\n",sizeof(int *));
    printf("long * 大小为:%ld\n",sizeof(long *));
    printf("float * 大小为:%ld\n",sizeof(float *));
    printf("double * 大小为:%ld\n",sizeof(double *));
    return 0;
}

输出:

char * 大小为:8
short * 大小为:8
int * 大小为:8
long * 大小为:8
float * 大小为:8
double * 大小为:8

2. 指针变量

1.1 定义

语法:

数据类型 变量名

指针的类型:

char * 		存储字符型数据的地址编号的数据类型 		   字符指针
short * 	存储short型数据的地址编号的数据类型 		短整形指针
int * 		存储int型数据的地址编号的数据类型 			整形指针
long * 		存储long型数据的地址编号的数据类型 		长整形指针
float * 	存储float型数据的地址编号的数据类型 		单精度浮点型指针
double * 	存储double型数据的地址编号的数据类型 		双精度浮点型指针
...

如:

//案例1: int num = 10; 定义一个指针变量存储num的地址
int *p;
//案例2: char c = 'a'; 定义一个指针变量存储c的地址
char *p
//案例3: int *p = &num; 定义一个指针变量存储变量p的地址
int **p2;

注意:

如果在一行中定义多个指针变量,每个指针变量前面都需要加*来修饰
void fun05()
{
    int a,b,c;
    int *p1,*p2,*p3;
}

1.2 初始化

(1)、定义指针变量时,赋真实的地址

int num = 10;
int *p = &num;

(2)、当指针变量的值 等于 NULL 时,这种指针叫做 空指针

int *p = NULL;

(3)、当指针变量是局部变量,在其定义时没有赋值,此时系统将随机给其一个值,这种指针称为 野指针

int *p;

1.3 运算符

1.3.1 &
  • 作用:取地址

  • & 取地址符 可取区域只能获取变量地址

    栈区

    静态全局区

在这里插入图片描述

  • 代码:

    #include <stdio.h>
    char c = 'a';
    int main(int argc, char const *argv[])
    {
        int num = 10;
        int *p = &num;
        printf("p = %p\n", p);
    
        char *p2 = &c;
        printf("p2 = %p\n", p2);
    
        // int *p3 = &10;  //& 取常量10的地址会报错
        const int num02 = 20;
        int *p4 = &num02;
        printf("p4 = %p\n", p4);
    
        return 0;
    }
    
    // 输出:
    // p = 0x7ffe8dfe59f8
    // p2 = 0x601040
    // p4 = 0x7ffe8dfe59fc
    
1.3.2 *

作用:取值改值(修改指针指向的地址的值)

语法:*指针变量名

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int num = 10;
    int *p = &num; 				//此时 * 表示 变量p是int型指针变量
    printf("*p = %d\n", *p); 	//此时 * 表示为取值

    *p = 20;
    printf("num = %d\n", num);
    return 0;
}

// 输出:
// *p = 10
// num = 20

3. 指针类型

3.1 指针本身的类型

指针变量 去除 变量名,剩余的就是 指针本身的类型

如:

int *p1;	// int *  
int **p2;	//int **
int (*p)(int int);//int (*)(int,int)
...

例:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int num = 10;
    int *p = &num;			//去除变量名,剩余指针类型 int *,便于判断等号左右两边类型是否一致
    printf("p = %p\n", p);

    char *p2 = &num;		//语法错误,=两边类型不一致,但是编译器会做优化,只报警告,不报error
    printf("p2 = %p\n", p2);
    return 0;
}

在这里插入图片描述

3.2 指针指向的数据的数据类型

指针变量 去除 变量名与最近的一个,剩余的就是 指针 指向的数据的 类型

如:

int *p1;  			// int
int **p2; 			// int *
int (*p)(int int); 	//int (int int)
...

3.3 取值宽度

int num = 0x01020304;
int *p = &num;
print("*p = %d\n", *p);

问题:num为int型变量,占4个字节,那就是4个地址(1个字节,一个地址),

​ 那么指针变量p在存储num的地址时,是怎么存储的?存储的是哪个地址?

答:指针变量有取值宽度,如下:

指针变量的数据类型 决定了 取值宽度:

int * 		取值宽度为4字节
char * 		取值宽度为1字节
short * 	取值宽度为2字节
...

例:与单位跨度同一代码

3.4 单位跨度

指针变量的数据类型 决定了 单位跨度:(就是地址在进行加减时地址增减的字节数)

int * 		单位跨度为4字节
char * 		单位跨度为1字节
short * 	单位跨度为2字节

例:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int num = 0x01020304;
    //对应的十六进制:0x0000 0001 0000 0010 0000 0011 0000 0100
    //Linux系统存储是倒叙存储的:
    //0000 0100 0000 0011 0000 0010 0000 0001
    //0x04 0x03 0x02 0x01
    int *p = &num;
    printf("*p = %d\n", *p);    //*p = 16909060

    char *p2 = (char *)&num;    //强制转换为char *类型
    printf("*p2 = %d\n", *p2);  //*p2 = 4

    short *p3 = (short *)&num;  
    printf("*p3 = %d\n", *p3);  //*p3 = 772  对应的十六进制:0x0304

    printf("*p2 = %d\n", *(p2+1)); //*p2 = 3 对应的十六进制:0x03 此时p2为首个字节存储的地址+1,加的是一个单位跨度即1字节
    printf("*p2 = %d\n", *(p2+2)); //*p2 = 2 对应的十六进制:0x02 步长为1,+2表示向后挪二位

    printf("*p3 = %d\n", *(p3+1)); //*p3 = 258 对应的十六进制:0x0102 步长为2,+1表示向后挪二位
    return 0;
}

4. void

作用:

1、当函数没有返回值时,返回值类型为void;

2、void和指针结合作为一种指针类型,如 void * , 这种指针被称为 万能指针,意味着任何一种地址可以赋值给该类型的指针变量

例:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    char c = 'a';
    short s = 1;
    int num = 10;

    char * p1 = &c;
    short * p2 = &s;
    int * p3 = &num;
    printf("*p1 = %d\n", *p1);
    printf("*p2 = %d\n", *p2);
    printf("*p3 = %d\n", *p3);

    void * p4 = &c;
    void * p5 = &s;
    void * p6 = &num;

    return 0;
}

5. 指针变量使用的注意事项

5.1 野指针操作会出现段错误

void fun01()
{
    //野指针
    int *p;
    printf("*p=%d\n",*p);
}

在这里插入图片描述

5.2 空指针操作会出现段错误

void fun02()
{
    //空指针
    int *p = NULL;
    printf("*p=%d\n",*p);
}

在这里插入图片描述

5.3 不要对万能指针进行操作

void fun03()
{
    int num = 10;
    int *p = &num;
    printf("*p=%d\n",*p);
    void *p2 = &num;
    printf("*p2=%d\n",*p2);
}

在这里插入图片描述

5.4 操作指针变量不要越界

#include <stdio.h>

void fun04()
{
    int num = 0x01020304;
    int *p = &num;
    char *p2 = (char *) p;
    printf("%#p\n",*p2);
    printf("%#p\n",*(p2+1));
    char c = 'a';
    char * p3 = &c;
    //1
    int *p4 = (int *)p3;
    printf("%#p\n",*p4);
}

int main(int argc, char const *argv[])
{
    fun04();
    return 0;
}

// 输出:
// 0x4
// 0x3
// 0x2030461

6. 练习

案例1:以下赋值语句正确的是___
int num=10, *p=&num, **q=&p;
A:p=&num B:q =p; c:q=&num D:q=&p;

正确答案:AD
但是,Bc也可以通过,会有警告,相当于指针变量赋给二维指针变量

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flutter开发实战-实现获取视频的缩略图封面video_thumbnail

flutter开发实战-实现获取视频的缩略图封面video_thumbnail 在很多时候&#xff0c;我们查看视频的时候&#xff0c;视频没有播放时候&#xff0c;会显示一张封面&#xff0c;可能封面没有配置图片&#xff0c;这时候就需要通过获取视频的缩略图来显示封面了。这里使用了video…

【linux】信号——信号保存+信号处理

信号保存信号处理 1.信号保存1.1信号其他相关概念1.2信号在内核中的表示 2.信号处理2.1信号的捕捉流程2.2sigset_t2.3信号集操作函数2.4实操2.5捕捉信号的方法 3.可重入函数4.volatile5.SIGCHLD信号 自我名言&#xff1a;只有努力&#xff0c;才能追逐梦想&#xff0c;只有努力…

手写链表反转

LeetCode206 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 1. 建立虚拟头结点辅助反转 在分析链表插入元素的时候&#xff0c;会发现如何处理头…

【Python】实现一个简单的区块链系统

本文章利用 Python 实现一个简单的功能较为完善的区块链系统&#xff08;包括区块链结构、账户、钱包、转账&#xff09;&#xff0c;采用的共识机制是 POW。 一、区块与区块链结构 Block.py import hashlib from datetime import datetimeclass Block:"""区…

简单搭建Python开发环境

Python环境安装 Python官网: Welcome to Python.org 1. 选择Python3.x版本下载&#xff0c;建议使用稳定版3.9.13&#xff08;Stable Releases&#xff09;&#xff0c;绝大数库对3.9版本Python已良好支持&#xff0c;但对3.10及以上支持不完全&#xff1a; https://www.…

华清远见嵌入式学习——C++——作业4

作业要求&#xff1a; 代码&#xff1a; #include <iostream>using namespace std;class Stu {friend const Stu operator*(const Stu &L,const Stu &R);friend bool operator<(const Stu &L,const Stu &R);friend Stu operator-(Stu &L,const S…

Git 简介及异常场景处理

一、简介 介绍Git之前&#xff0c;还得先介绍下 版本控制系统&#xff08;VCS&#xff09;&#xff0c; 和它的发展历史 纵观版本控制系统的发展历史&#xff0c;广义上讲&#xff0c;版本控制工具的历史可以分为三代&#xff1a; 第一代 第一代版本控制系统被称为本地版本控…

C语言结构体详解(一)(能看懂文字就能明白系列)

&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;个人主页&#xff1a; 古德猫宁- &#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;…

Gateway跨域解决可copy配置代码

globalcors: # 全局跨域处理配置add-to-simple-url-handler-mapping: true # 解决options请求被拦截的问题cors-configurations:[/**]:allowed-origins:- "http://localhost:8090"- "http://www.qvfan.com"allowedMethods:- "GET"- "POST&q…

C++相关闲碎记录(3)

1、reference wrapper 例如声明如下的模板&#xff1a; template <typename T> void foo(T val); 如果调用使用&#xff1a; int x; foo(std::ref(x)); T变成int&&#xff0c;而使用调用 int x; foo(std::cref(x)); T变成const int&。 这个特性被C标准库用…

【每日一题】1094. 拼车-2023.12.2

题目&#xff1a; 1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi…

vue中中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…

@2023 中国家居家具行业数字化转型分析与案例解读|商派徐礼昭

作者&#xff1a;徐礼昭&#xff08;商派市场负责人&#xff0c;重构零售实验室负责人&#xff09; 中国的家居家具行业面临着市场竞争激烈、消费者需求多变等诸多挑战。为了应对这些挑战&#xff0c;许多品牌企业开始探索数字化转型的道路&#xff0c;以提升竞争力并满足消费…

非应届生简历模板13篇

无论您是职场新人还是转行求职者&#xff0c;一份出色的简历都是获得心仪岗位的关键。本文为大家精选了13篇专业的非应届生简历模板&#xff0c;无论您的经验如何&#xff0c;都可以灵活参考借鉴&#xff0c;提升自己的简历质量。让简历脱颖而出&#xff0c;轻松斩获心仪职位&a…

np.array无法直接用matplotlib画图,因为需要借用np.squeeze先转化

文章目录 前言一、使用步骤1.没使用np.squeeze转化2.使用np.squeeze转化 前言 实际工作中&#xff0c;时而难免会遇见np.array无法直接用matplotlib画图的情况&#xff0c;这个时候&#xff0c;是因为在画图之前少了一个步骤&#xff0c;需要先借用np.squeeze先转化 一、使用步…

ES通过抽样agg聚合性能提升3-5倍

一直以来&#xff0c;es的agg聚合分析性能都比较差&#xff08;对应sql的 group by&#xff09;。特别是在超多数据中做聚合&#xff0c;在搜索的条件命中特别多结果的情况下&#xff0c;聚合分析会非常非常的慢。 一个聚合条件&#xff1a;聚合分析请求的时间 search time a…

【算法】Rabin-Karp 算法

目录 1.概述2.代码实现3.应用 更多数据结构与算法的相关知识可以查看数据结构与算法这一专栏。 有关字符串模式匹配的其它算法&#xff1a; 【算法】Brute-Force 算法 【算法】KMP 算法 1.概述 &#xff08;1&#xff09;Rabin-Karp 算法是由 Richard M. Karp 和 Michael O. R…

免费采集工具推荐,好文章值得收藏

采集工具的作用 在互联网的海洋中&#xff0c;有许多强大的免费采集工具&#xff0c;它们为用户提供了便捷、高效的方式&#xff0c;帮助用户从各种网站中收集、整理所需的信息。这些工具不仅广泛应用于市场研究、竞争情报等商业领域&#xff0c;同时也服务于学术研究、个人兴…

虚函数表和虚函数在内存中的位置

文章目录 结论验证 结论 虚函数表指针是虚函数表所在位置的地址。虚函数表指针属于对象实例。因而通过new出来的对象的虚函数表指针位于堆&#xff0c;声名对象的虚函数表指针位于栈 虚函数表位于只读数据段&#xff08;.rodata&#xff09;&#xff0c;即&#xff1a;C内存模…

量子测量-技术点杂录

目录: 高质量文章导航-持续更新中_GZVIMMY的博客-CSDN博客 前置:量子测量设备 电子显微镜:电子显微镜可以在非常高分辨率下观察生物组织、细胞和分子结构。通过调整电子束的强度和聚焦来观察细胞内部的微小结构。但是,电子显微镜需要对样品进行切片处理,而且在真空中进行…