指针(6)

news2024/11/19 11:28:26

1. sizeof和strlen的对比

1.1 sizeof

  • 在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的大小。

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

  • sizeof是操作符 不是函数

int main() {
    int a = 10;
    printf("%zd\n", sizeof(int));
    printf("%zd\n", sizeof(a));
    int arr[10] = { 0 };//里面放了什么数据不会影响 
    printf("%zd", sizeof(arr)); //只关注内存空间大小
}

1.2 strlen

  • strlen库函数,求字符串的长度,只能针对字符串(字符数组)

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

int main() {
    char arr[] = { 'a','b','c' }; //char 一个字符一个字节
    char arr1[] = "abc";
    int arr2[] = { 1,2 };//int 一个整形4个字节
    //strlen函数 计算数组的元素个数(字符串)
    printf("%zd\n", strlen(arr));
    printf("%zd\n", strlen(arr1));
    //sizeof 不关注里面存的数据 只关注数组的大小
    printf("%zd\n", sizeof(arr));//3
    printf("%zd\n", sizeof(arr1));//4 把\0也也统计了
    printf("%zd\n", sizeof(arr2));//8
    return 0;
}

1.3 sizeof和strlen比较

sizeofstrlen
1. sizeof是操作符1.strlen是库函数,使⽤需要包含头⽂件 string.h
2. sizeof计算操作数所占内存的大小,单位是字节2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数
3.不关注内存中存放什么数据3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能越界

2..数组和指针笔试题解析

2.1 ⼀维数组

  • 整形的地址, -->(&a) 是地址都是4(x86)/8(x64)

  • arr 只有在-->sizeof(arr)&arr的时候 不是表示首字元素的地址

  • sizeof(arr) ---> 整个数组的大小,单位是字节

  • &arr ---> 整个数组的地址 -->> 4 或者8

  • sizeof(arr+0) 因为他不是 sizeof(arr) 这种形式 所以它代表的是首元素地址 +0 也一样

int main() {
    int a[] = { 1,2,3,4 };
    printf("%zd\n", sizeof(a));
    printf("%zd\n", sizeof(a + 0));
    printf("%zd\n", sizeof(*a));
    printf("%zd\n", sizeof(a + 1));
    printf("%zd\n", sizeof(a[1]));
    printf("%zd\n", sizeof(&a));//4 或者 8
    printf("%zd\n", sizeof(*&a));//16
    printf("%zd\n", sizeof(&a + 1));//4 或者 8
    printf("%zd\n", sizeof(&a[0]));//4 或者 8
    printf("%zd\n", sizeof(&a[0] + 1));//4 或者 8
}
  • 看如下解析

2.2字符数组

2.2.1代码1
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//整个数组的大小6个元素 6个字节
printf("%d\n", sizeof(arr+0));//  首元素地址4/8
printf("%d\n", sizeof(*arr));// 首元素大小1
printf("%d\n", sizeof(arr[1]));//首元素大小1
printf("%d\n", sizeof(&arr));//首元素地址 4/8
printf("%d\n", sizeof(&arr+1));//第二个元素地址 4/8
printf("%d\n", sizeof(&arr[0]+1));//第二个元素地址 4/8
2.2.2代码2

字符数组 strlen函数找不到\0 输出随机值

int main() {
    char arr[] = { 'a','b','c','d','e','f' };
    printf("%zd\n", strlen(arr));
    printf("%zd\n", strlen(arr + 0));
    printf("%zd\n", strlen(*arr));
    printf("%zd\n", strlen(arr[1]));
    printf("%zd\n", strlen(&arr));
    printf("%zd\n", strlen(&arr + 1));
    printf("%zd\n", strlen(&arr[0] + 1));
}
2.2.3代码3
  • char arr[] = "abcdef";
  • 数组中存放的是{a,b,c,d,e,f,\0}
int main() {
    char arr[] = "abcdef";
    //{ a b c d e f \0}
    printf("%zd\n", sizeof(arr));//7 
    printf("%zd\n", sizeof(arr + 0));//4/8
    printf("%zd\n", sizeof(*arr));//1
    printf("%zd\n", sizeof(arr[1]));//1
    printf("%zd\n", sizeof(&arr));//4或8
    printf("%zd\n", sizeof(&arr + 1));//4或8
    printf("%zd\n", sizeof(&arr[0] + 1));//4或8
    return 0;
​
}
2.2.4代码4
  • printf("%d\n", strlen(&arr));

    &arr 的类型是 char (*) [7]

    strlen函数接受的类型是 (const char* str) &arr传给strlen的话会进行强制转换,从第一个元素开始数,最后输出也是6

  • printf("%d\n", strlen(&arr + 1));

    &arr+1 直接跳到数组的最后个元素,从该位置开始往后数,不知道后面有啥元素就返回一个随机

int main() {
    char arr[] = "abcdef";
    //arr 是首元素地址 strlen从第一个元素往后统计个数 一直到\0
    printf("%d\n", strlen(arr)); //6 
    printf("%d\n", strlen(arr + 0));//6
    //printf("%d\n", strlen(*arr)); 得到一个元素'a' 找97的字符个数,程序报错 
    //printf("%d\n", strlen(arr[1]));'b',程序报错
    printf("%d\n", strlen(&arr));
    printf("%d\n", strlen(&arr + 1));
    printf("%d\n", strlen(&arr[0] + 1));//第二个元素开始数 5
} 
2.2.5代码5

p[0] 等价于 *(p+0)

int main() {
    char* p = "abcdef";
    printf("%zd\n", sizeof(p));
    printf("%zd\n", sizeof(p + 1));
    printf("%zd\n", sizeof(*p));
    printf("%zd\n", sizeof(p[0]));
    printf("%zd\n", sizeof(&p));
    printf("%zd\n", sizeof(&p + 1));
    printf("%zd\n", sizeof(&p[0] + 1));
}
2.2.6代码6
  • &p[0] 等价于 & * (p+0) 等价于 p

  • 所以strlen(&p[0]+1) 输出 5

char *p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(p+1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));

2.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]));

  • 注意:a[3] 数组越界,但是sizeof内部的表达式不会真实计算,只会看它的类型int [4],所以只计算4个整形元素的大小 16个字节

  • 如果不懂我们在再看看以下列子,他输出的是什么呢?

  • 答案是4 因为sizeof内部不进行计算,只会看a的类型,a是整形所以是4个字节

int main() {
    int a = 3;
    int b = 3;
    printf("%zd", sizeof(a = b + 3));
}

3.指针运算笔试题解析

3.1题目1

#include <stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int* ptr = (int*)(&a + 1); //int(*) 强制类型转换
    printf("%d,%d", *(a + 1), *(ptr - 1)); //输出 2 5 
    return 0;
}

3.2题目2

  • 注意:

    指针加1==>跳过一个指针类型大小

    整数加1==>那就是加上一个1

//在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;
}
  • 为了让我们更好的理解以上代码,我们拆分如下
struct Test
{
    int Num;
    char* pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*  这个代表的是结构体指针的类型 
p是指针变量 
(struct Test*) 0x100000
0x100000代表的是一个八进制数,整形  
(struct Test*) 强制类型转换成 结构体指针类型

3.3题目3

  • 我们是不是觉得他是一个三行两列的二维数组,其实并不是

  • 我们数组赋值时用的是{ },并非( ), ( )代表的是括号表达式,从左向右计算,最终结果取右边的数值 例如(0,1) ==> 1

  • 所以该数组的是 {1 , 3 , 5}

  • 所以p[0] 输出 1

#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;
}

3.4题目4

  • 地址 ➖ 地址 = 元素个数 小地址减去大地址 取负数

  • -4在内存中以补码形式保存

  • %p 打印16进制的地址,输出就是内存中保存 的-4的补码 ==>FF FF FF FC

  • %d 打印原码 有符号数 -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;
}

3.5题目6

  • (*(aa+1)) 等价于 aa[1] 第一行首元素的地址+1 然后解引用等于 6

#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)); //10  5
 return 0;
}

3.6题目6

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

3.7题目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;
}
  • 注意: 一开始 ++cpp 这个运算 cpp自身的值发生改变 后面的结果会受到影响

  • 第一个输出

  • 第二个输出

  • 第三个输出

  • 第四个输出

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

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

相关文章

精品丨快速申请免费https证书

https域名证书对提高网站排名有一定的好处&#xff0c;所以当今很多企业为了给网站一个好的安全防护&#xff0c;就会去申请该证书。如今很多企业虽然重视网站的安全防护&#xff0c;但是也重视成本&#xff0c;所以为了节约成本会考虑申请免费的https证书。 第一个好处 企业不…

力扣496. 下一个更大元素 I

Problem: 496. 下一个更大元素 I 文章目录 题目描述思路复杂度Code 题目描述 思路 因为题目说nums1是nums2的子集&#xff0c;那么我们先把nums2中每个元素的下一个更大元素算出来存到一个映射里&#xff0c;然后再让nums1中的元素去查表即可 复杂度 时间复杂度: O ( n 1 n 2…

吉林大学计科21级《软件工程》期末考试真题

文章目录 21级期末考试题一、单选题&#xff08;2分一个&#xff0c;十个题&#xff0c;一共20分&#xff09;二、问答题&#xff08;5分一个&#xff0c;六个题&#xff0c;一共30分&#xff09;三、分析题&#xff08;一个10分&#xff0c;一共2个&#xff0c;共20分&#xf…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-22讲 RTC 时钟设置

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

十四天学会Vue——Vue核心(理论+实战)(第一天)上篇

&#xff01;&#xff01;&#xff01;声明必看&#xff1a;由于本篇开始就写了Vue&#xff0c;内容过多&#xff0c;本篇部分内容还有待完善&#xff0c;小编先去将连续更新的js高阶第四天完成~本篇部分待完善内容明日更新 一、Vue核心&#xff08;上篇&#xff09; 热身top…

mysql - 索引原理

mysql索引原理 文中的查询, 以该表结构为例 CREATE TABLE user (id int NOT NULL COMMENT id,name varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 姓名,age int NOT NULL COMMENT 年龄,sex tinyint(1) NOT NULL COMMENT 性别,phone varchar(255) CHARACTER SET utf8mb4…

06中间件RTOS/CP

Autosar CP 操作系统详解-CSDN博客 1. 什么是RTOS &#xff1f; RTOS&#xff0c;英文全称是 Real-time Operation System&#xff0c;中文就是 实时操作系统&#xff0c;又称及时操作系统。 实时操作系统&#xff0c;是指当外界事件或数据产生时&#xff0c;能够接受并以足…

GEC210编译环境搭建

一、下载编译工具链 下载&#xff1a;点击跳转 二、解压到 /usr/local/arm 目录 sudo mv gec210.zip /usr/local/arm cd /usr/local/arm sudo unzip gec210.zip 三、添加到环境变量 PATH/usr/local/arm/arm-cortex_a8-linux-gnueabi-4.7.3/bin:$PATH 四、测试验证 在终端…

微信小程序如何跳转微信公众号

1. 微信小程序如何跳转微信公众号 1.2. 微信公众号配置 登录微信公众号&#xff0c;点击【小程序管理】&#xff1a;   点击【添加】&#xff1a;   点击【关联小程序】&#xff1a;   输入小程序进行关联&#xff1a; 1.2. 微信小程序配置 登录微信小程序&#xf…

力扣刷题---LCS 02. 完成一半题目【简单】

题目描述 有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&…

【NumPy】关于numpy.sum()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

JAVA实现图书管理系统(初阶)

一.抽象出对象: 1.要有书架&#xff0c;图书&#xff0c;用户&#xff08;包括普通用户&#xff0c;管理员用户&#xff09;。根据这些我们可以建立几个包&#xff0c;来把繁杂的代码分开&#xff0c;再通过一个类来把这些&#xff0c;对象整合起来实现系统。说到整合&#xf…

C++ List完全指南:使用方法与自定义实现

文章目录 list的使用几种构造函数 list的实现1.节点类的定义1.1节点类的构造函数 2.正向迭代器实现2.1operator*重载2.2operator->重载2.3operator重载2.4operator--2.5operator和operator&#xff01; 3.反向迭代器实现3.1operator*重载3.2operator->重载3.3operator重载…

SpringBoot使用Mock进行单元测试

需求说明&#xff1a;需要对一个service接口进行单元测试 1.在pom.xml中加入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-ins…

计算机网络 1

两台主机想通信&#xff0c;其实本质就是两个文件的资源交换&#xff0c;但是长距离的通信&#xff0c;面临的是很多的问题。这个时候需要通过一些方式来保证可靠性 什么是协议 这样一个例子&#xff0c;我是住在农村&#xff0c;我读高中了我需要去县里面读书。这个时候呢&…

arm64虚拟化-CPU虚拟化

arm64虚拟化-CPU虚拟化 1 虚拟化1.1 CPU虚拟化1.2 内存虚拟化1.3 I/O虚拟化 2 异常状态2.1 AArch642.2 AArch32 3 启动到EL2异常等级4 CPU虚拟化4.1 进入VM4.2 退出VM 本篇博客是基于对苯叔《ARM64高级特性专题》的学习而总结的&#xff0c;大家如有需要可以去淘宝或者奔跑吧li…

【Nginx <末>】Nginx 基于 IP 地址的访问限制

目录 &#x1f44b;前言 &#x1f4eb;一、限制 IP 可以实现哪些功能 &#x1f440;二、 项目实现 2.1 访问控制实现 2.2 Nginx 配置中指定 IP 地址 &#x1f49e;️三、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;前面一段时间学习了 Nginx 的相关知识&#xff0c…

DAMA数据管理知识体系必背18张框图

近期对数据管理知识体系中比较重要的框图进行了梳理总结,总共有18张框图,供大家参考。主要涉及数据管理、数据治理阶段模式、数据安全需求、主数据管理关键步骤,主数据架构、DW架构、数据科学的7个阶段、数据仓库建设活动、信息收敛三角、大数据分析架构图、数据管理成熟度等…

Jenkins--从入门到入土

Jenkins–从入门到入土 文章目录 Jenkins--从入门到入土〇、概念提要--什么是CI/DI&#xff1f;1、CI&#xff08;Continuous Integration&#xff0c;持续集成&#xff09;2、DI&#xff08;DevOps Integration&#xff0c;DevOps 集成&#xff09;3、解决的问题 一、Jenkins安…

【深度学习】1.手动LogisticRegression模型的训练和预测

通过这个示例&#xff0c;可以了解逻辑回归模型的基本原理和训练过程&#xff0c;同时可以通过修改和优化代码来进一步探索机器学习模型的训练和调优方法。 步骤&#xff1a; 生成了一个模拟的二分类数据集&#xff1a;通过随机生成包含两个特征的数据data_x&#xff0c;并基于…