指针详解(六)

news2024/11/13 15:20:29

目录

1. sizeof 和 strlen

1)sizeof

2)strlen

3)sizeof 和 strlen的区别

2. 数组和指针试题解析

1)一维数组

2)字符数组

3)二维数组

3. 指针运算试题解析


1. sizeof 和 strlen
1)sizeof

sizeof 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小

sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据

#include <stdio.h>
int main()
{
    int a = 10;
    printf("%d\n", sizeof(a));//int 类型为4字节
    printf("%d\n", sizeof a);
    printf("%d\n", sizeof(int));
    return 0;
}

2)strlen

strlen 是C语言库函数,功能是求字符串长度

size_t strlen ( 1 const char * str );

strlen 函数的参数 str 中首地址开始向后寻找,统计 \0 之前字符串中字符的个数strlen 函数会一直向后寻找 \0 字符,直到找到为止,所以可能存在越界查找

#include <stdio.h>
int main()
{
    char arr1[3] = {'a', 'b', 'c'};
    char arr2[] = "abc";
    printf("%d\n", strlen(arr1));//随机值 
    printf("%d\n", strlen(arr2));// a b c \0 3个元素(字节)
    printf("%d\n", sizeof(arr1));//char * 3 == 3 字节
    printf("%d\n", sizeof(arr2));//a b c \0 4字节
    return 0;
}

 

3)sizeof 和 strlen的区别

sizeof

  1. sizeof 是操作符
  2. sizeof 计算操作数所占内存的大小,单位是字节
  3. 不关注内存中存放什么数据

strlen

  1. strlen是库函数,使用需要包含头文件 string.h
  2. srtlen是求字符串长度的,统计的是 \0 之前字符的元素个数
  3. 关注内存中是否有 \0 ,如果没有\0 ,就会持续往后找,可能会越界访问
     

 

2. 数组和指针试题解析
1)一维数组
int a[] = {1,2,3,4};//4个元素 16字节

printf("%d\n",sizeof(a));// a 为数组名 代表整个数组 int(4字节)*4 == 16
printf("%d\n",sizeof(a+0));// a 为首元素地址 a+0==a ->sizeof(int) == 4(32位)/8(64位)
printf("%d\n",sizeof(*a));// a 为首元素地址 *a==1  sizeof(1) == 4(32位)/8(64位)
printf("%d\n",sizeof(a+1));// a 为首元素地址 a+1 ->2的地址 sizeof(地址)== 4(32位)/8(64位)
printf("%d\n",sizeof(a[1]));// a 为首元素地址 a[i]==*(a+i)==2 sizeof(2)-> 4
printf("%d\n",sizeof(&a));// a 为数组名 &a 为整个数组地址 但还是地址 4(32位)/8(64位)
printf("%d\n",sizeof(*&a));// a 为首元素地址 *&a==a sizeof(a)->int(4字节)*4 == 16
printf("%d\n",sizeof(&a+1));//a 为数组名 &a 为整个数组地址 &a+1 跳过1个数组大小 但还是地址 4(32位)/8(64位)
printf("%d\n",sizeof(&a[0]));//取1的地址 还是地址 ->4(32位)/8(64位)
printf("%d\n",sizeof(&a[0]+1));//取2的地址 还是地址 ->4(32位)/8(64位)

 

2)字符数组
//代码1:
char arr[] = {'a','b','c','d','e','f'};//6个元素(字节)
printf("%d\n", sizeof(arr));// arr 为数组名 sizeof(数组名)->6*1==6(字节)
printf("%d\n", sizeof(arr+0));// arr 为首元素地址 sizeof(首元素地址)-> 地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(*arr));// arr 为首元素地址 *arr == 'a' sizrof('a')-> 1
printf("%d\n", sizeof(arr[1]));// arr 为首元素地址 arr[i]==*(arr+i) ->sizeof('b') == 1
printf("%d\n", sizeof(&arr));// arr 为数组名 &arr 为整个数组地址 但还是地址 -> 4(32位)/8(64位)
printf("%d\n", sizeof(&arr+1));// arr 为数组名 &arr 为整个数组地址 &arr+1 跳过1个数组 但还是地址 -> 4(32位)/8(64位)
printf("%d\n", sizeof(&arr[0]+1));// arr 为首元素地址 &arr[0】为'a'的地址 &arr[0]+1 为'b'的地址 但还是地址 -> 4(32位)/8(64位)

//代码2:
char arr[] = {'a','b','c','d','e','f'};//6个元素(字节)
printf("%d\n", strlen(arr));//随机值 无\0
printf("%d\n", strlen(arr+0));///随机值 无\0
printf("%d\n", strlen(*arr));//err
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//随机值 无\0
printf("%d\n", strlen(&arr+1));//随机值 无\0  跳过1整个数组 &arr的随机值 -6
printf("%d\n", strlen(&arr[0]+1));//随机值 无\0 比 &arr的随机值r -1

//代码3:
char arr[] = "abcdef";//7个元素 a b c d e f \0  7字节
printf("%d\n", sizeof(arr));// arr 为数组名 7*1==7(字节)
printf("%d\n", sizeof(arr+0));// arr 为首元素地址 但还是地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(*arr));//arr 为首元素地址 *arr=='a' sizeof('a') -> 1
printf("%d\n", sizeof(arr[1]));// arr 为首元素地址 arr[i]==*(arr+i) ->sizeof('b') == 1
printf("%d\n", sizeof(&arr));// arr 为数组名 &arr 为整个数组地址 但还是地址 -> 4(32位)/8(64位)
printf("%d\n", sizeof(&arr+1));// arr 为数组名 &arr 为整个数组地址 &arr+1 跳过1个数组 但还是地址 -> 4(32位)/8(64位)
printf("%d\n", sizeof(&arr[0]+1));// arr 为首元素地址 &arr[0】为'a'的地址 &arr[0]+1 为'b'的地址 但还是地址 -> 4(32位)/8(64位)

//代码4:
char arr[] = "abcdef";//7个元素 a b c d e f \0  6字节
printf("%d\n", strlen(arr));// arr 为首元素地址 6
printf("%d\n", strlen(arr+0));// arr 为首元素地址 6
printf("%d\n", strlen(*arr));//err
printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//arr 为数组名 &arr 为首元素地址 6
printf("%d\n", strlen(&arr+1));//随机值
printf("%d\n", strlen(&arr[0]+1));// arr 为首元素地址 arr[i]==*(arr+i) ->从第二个‘b'开始计数 
 -> 6-1 == 5

//代码5:
char *p = "abcdef";//p == &a
printf("%d\n", sizeof(p));//p为地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(p+1));// 还是地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(*p));//sizeof('a')  1
printf("%d\n", sizeof(p[0]));//sizeof('a')  1
printf("%d\n", sizeof(&p));//还是地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(&p+1));//还是地址 == 4(32位)/8(64位)
printf("%d\n", sizeof(&p[0]+1));//还是地址 == 4(32位)/8(64位)

//代码6:
char *p = "abcdef";//p == &a
printf("%d\n", strlen(p));//从 a 开始计数 6 
printf("%d\n", strlen(p+1));//从 b 开始计数 5
printf("%d\n", strlen(*p));//err
printf("%d\n", strlen(p[0]));//err
printf("%d\n", strlen(&p));//随机值 二级指针
printf("%d\n", strlen(&p+1));//随机值 比&p得随机数小1
printf("%d\n", strlen(&p[0]+1));//从 b 开始计数 5

 

 

 

 

 

3)二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));

数组名的意义:

  • sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址
  • 除此之外所有的数组名都表示首元素的地址

 

3. 指针运算试题解析
//题目1:
#include <stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));//2,5
    return 0;
}

//题目2
//在X86环境下
//假设结构体的大小是20个字节
//程序输出的结构是啥?
struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p = (struct Test*)0x100000;

int main()
{
    printf("%p\n", p + 0x1);
    printf("%p\n", (unsigned long)p + 0x1);
    printf("%p\n", (unsigned int*)p + 0x1);
    return 0;
}

//题目3
#include <stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0];
    printf( "%d", p[0]);
    return 0;
}

//题目4
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

//题目5
#include <stdio.h>
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int *ptr1 = (int *)(&aa + 1);
    int *ptr2 = (int *)(*(aa + 1));
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

//题目6
#include <stdio.h>
int main()
{
    char *a[] = {"work","at","alibaba"};
    char**pa = a;
    pa++;
    printf("%s\n", *pa);
    return 0;
}

//题目7
#include <stdio.h>
int main()
{
    char *c[] = {"ENTER","NEW","POINT","FIRST"};
    char**cp[] = {c+3,c+2,c+1,c};
    char***cpp = cp;
    printf("%s\n", **++cpp);
    printf("%s\n", *--*++cpp+3);
    printf("%s\n", *cpp[-2]+3);
    printf("%s\n", cpp[-1][-1]+1);
    return 0;
}

谢谢观看

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

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

相关文章

【hot100篇-python刷题记录】【全排列】

R5-回溯篇 思路也是如下&#xff1a; 层层固定 class Solution:def permute(self, nums: List[int]) -> List[List[int]]:#x代表当前固定/选择的数的下标def dfs(x):if xlen(nums)-1:ret.append(list(nums))returnfor i in range(x,len(nums)):#交换&#xff0c;将nums[i]固…

SAP_MM模块-MASS批量操作技巧

业务背景: 现在想要获得平台的流量券,每天必须要发两篇文章才行,但是一天发两篇的话,按照我的写作风格,很难写得出来~~我又不想把原本一篇完整的文章给拆分开来,那怎么办呢??今天就讲一下我常用的批量操作事务码MASS吧。 一、功能概述; MASS是系统标准的批量操作程序,…

HCIP第十一(生成树基础知识点)

企业网三层架构-冗余&#xff08;线路&#xff0c;设备&#xff0c;网关&#xff0c;电源Ups&#xff09; 三层架构-冗余&#xff0c;线路冗余&#xff1a;二层桥接技术 一台交换机上的一个接口可以映射多个MAC地址&#xff0c;但是一个MAC地址只能对应一个接口 当交换机触环…

2024.8.19 学习记录 —— 作业

一、TCP机械臂测试 #include <myhead.h>#define SER_PORT 8888 // 与服务器保持一致 #define SER_IP "192.168.0.114" // 服务器ip地址int main(int argc, const char *argv[]) {// 创建文件描述符打开键盘文件int fd open("/dev/input/event1…

设备实时数据采集:开启制造业智能化、自动化的新篇章

传统制造业在进行生产过程中&#xff0c;会涉及到设备实时数据采集需求&#xff0c;这些数据对于监控生产流程、优化生产效率、保证产品质量以及降低成本等方面至关重要。以下是一些常见的数据采集需求&#xff1a; 1.生产数据&#xff1a;包括生产数量、生产批次、生产速度等&…

Facebook与区块链:社交网络如何融入去中心化技术

随着区块链技术的飞速发展&#xff0c;去中心化理念逐渐渗透到各个领域&#xff0c;社交网络也不例外。作为全球领先的社交平台&#xff0c;Facebook在这一趋势下开始积极探索区块链技术的潜力&#xff0c;希望利用这一前沿技术来提升平台的安全性、透明度和用户控制权。本文将…

Maven-02.介绍安装

一.介绍 首先从本地仓库中寻找所需要的jar包&#xff0c;如果没有就从中央仓库中寻找。然后从中央仓库中下载使用。但是中央仓库的服务器在国外&#xff0c;因此速度和稳定性都不好&#xff0c;因此我们在中间设立远程仓库&#xff08;私服&#xff09;&#xff0c;远程仓库一般…

光伏气象站——提升光伏发电效率和稳定运行

光伏气象站作为现代光伏电站的必备组成部分&#xff0c;‌特别适用于地理分布广泛、‌气象条件复杂多变的地区&#xff0c;‌如山区、‌森林或分散的屋顶安装等。‌这些地方由于可能存在微气候差异&#xff0c;‌对光伏系统的运行效率和性能有着显著影响。‌因此&#xff0c;‌…

LeetCode:3148. 矩阵中的最大得分(DP Java)

目录 3148. 矩阵中的最大得分 题目描述&#xff1a; 实现代码与解析&#xff1a; DP 原理思路&#xff1a; 3148. 矩阵中的最大得分 题目描述&#xff1a; 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧…

STM32裸机和RTOS中的线程安全问题及STM32cubeMX中的线程安全策略

STM32线程安全问题 术语“线程” 和“多线程” 适用于裸机和基于RTOS的应用程序&#xff0c;线程安全问题并不只存在于基于RTOS的应用程序中&#xff1b;裸机应用程序中也存在这个问题&#xff0c;在裸机应用程序中&#xff0c;中断服务程序允许调用C库函数。线程安全问题可能…

『Z-Workshop』 The Graph workshop mini hackathon活动

Community Meetup In Hangzhou ZJUBCA 2024 求是 创新 概述 / OVERVIEW The Graph作为一个去中心化的查询协议&#xff0c;为区块链数据的索引和查询提供了强大的支持。我们希望通过这场黑客松&#xff0c;激发大家对区块链技术更深层次的探索和应用&#xff0c;共同推动这一…

第七十四:前端实现点击页面某个菜单跳转到对应的锚点功能

1.用js来实现 scrollIntoView方法 先定义个id或者class随意&#xff0c;因为我是循环好几个小模块所以用动态的来实现 点击的时候传对应的类名进行滑动 document.getElementById(item.variableCode).scrollIntoView({behavior:“smooth”}); 加上behavior:“smooth” 进行平…

为Linux/centos虚拟机已有硬盘扩容

为Linux已有硬盘扩容 旧盘扩容的大体流程与关键命令&#xff1a; 为虚拟机磁盘加容量&#xff1b; 为磁盘新容量分区&#xff08;fdisk&#xff09;&#xff1b; 将分区信息写入内核&#xff08;partx&#xff09;&#xff1b; 为分区创建物理卷&#xff08;pvcreate&#xff0…

电脑如何录屏?三款电脑录屏工具分享

电脑如何录屏&#xff1f;作为一个经常需要录制电脑屏幕大职场人&#xff0c;不是为了制作教程、记录会议&#xff0c;就是偶尔想自己做个游戏解说视频。市面上的录屏软件琳琅满目&#xff0c;经过一番尝试和比较&#xff0c;我选出了三款我个人认为表现不错的软件&#xff0c;…

Qt qss以及对话框

字体对话框的实现 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }void Widget::on_fontbtn_clicked() {bool ok;QFont ret…

开源的向量数据库Milvus

Milvus是一款开源的向量数据库&#xff0c;专为处理向量搜索任务而设计&#xff0c;尤其擅长处理大规模向量数据的相似度检索。 官网地址&#xff1a;https://milvus.io/ 以下是关于Milvus的详细介绍&#xff1a; 一、基本概念 向量数据库&#xff1a;Milvus是一款云原生向量…

pyinstaller打包vnpy项目

因为我写的软件主要是自己用&#xff0c;很少有打包的习惯&#xff0c;直接源代码部署&#xff0c;导致打包&#xff0c;以下记录一下给一个朋友做的&#xff0c;对vnpy的改写&#xff0c;实现实时读取信号文件&#xff0c;发现文件中信号改变就做出相应的交易动作&#xff0c;…

离线安装 MySQL 数据库系统并实现远程登录

MySQL 5.7.25 的安装包&#xff0c;存放在 /opt/software 目录下 详细步骤 一、离线安装 MySQL 数据库系统1. 解压安装包2. 安装 MySQL 组件3. 登录 MySQL&#xff08;1&#xff09;初始化 MySQL 的数据库&#xff08;2&#xff09;启动 MySQL 服务&#xff08;3&#xff09;登…

书生大模型学习笔记9 - LMDeploy 量化部署

LMDeploy 量化部署 InternLM 2.5 20b量化前部署W4A16 模型量化量化模型部署streamlit web InternLM 2.5 20b量化前部署 lmdeploy serve api_server \/root/learning/InternLM/XTuner/merged_20b \--model-format hf \--quant-policy 0 \--cache-max-entry-count 0.01\--server…

创建干净虚拟环境对YOLOV8进行打包

背景 基于Yolov8写了一个视频检测小demo&#xff0c;考虑后续要到项目上使用&#xff0c;所以研究了一下打包流程。使用的工具是Pyinstaller&#xff0c;在原有的环境下面打包发现&#xff0c;大小有6个多G。所以想再弄一个干净的环境&#xff0c;只安装需要的模块&#xff0c…