C语言中那些后知后觉的细节冷知识(二)typedef、死循环、位移、内存访问

本文主要是介绍C语言中那些后知后觉的细节冷知识(二)typedef、死循环、位移、内存访问,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

系列文章目录

C语言中那些后知后觉的细节冷知识(一)static、const、volatile、数组、宏
C语言中那些后知后觉的细节冷知识(二)typedef、死循环、位移、内存访问
持续更新中… …


文章目录

  • 系列文章目录
  • 前言
  • 一、typedef
  • 二、死循环
  • 三、位移
  • 四、内存访问
  • 总结


前言

C语言诞生于1972年11月,由美国电话电报公司(AT&T)贝尔实验室的丹尼斯·里奇(Dennis Ritchie)发明,在1978年,美国电话电报公司(AT&T)贝尔实验室正式发布了C语言。C语言作为一种经典的编程语言,时至今日,仍然在许多领域仍然被广泛使用,并且仍然是一种强大、高效和灵活的编程语言。
学习C语言对于初学者来说可能有一定的难度,因为C语言是一种比较底层的编程语言,它提供了更接近计算机硬件的控制能力。与一些更高级的编程语言相比,C语言在语法和概念上可能更加复杂,需要更多的时间和精力来学习和掌握。
今天继续分享一些C语言的细节冷知识,主要涉及typedef、死循环、位移、直接内存访问等,希望对大家有所帮助。


一、typedef

在C语言中,typedef关键字用于为一个已经存在的类型创建一个新的名字。它通常用于帮助你简化代码、提高可读性,并为底层数据类型提供抽象。经常被用于为基本数据类型定义别名、为结构体定义别名、为枚举定义别名、为函数指针定义别名等。
与其比例类似的是宏定义#define,需要注意区别。比如以下例子:

#define dS struct s * typedef struct s * tS; 

以上两种情况的都是要定义dS 和 tS 作为一个指向结构s指针。哪种方法更好呢?答案是:typedef更好。思考下面的例子:

dS p1,p2;tS p3,p4;

第一个例子在宏定义展开替换后为“Struct s * p1, p2;”,定义p1为一个指向结构体的指针,而p2为一个实际的结构。而第二个例子正确的定义了p3和p4两个指向结构体的指针。
所以一般在用于为一个已经存在的类型创建一个新的名字时,应尽量使用typedef,而不是#define。

二、死循环

死循环即无限循环,其实是普通的循环结构,但是没有退出循环的条件,即实现了无限循环。C语言中一般有以下几种方式实现死循环:
1、while(1){ … … }
2、for(;😉{ … … }
3、结合goto,如:
Loop:
… …
goto Loop;

推荐使用第一种while(1);如果使用第二种for(;😉,你也要了解为什么这样写for语句代表无限循环(其实就是第二个“;”语句中未填写退出for循环的条件造成的);第三种比较少用,可能经常写汇编语言的程序员会使用这种方式,但是不推荐。在C语言中,goto语句是一种控制流语句,允许程序无条件地跳转到程序中的另一个位置,但是很多的编码标准都谈及了避免或限制使用goto,主要原因是使用goto会降低代码的可读性、破坏程序的结构化、增加调试难度等。

三、位移

在C语言中,位移操作被广泛应用于各种场景,主要是由于其能够高效地操作二进制数据。位移操作通常比乘法和除法操作更快,因此在对性能有要求的计算场景中,可以使用位移来替代乘法和除法(左移N位相当于乘以2的N次幂,右移N位则相当于除以2的N次幂)。
在C语言中使用位移操作符(左移 << 和右移 >>)时,需要注意以下几点:
1、操作数的类型:位移操作符通常应用于整数类型(如short 、int、long等)的操作数。对浮点数应用位移操作符是未定义的行为(各位可以查一查浮点数在内存中的存储方式,就知道为什么了);
2、符号位:对于有符号整数,位移操作可能会涉及到符号位(最高位)。左移时,符号位会被“推出去”,并从另一端补入新的位(通常是0,但取决于具体的实现)。右移时,符号位的行为取决于编译器:算术右移(保留符号位)或逻辑右移(不保留符号位);
3、位移量:位移量应该是非负整数,并且小于或等于被操作数类型的位数。例如,对于32位整数,有效的位移量范围是0到31。超出这个范围的位移量可能导致未定义的行为。在实际编程中,通常会使用无符号类型(如 unsigned int)的变量来存储位移量,以避免负值;
4、无符号整数与有符号整数的区别:对于无符号整数,位移操作通常是逻辑移位,即左移时补0,右移时也补0。而对于有符号整数,右移可能是算术移位(保留符号位)。

四、内存访问

C语言主要运用于嵌入式系统中,而嵌入式系统经常会要求程序员去访问某特定的内存位置,主要的方式就是采用将绝对地址的整型数强制转换为指针,从而进行内存访问。比如:

int *ptr;
ptr = (int *)0x123456;
*ptr = 0xAABB;
//或者
*(int *)(0x123456) = 0xAABB;

上述代码可以实现对绝对地址为0x123456的内存赋值为0xAABB的目的。


总结

以上都是一些C语言的基础,但却又是平时编程中很容易因为疏忽出现问题的地方。更多的细节冷知识将在后续系列文章中持续更新,希望对大家有所帮助。

这篇关于C语言中那些后知后觉的细节冷知识(二)typedef、死循环、位移、内存访问的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/678939

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir