第七十一天学习记录:对陈正冲编著《C 语言深度解剖》中关于1、2、4,5章作者留下部分问题的学习

news2024/9/25 21:27:09

问:有如下代码。

static int j;

void fun1(void)
{
	static int i = 0;
	i++;
}

void fun2(void)
{
	j = 0;
j++;
}

int main()
{
	int k = 0;
	for (k = 0; k<10; k++)
	{
		fun1();
		fun2();
	}
	return 0;
}

i 和 j 的值分别是什么,为什么?
答:
在这份代码中,变量 i 和 j 分别是函数 fun1 和 fun2 的静态局部变量。静态局部变量在函数内部声明,但在整个程序生命周期内都存在,且只初始化一次(第一次进入函数时初始化)。

在 main 函数中,fun1 和 fun2 分别被调用了 10 次,这意味着变量 i 和变量 j 都被分别累加了 10 次。但是由于变量 i 是函数 fun1 的静态局部变量,所以它的值在每次 fun1 调用后都会被保留。因此,最终 i 的值是 10,而 j 是一个全局变量,每次 fun2 调用都会将其值重置为 0,所以最终 j 的值是 1。

问:在 switch case 语句中能否使用 continue 关键字?为什么?
答:
在C/C++中,可以使用continue关键字来终止当前循环中的迭代,并开始下一轮迭代。但是,在switch-case语句中,不能使用continue关键字。

原因是,在switch-case语句中,switch关键字后跟随一个表达式,这个表达式决定了程序流程的走向。case标签则是用来匹配表达式结果的值之一。当匹配成功时,程序会执行对应的分支,并直接跳转到switch语句的结束位置,而不是进入一个循环体内部。因此,在switch语句内部使用continue关键字是没有意义的,也是无效的。如果需要提前结束switch-case语句的执行,可以使用break关键字来实现。

需要注意的是,在含有循环语句的switch-case代码块中,仍可以使用continue来终止当前循环中的迭代,并开始下一次迭代。但是,这与switch-case语句本身并没有直接联系,而只是循环语句的一种使用方式。

问:return ;
这个语句有问题吗?如果没有问题,那返回的是什么?

答:
return ;语句在函数中表示空返回,即返回值为空,并且结束当前函数的执行。这个语句不会报错,是合法的语法。

当函数的返回类型为void时,可以使用return ;来显式地返回空值。如果没有写return语句或者return后面没有指定返回值,也默认会返回一个空值,即函数的返回值为void。

当函数的返回类型不是void时,直接使用return ;是不合法的,编译器会报错。此时必须提供与返回类型相符的返回值表达式,将其作为return语句的参数来进行返回。

问:case 语句后面是否可以是 const 修饰的只读变量呢?
答:
在C/C++的case语句中,case标签后可以是常量表达式,但不能是变量。常量表达式是指在编译时就可以计算出结果的表达式,可以由字面值、枚举常量、const 变量或者 constexpr 函数等构成。

常量变量是指定义时使用了关键字const修饰的变量,它们的值在定义后不可更改。但是,在case标签后不能使用常量变量作为标签值,因为常量变量只有在运行时才能获取其值,而case标签要求在编译时就可以确定其值。

如果需要在switch-case语句中使用变量作为标签值,可以使用default标签来代替,然后在switch语句内部使用if-else判断来实现相应的逻辑。
问:以下代码杂x86系统下输出为多少?

#include <stdio.h>
int main()
{
	int a[5] = { 1,2,3,4,5 };
	int *ptr1 = (int *)(&a + 1);
	int *ptr2 = (int *)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

答:5,20

问:sizeof(ColorVal)的值为多少?为什么?
答:
sizeof(ColorVal)的值为4,因为枚举类型在内存中占用的空间是与int类型相同的。在C/C++中,枚举类型本质上是int类型的一种特殊取值方式,它只是通过标识符来方便地指代一组整数值,并不会改变其实际的数据类型。

因此,在定义枚举变量时,编译器会将其所定义的枚举类型映射为一个整数(如在上述代码中,GREEN=1, RED=2, BLUE=3,等等),并在内存中按照int类型的存储方式分配所需的空间。在32位机器上,int类型占用4个字节的空间,因此枚举变量ColorVal所占据的空间也是4个字节。

问:看看下面的代码:

#include <stdio.h>

int main()
{
	char a[5] = { 'A','B','C','D' };
	char(*p3)[5] = &a;
	char(*p4)[5] = a;
	printf("p3=%p,p4=%p,p3+1=%p,p4+1=%p\n", p3, p4, p3 + 1, p4 + 1);
	return 0;
}

上面对 p3 和 p4 的使用,哪个正确呢?p3+1 的值会是什么?p4+1 的值又会是什么?
答:
在这里插入图片描述
问:对 NULL 指针连续 free 多次会出错吗?为什么?如果让你来设计 free
函数,你会怎么处理这个问题?

答:
对 NULL 指针进行 free 是没有意义的,因为 free 会释放指向的动态分配内存,并将指针所指向的位置标记为未被分配状态。因此在调用 free 前需要对指针进行非空判断。

如果对一个已经被释放的指针再次进行 free ,就会发生 undefined behavior(未定义行为),包括程序崩溃,内存泄漏,程序运行出现不可预测的错误等情况,这是因为 free 函数只能释放一次动态分配的内存,多次释放同一块内存会破坏内存管理系统的数据结构。

为了避免这种问题的发生,我们可以在每次 free 后将指针赋值为 NULL,即:

int *p = (int *)malloc(sizeof(int));
if (p != NULL) { 
    // do something 
    free(p); 
    p = NULL;   // 将指针赋 NULL
}

这样即使误操作多次 free,也不会造成实际上的内存重复释放。

另外,还可以采用一些静态分析工具或者内存检测工具提前捕获类似的问题,避免出现重复释放内存的情况。

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

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

相关文章

Dtop环球嘉年华推动Web 3.0国际电商领域的革新

随着互联网技术的与日俱进和数字经济的高速发展,国际贸易正在经历一场重大变革。其中,跨境电商作为一种新兴的商业模式,正在全球迅速崛起。然而,自2021年以来,跨境电商行业也面临着各种风险和挑战,如各国增值税新规、电商账号封禁事件以及海运价格持续上涨等冲击。这些因素共同…

Spark SQL数据帧与数据集

文章目录 一、数据帧 - DataFrame&#xff08;一&#xff09;DataFrame概述&#xff08;二&#xff09;将RDD转成DataFrame 二、数据集 - Dataset&#xff08;一&#xff09;Dataset概述&#xff08;二&#xff09;将RDD转成DataSet&#xff08;三&#xff09;DataFrame与Datas…

ATA-4000系列高压功率放大器——超声导波中的典型应用

ATA-4000系列高压功率放大器——超声导波中的典型应用 超声导波技术 超声导波(guided waves ultrasonic)技术是一项近年来广受关注的无损检测技术。导波是由于介质边界存在而被限制在介质中传播的、同时其传播方向平行于介质边界的波。超声导波较早期的研究由一些著名学者完成&…

react + antd实现动态切换主题功能(适用于antd5.x版本)

前言 在之前的几篇文章中&#xff08;React Antd实现动态切换主题功能之二&#xff08;默认主题与暗黑色主题切换&#xff09;、React Antd实现动态切换主题功能&#xff09;介绍了antd实现动态切换主题功能&#xff0c;文章里介绍的方法在antd5.x版本却不适用&#xff0c;因…

【UE5】分分钟简单使用像素流云服务(Pixel Streaming)

【UE5】分分钟简单使用像素流云服务&#xff08;Pixel Streaming&#xff09; 前言 UE5的Pixel Streaming已经封装的很好&#xff0c;简单三步实现简单的服务搭建。 安装插件打包项目运行服务 注&#xff1a;实例平台为Windows 安装插件 编辑→插件→输入查询Pixel Strea…

Java之~Bigdicmal的长度,小数点后用0补位

/*** 获取bigdicmal的长度* param number 需要截取的数字* param num 需要保留小数点后的位数* return*/ public static int checkBigDecimalLength(String number ,int num){String s getSupString(number,num);return s.length(); }/*** 补充后面数值0* param number 需要截…

5G技术学习——5GNR帧结构和空口资源

这里写目录标题 4G时域定义&#xff1a;资源划分 5GNR中时域 频域 与空域资源 循环前缀CP:背景和原理5G帧结构&#xff1a;基本框架5G slot分类 5G 频域资源5G频域资源基本概念信道带宽与传输带宽BWP定义及其应用场景 4G 时域定义&#xff1a; 帧&#xff1a;10ms&#xff0c;…

【go-zero】go-zero微服务实战系列九 聚合策略 极致优化秒杀性能(转)

上一篇文章中引入了消息队列对秒杀流量做削峰的处理,我们使用的是Kafka,看起来似乎工作的不错,但其实还是有很多隐患存在,如果这些隐患不优化处理掉,那么秒杀抢购活动开始后可能会出现消息堆积、消费延迟、数据不一致、甚至服务崩溃等问题,那么后果可想而知。本篇文章我们…

深度学习-pytorch_lightning框架使用实例

下面是我写过的一个pytorch_lightning项目的代码框架。关键代码已经省略。 模型构建 import pytorch_lightning as pl from pytorch_lightning.plugins.io import TorchCheckpointIO as tcio import torch from torch import nn import torch.nn.functional as F from torch.…

师生相逢,潇潇洒洒出品

师生相逢2023年6月10日潇潇洒洒出品骑行肩并肩 相望曾相识①遥忆多年前 青春勃发时豪情梦摘星 清纯玉壶冰感叹岁月老 友情弥久新寄情山水间 天涯不负卿①骑行路上&#xff0c;偶遇30年前的学生&#xff0c;现在是骑行群的骑友&#xff0c;共同的兴趣爱好使我们30年后再相逢&…

【服务器数据恢复】热备盘激活失败导致raid5瘫痪的数据恢复案例

服务器数据恢复环境&#xff1a; 一台EMC存储中数块磁盘组建了一组raid5磁盘阵列&#xff0c;阵列中有2块热备盘&#xff1b;上层采用ZFS文件系统&#xff0c;划分了一个lun&#xff0c;供sun小机使用。 服务器故障&检测&#xff1a; 存储在正常运行中突然崩溃无法使用&…

STM32单片机(五)第一节:EXTI外部中断

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

AST反混淆js代码——猿人学竞赛第二题

猿人学JS比赛第二题解混淆 分析代码解混淆代码结果 前一段时间参加猿人学js比赛&#xff0c;今天把第二题的还原做一下笔记。 分析代码 首先&#xff0c;我们需要对混淆js代码进行分析&#xff0c;确定还原的思路&#xff0c;才能书写解混淆代码进行还原。代码是静态的&#x…

KYOCERA Programming Contest 2023(AtCoder Beginner Contest 305)(A、B、C、D)[施工中]

文章目录 A - Water Station(模拟)B - ABCDEFG&#xff08;模拟&#xff09;C - Snuke the Cookie Picker(模拟、暴力)D - Sleep Log&#xff08;二分&#xff0c;前缀&#xff09; A - Water Station(模拟) 题意&#xff1a;在[0,100]所有 x % 5 0的地方设置一个水站&#x…

由源码生成Python可调用的dll

1. 不带参数的函数与调用 blog.csdn.net/qq 40833391/article/details/128000638python编程&#xff08;python调用dll程序&#xff09;_python 调用dll_嵌入式-老费的博客-CSDN博客思路很简单&#xff0c;只需要在Visual Studio中设置输出类型即可 1.1. 创建项目 首先创建一…

【HashMap集合】存储学生对象并遍历

HashMap集合存储学生对象并遍历 1.键是String&#xff0c;值是Student 需求&#xff1a;创建一个HashMap集合&#xff0c;键是学号(String)&#xff0c;值是学生对象(Student)。存储三个键值对元素&#xff0c;并遍历 思路&#xff1a; 定义学生类 创建HashMap集合对象 创建…

uni.navigateBack()返回上一页携带参数的实现

a页面跳转b页面&#xff0c;再b页面点击确定返回到a页面刷新列表 //b页面confirm(){let pages getCurrentPages();//当前页面let prevPage pages[pages.length - 2];//上一个页面prevPage.setData({//直接给上一个页面赋值isRefresh: true})uni.navigateBack();} 返回到a页面…

适用于 Linux 的 Windows 子系统wsl文档

参考链接&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜&#xff1a;http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…

【Protobuf】Map类型的使用

文章目录 2.4 map 类型一、 基本认识二、map相关函数4.3 contact2.4的改写 2.4 map 类型 本系列文章将通过对通讯录项目的不断完善&#xff0c;带大家由浅入深的学习Protobuf的使用。这是Contacts的2.4版本&#xff0c;在这篇文章中将带大家学习Protobuf的 map 语法&#xff0c…

STM32F407软件模拟I2C实现MPU6050通讯(CUBEIDE)

STM32F407软件模拟I2C实现MPU6050通讯&#xff08;CUBEIDE&#xff09; 文章目录 STM32F407软件模拟I2C实现MPU6050通讯&#xff08;CUBEIDE&#xff09;模拟I2C读写的实现mpu6050_iic.cmpu6050_iic.h代码分析 复位&#xff0c;读取温度&#xff0c;角度等函数封装mpu6050.cmpu…