【C语言】指针那些事(上)

news2024/9/23 5:23:08

C语言系列

文章目录


文章目录

一. 字符指针

一.(1 ) 数组创建空间的地址和指针指向的地址

二. 指针数组

二.(1)指针数组模拟一个二维数组

​         三. 数组指针

         三.(1)数组指针到底有什么用

对一维数组没有什么用

二.(2)正常的二维数组传参的写法 

总结


前言

该文章详细的讲解都有啥指针,及包括指针的日常使用等等,各位可以愉快的食用该文章的对于指针的理解,可以为大家对指针的理解加深一点。


一. 字符指针

关于指针的基本常识:
1. 指针变量就是个变量,用来存放地址,地址唯一标识一块内存空间。
理解:内存单元是有编号,编号 == 地址 == 指针 要存起来的话就需要一个指针变量 
2. 指针的大小是固定的4 / 8个字节(32位平台 / 64位平台)。
理解:地址/指针的大小是4/8个字节,或者是指针变量的大小是4/8个字节
3. 指针是有类型,指针的类型决定了指针的 + -整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。

int main()
{
    char ch = 'w';
    char* pc = &ch;
    //将一个字符w的地址赋值给到char*类型的指针变量里面去
    char* p = "abcdef";//该字符串作为一个表达式的时候它的值其实是首字符的地址
    //当我们把这个字符串赋给p的时候,其实就是将该字符串的首地址赋给p
    //当我们在x86环境下,一个指针变量是4个字节
    //常量字符串无法被改变
    printf("%s\n", p);//通过这个字符指针,可以连续访问整个字符串
    printf("%c\n",*p);//对p进行解引用只能拿到一个字符
    return 0;
}

一.(1 ) 数组创建空间的地址和指针指向的地址

我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

int main()
{
    char str1[] = "hello bit.";
    char str2[] = "hello bit.";
    //str1和str2两个数组创建了两个不同空间
    //系统创建一个常量字符串,因为常量字符串无法被修改,
    //所以系统不会创建两个相同的常量字符串,
    //str3和str4这两个指针变量指向的就是那个相同的常量字符串的首地址
    //str3和str4还是两个不同的指针变量,但是它们的存放的值是相同的
    const char* str3 = "hello bit.";
    const char* str4 = "hello bit.";
    if (str1 == str2)
        printf("str1 and str2 are same\n");
    else
        printf("str1 and str2 are not same\n");

    if (str3 == str4)
        printf("str3 and str4 are same\n");
    else
        printf("str3 and str4 are not same\n");

    return 0;
}


 二. 指针数组

关于指针数组是个啥?

指针数组是数组
字符数组 - 存放字符的数组
整型数组 - 存放整型的数组
指针数组 - 存放指针的数组,存放在数组中的元素都是指针类型的

  int*         arr[5];//存放整型指针的数组
//整型指针类型 aar数组
char* ch[6];//存放字符指针的数组

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 4;
    //不会有人这样使用,因为怎样使用的话,就是多此一举,还不如直接将数字写进数字里面去
    int* arr[] = { &a,&b,&c,&d };
    return 0;
}

二.(1)指针数组模拟一个二维数组

我们直接在代码中添加注释,以及游行图,让大家可以更加直观的理解代码中的指针的应用:

int main()
{
    int arr1[] = { 1,2,3,4,5 };
    int arr2[] = { 2,3,4,5,6 };
    int arr3[] = { 3,4,5,6,7 };
            //int* int* int*  //因为是arr1的地址指向的是数组中的整型,所以是整形指针
    //这个时候就可以认为arr数组是一个指针数组
    int* arr[] = { arr1,arr2,arr3 };
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        int j = 0;
        for (j = 0; j < 5; j++)
        {
            printf("%d", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

int main()
{
    //指针数组:就是数组类型是指针类型的数组 
    char* arr[5] = { "hello bit","hehe","penggeC","bitejiuyeke","c++" };
    int i = 0;
    for (i = 0; i < 5; i++)
    {
        printf("%s\n", arr[i]);
    }
    return 0;
}

 三. 数组指针

啥是数组指针: 

指针数组 - 是数组,是存放指针的数组
数组指针 - 是指针
字符指针 - 指向字符的指针
整型指针 - 指向整型的指针
浮点型指针 - 指向浮点数指针
数组指针 - 指向数组的指针

将数组的地址赋给数组指针

 数组名的理解
 数组名是数组首元素的地址
 但是存在两个例外
 1,sizeof(数组名)
 2,&数组名,这里的数组名表示整个数组,取出的是数组的地址

int main()
{
    int arr[10];
    printf("%p\n", arr);//数组名是首元素的地址int*
    printf("%p\n", arr+1);//数组名是首元素的地址+1就是加一个整数4
    printf("%p\n", &arr[0]);//arr[0]是首元素地址int*
    printf("%p\n", &arr[0]+1);//arr[0]是首元素地址+1就是加一个整数4
    printf("%p\n", &arr);//arr的数组地址
    printf("%p\n", &arr+1);//加1就是增加了一个数组的大小
    //指针类型决定了指针+1.到底是+几个字节
    return 0;
}

三.(1)数组指针到底有什么用

对一维数组没有什么用

int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int* p = arr;
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d", p[i]);
    }
    //int (*p)[10] = &arr
    //int i = 0;
    /*for (i = 0; i < 10;)
    {
        printf("%d", (*p)[i]);
    }*/
    //这两种形式上不同,但是他们的结果是相同的
    return 0;
}

二.(2)正常的二维数组传参的写法 

//数组名就是首元素地址 
void print(int arr[3][5], int r, int c)//数组传参同样传的首元素地址,
//首元素的地址是二维数组第一行的地址,
{
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        int j = 0;
        for (j = 0; j < 5; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}
print(int (*p)[5], int r, int c)
//使用数组指针的形式,传的二维数组,但是指向的第一行的一维数组的地址,一行有5个,
//必须要写成一个一维数组的指针才可以
{
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        int j = 0;
        for (j = 0; j < 5; j++)
        {
            printf("%d ", p[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
    print(arr, 3, 5);
    return 0;
}
void print(int arr[], int sz)//形式参数是数组形式,因为数组传参传的就是一个地址,而不是创建一个新的数组
{//写成数组形式的形参是因为方便新手理解
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d", arr[i]);
    }
}
void print(int* arr, int sz)//形式参数是指针的形式
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d", arr[i]);//arr[i] ===> *(arr+i)
    }
}
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    print(arr, sz);//一维数组传参传的是数组名,而数组名也等于数组首元素地址
    return 0;
}
int arr[5];//arr是一个能够存放5个整型数组数据的数组
int* parr1[10];//parr是一个指针数组,数组大小为10个元素,类型为整型指针类型
int(*parr2)[10];//parr2是一个数组指针,该指针是指向数组的,指向的数组有10个元素,每个元素的类型的是整型
int(*parr3[10])[5];//parr3是一个数组,是存放数组指针的数组,这个数组有10个元素,存放的这个数组指针,指向的数组有5个元素,每个元素都是整型

总结

本文详细的的介绍了一部分的指针的知识,还有代码的理解帮助,并不是全部的知识,大家感觉有用处就好

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

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

相关文章

VC++程序崩溃时,使用Visual Studio静态分析dump文件

1、通过Visual Studio直接把Dump文件打开 2、点击【仅限本机进行调试】&#xff0c;启动Dump 3.1、本机调试启动后&#xff0c;如果程序运行模块和pdb文件在同一个目录的&#xff0c;直接定位到异常代码行 3.2、如果显示找不到pdb文件&#xff0c;则需要通过【新建路径】设置…

Python-列表、元组和字典

目录 一、列表概述 二、列表的循环遍历 1、使用for循环遍历列表 2、使用while循环遍历列表 三、列表的常见操作 1、在列表中增加元素 &#xff08;1&#xff09;使用append方法 &#xff08;2&#xff09;使用extend方法 &#xff08;3&#xff09;使用insert方法 2、…

温馨提示!小心不法分子的隐藏陷阱

《绝地求生》国服的”老兵回归”活动一经推出就受到广大玩家欢迎&#xff0c;因此也有不法分子想趁虚而入。就在近日&#xff0c;我们接到玩家举报&#xff0c;发现一些不法分子通过伪基站邮件群发的形式&#xff0c;以“第XXXX位老兵奖励”为主题&#xff0c;向用户推荐一个非…

【薅羊毛】免费领取6个月语雀会员-关于语雀 23 日故障的公告

关于语雀 23 日故障的公告 关于语雀 23 日故障的公告 语雀团队 语雀 2023-10-24 21:11 发表于浙江 各位语雀的用户&#xff1a; 10 月 23 日语雀出现重大服务故障&#xff0c;且持续 7 个多小时才完全恢复&#xff0c;给用户使用造成极大不便&#xff0c;对此我们深感抱歉。…

Go 包操作之如何拉取私有的Go Module

Go 包操作之如何拉取私有的Go Module 在前面&#xff0c;我们已经了解了GO 项目依赖包管理与Go Module常规操作&#xff0c;Go Module 构建模式已经成为了 Go 语言的依赖管理与构建的标准。 在平时使用Go Module 时候&#xff0c;可能会遇到以下问题&#xff1a; 在某 modul…

关于报错java.util.ConcurrentModificationException: null的源码分析和解决

一般有这种问题,方法中至少会有List或者Map下的至少两个子类,有可能参数类型相同,也有可能不同都有可能触发这个问题!其主要原因是使用了ArrayList进行删除操作或者使用iterator遍历集合的同时对集合进行修改都有可能会出现这个问题 ArrayList属于List下的子类 需要区分的是Li…

AI小百科 - 什么是生成式AI中的提示语 “Prompt“

定义 "Prompt" 是指在生成式AI中用于指导模型生成输出的输入文本或问题。它是一种方法&#xff0c;通过提供特定的信息或指示&#xff0c;引导AI生成与所需任务相关的响应。 让我们用一个小学生可以理解的方式来解释提示语。想象一下&#xff0c;你是一名小学生&am…

深入剖析Java反射机制:解锁高级编程技巧,事半功倍

前言 在 Java中&#xff0c;反射机制&#xff08;Reflection&#xff09;非常重要&#xff0c;但对于很多开发者来说&#xff0c;这并不容易理解&#xff0c;甚至觉得有点神秘 目录 1. 简介 定义&#xff1a;Java语言中 一种 动态&#xff08;运行时&#xff09;访问、检测 …

docker安装minio作为图床服务

minio官网&#xff1a;MinIO | 高性能分布式存储&#xff0c;私有云存储 适用于AI的高性能分布式云存储&#xff0c;MinIO提供高性能、与S3 兼容的对象存储系统&#xff0c;让你自己能够构建自己的私有云储存服务。 MinIO原生支持 Kubernetes&#xff0c;它可用于每个独立的公…

迅为itop-3568开发板qt学习手册上新

基于RK3568的QT教程他来了~从C基础到QT编程实例再到项目实战&#xff0c;《iTOP-3568开发板QT学习手册》带你打通QT的任督二脉。 界面布局 3.5.1 水平布局 l Horizontal Layout&#xff1a;水平方向布局&#xff0c;组件自动在水平方向上分布 使用时先选中组件&#xff0…

外卖霸王餐系统 支持小程序,分站合作

它终于出来啦&#xff01;微客云分站终于正式发布&#xff01;&#xff01;&#x1f4e3;&#x1f4e3;&#x1f4e3; 先前的文章就已经预告过微客云要搞分站&#xff0c;很多小伙伴们一直在问老许分站什么时候出来&#xff0c;想加盟分站怎么做&#xff1f;有什么条件&#xf…

部署:端口映射相关问题

图片仅作示意用途 在很多现场部署环境里&#xff0c;网络管理是相对严格的&#xff0c;设备所在的子网如果需要和办公网所在的服务器通讯&#xff0c;需要通过专门的中间节点&#xff0c;一般还有严格的防火墙配置。此时&#xff0c;研发环境里&#xff0c;服务器与设备子网各…

【Python3】【力扣题】136. 只出现一次的数字

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;遍历列表元素&#xff0c;查看该元素在列表中共有多少个&#xff0c;返回个数为1的元素。 知识点&#xff1a;列表.count(...)&#xff1a;统计列表中某元素个数。 class Solution:def …

【实战项目】高并发内存池(下)

我们上篇文章&#xff08;高并发内存池&#xff08;上&#xff09;&#xff09;介绍了向高并发内存池申请资源的整个过程&#xff0c;本篇文章我们将会对申请后的空间资源释放的整个流程。同时也会对我们自己实现的内存池进行性能测试和优化。 文章目录 一、thread cache 回收资…

CentOS 7 安装和配置java环境

1 安装包准备 安装包可以通过下面地址进行版本选择安装&#xff1a; https://www.oracle.com/java/technologies/downloads/#java8 2 正式开始安装 本次分享的安装方法直接通过编辑/etc/profile文件实现java的安装 2.1 新建安装包存放目录 mkdir /java cd /java/ 2.2 解压安…

Mac电脑窗口管理Magnet中文 for mac

Magnet是一款Mac窗口管理工具&#xff0c;它可以帮助用户轻松管理打开的窗口&#xff0c;提高多任务处理效率。以下是Magnet的一些主要特点和功能&#xff1a; 分屏模式支持&#xff1a;Magnet支持多种分屏模式&#xff0c;包括左/右/顶部/底部 1/2 分屏、左/中/右 1/3 分屏、…

分享一下怎么做一个投票小程序链接

在这个数字化时代&#xff0c;微信小程序已经成为了我们生活中不可或缺的一部分。而投票小程序链接&#xff0c;更是具有广泛的应用场景和巨大的市场潜力。本文将详细介绍如何制作一个投票小程序链接&#xff0c;帮助大家了解其意义、设计思路、实现方法、亮点突出以及如何推广…

【notion enhancer安装】一个强大的笔记软件,可以实现侧边目录的notion

官网地址&#xff1a; https://notion-enhancer.github.io/getting-started/installation/ 介绍 众所周知&#xff0c;notion作为一款强大的笔记软件&#xff0c;深受广大uu的热爱。但是在使用普通版本的时候 &#xff0c;notion不能实现目录的侧边导航&#xff0c;对于很长的…

MyBatis Plus公共字段自动填充

MyBatis Plus公共字段自动填充&#xff0c;也就是在插入或者更新的时候为指定字段赋予指定的值&#xff0c;使用它的好处就是可以统一对这些字段进行处理&#xff0c;避免了重复代码。 例如&#xff0c;像每个table中都有createTime,createUser,updateTime,updateUser这些字段…

信奥赛一本通算法 第二章数据排序(【例2.2】车厢重组、谁考了第k名、奇数单增序列、成绩排序、奖学金、分数线划定、整数奇偶排序)

数据算法 1310&#xff1a;【例2.2】车厢重组1176&#xff1a;谁考了第k名1177&#xff1a;奇数单增序列1178&#xff1a;成绩排序1179&#xff1a;奖学金1180&#xff1a;分数线划定1181&#xff1a;整数奇偶排序 1310&#xff1a;【例2.2】车厢重组 这道题简单&#xff0c;题…