指针(6)

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自身的值发生改变 后面的结果会受到影响

  • 第一个输出

  • 第二个输出

  • 第三个输出

  • 第四个输出

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

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

相关文章

leetcode:计数质数

class Solution { public:// 如果 x 是质数&#xff0c;那么大于 x 的 x 的倍数 2x,3x… 一定不是质数int countPrimes(int n) {vector<int> isPrime(n, 1);int ans 0;for (int i 2; i < n; i) {if (isPrime[i]) {ans 1;if ((long long)i * i < n) {for (int j …

Linux内核重置root密码

Ubuntu 首先重新启动Ubuntu系统&#xff0c;然后快速按下shift键&#xff0c;以调出grub启动菜单在这里我们选择第二个&#xff08;Ubuntu高级选项&#xff09;&#xff0c;选中后按下Enter键 选择最高的Linux内核版本所对应的recovery mode模式&#xff0c;按e键编辑启动项 在…

C语言 | Leetcode C语言题解之第113题路径总和II

题目&#xff1a; 题解&#xff1a; int** ret; int retSize; int* retColSize;int* path; int pathSize;typedef struct {struct TreeNode* key;struct TreeNode* val;UT_hash_handle hh; } hashTable;hashTable* parent;void insertHashTable(struct TreeNode* x, struct Tr…

数据结构——链表——模板类实现双向链表——先完成再完美——持续更

链表&#xff1a;概念&#xff0c;实现&#xff0c;《数据结构》这里实现是基于模板的 C语言基础&#xff0c;指针&#xff0c;引用。模板。《CPrimer》有些进阶用法放在语言学习的目录 LeetCode应用&#xff0c;会更新在LeetCode150&#xff0c;目前这个系列先暂停&#xff0c…

【PB案例学习笔记】-09滚动条使用

写在前面 这是PB案例学习笔记系列文章的第8篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gitee…

云界洞见——基于移动云云数据库MySQL应用实践

目录 简介1 新手入门1.1 创建MySQL实例1.2 公网连接MySQL实例 2 操作指南2.1 创建数据库2.2 数据备份设置2.3 日志管理2.4 监控告警2.5 代码审计 3 应用场景4 总结 如今&#xff0c;大型企业如金融企业和银行等&#xff0c;在下一代的微服务架构转型要求下&#xff0c;需要基础…

C++ prime 第五版 第14章 重载运算与类型转换

一、基本概念 重载的运算符是具有特殊名字的函数&#xff1a;它们的名字由关键字operator和其后要定义的运算符号共同组成。和其他函数一样&#xff0c;重载的运算符也包含返回类型、参数列表以及函数体。 我们不能为内置类型的运算对象重定义运算符。对于一个运算符函数来说&…

【Week-R1】RNN实现心脏病预测,基于tensorflow框架

文章目录 一、什么是RNN&#xff1f;二、准备环境和数据2.1 导入数据 三、构建模型四、训练和预测五、其他&#xff08;1&#xff09;sklearn模块导入报错&#xff1a;ModuleNotFoundError: No module named sklearn&#xff08;2&#xff09;优化器改为SGD&#xff0c;accurac…

MySQL--备份恢复

目录 一、备份恢复的工作职责 1.备份的时间周期 2.备份的方式 3.恢复方案 4.检查备份 5.定期恢复演练 6.故障恢复策略 7.迁移升级 二、逻辑备份工具--mysqldump 1.介绍 2.使用场景 3.mysqldump命令的参数介绍 1&#xff09;全备&#xff1a; 2&#xff09;单库或…

四轮麦轮平衡车四个轮子安放位置要求,以及编码器测速注意事项(强调,否则无法正常平移)——基于STM32F103ZET6

轮子推荐ABBA&#xff0c;当然BAAB也可以 如图安放&#xff1a; 这两种安防位置可以实现平移效果 若要实现平移则需要先实现PID控制平衡&#xff0c;这里用到520编码电机&#xff0c;相较于370电机他的动力更足&#xff0c;在调节PID时能节约不少时间而且更加容易。 需要注意…

基于离散小波变换(DWT)的心电信号伪影去除及心电信号PQRST波检测(MATLAB R2018)

心电信号是心脏神经&#xff0c;肌肉组织电化学活动的表现形式。这些电化学活动使心脏内部产生一系列非常协调的电刺激脉冲&#xff0c;分别使心房&#xff0c;心室的肌肉细胞兴奋&#xff0c;从而有节律的舒张和收缩。这些生物电活动在体表的不同部位形成不同的电位差变化&…

622.设计循环队列

typedef struct {int* a;int head;int tail;int k; } MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj); bool myCircularQueueIsFull(MyCircularQueue* obj);//初始化 MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj(MyCircularQue…

ARM+FPGA+NVIDIA AI摄像头软硬件定制

拥有资深ISP图像技术团队&#xff0c;是英伟达、地平线等合作伙伴&#xff0c;我们的团队掌握目前市面上大部分车载平台的ISP图像画质服务能力&#xff0c;能自主开发图像ISP和增强算法。我们具有多名经验丰富光学设计专家&#xff0c;掌握车载模组光学设计能力&#xff0c;资深…

Mac上如何安装低版本chrome浏览器

背景 为了排查项目上使用chrome低版本的兼容性问题&#xff0c;需要在本机【mac系统】上安装一个低版本的chrome浏览器。 不同版本的chrome下载地址 https://www.slimjet.com/chrome/google-chrome-old-version.php 下载后要记得你下载的旧版本的版本号&#xff0c;后面修改…

Neural Filters:着色

Ps菜单&#xff1a;滤镜/Neural Filters/颜色/着色 Neural Filters/COLOR/Colorize 着色 Colorize滤镜可以对黑白照片自动着色&#xff0c;也为彩色照片简化色彩提供了有力的支持。 “着色”滤镜利用深度学习技术&#xff0c;对输入的黑白或彩色照片进行分析&#xff0c;识别图…

【云原生】kubernetes声明式管理-----YAML文件

目录 引言 一、声明式管理简介 &#xff08;一&#xff09;什么是声明式管理 &#xff08;二&#xff09;支持格式 二、YAML文件 &#xff08;一&#xff09;YAML文件基本格式 &#xff08;二&#xff09;YAML文件实践 三、YAML文件创建方式 &#xff08;一&#xff0…

rk3568_spinlock

文章目录 前言1、spinlock是什么?2、自旋锁实验2.1源码2.2 结果图总结前言 本文记录在rk3568开发板做的自旋锁实验。通过自旋锁控制state变量来限制只有一个应用程序来打开驱动设备。 1、spinlock是什么? spinlock称为自旋锁,如果获取不到资源,就只能一直傻傻地等待资源被…

B树与B+树区别

B树和B树是常见的数据库索引结构&#xff0c;都具有相较于二叉树层级较少&#xff0c;查找效率高的特点&#xff0c;它们之间有以下几个主要区别&#xff1a; 1.节点存储数据的方式不同 B树的叶子结点和非叶子节点都会存储数据&#xff0c;指针和数据共同保存在同一节点中B树…

一文教你使用stream流轻松解决java项目数据枚举显示问题

本篇文章主要讲解java枚举、vo实体类通过stream流形式输出枚举参数的方法。 日期&#xff1a;2024年5月26日 作者&#xff1a;任聪聪 本文代码实例附件&#xff1a;https://download.csdn.net/download/hj960511/89361611 实际效果 可以看到在枚举参数的基础上&#xff0c;我们…

这或许是国产游戏出海的最佳时机

《刺客信条&#xff1a;影》过于政治正确的选角激怒了全球玩家&#xff0c;而社交媒体上有玩家讨论育碧是否应该因为刻意加入DEI&#xff08;多元化&#xff09;而延期《刺客信条&#xff1a;影》时&#xff0c;没想到这得到了X拥有人埃隆马斯克的回复。马斯克表示“DEI&#x…