当前位置:网站首页>C Pitfalls and Defects Chapter 7 Portability Defects 7.11 An Example of a Portability Problem
C Pitfalls and Defects Chapter 7 Portability Defects 7.11 An Example of a Portability Problem
2022-08-01 21:04:00 【weixin_Guest time】
An example of a portability problem
The effect is: converts the given long integer to its decimal representation, and calls
the function pointed to by the function pointer for each character in the decimal representation:
void printnum(long n, void (*p)())
{
if (n < 0) {
(*p) ('-');
n = -n;
} }
if (n >= 10) {
printnum(n / 10, p);
} }
(*p)((int)(n % 10) + '0');
}
The portability problem is analyzed as follows:
The first problem lies in the method used by the program to convert the last digits of the decimal representation of n to character form.Adding '0' to it to get the corresponding character representation is not necessarily appropriate.The program's addition operation dictates that the numbers in the machine's character set are ordered without gaps.The solution is to use a character table representing numbers.Because a string constant can be used to represent an array of characters, any occurrence of an array name can be replaced by a string constant.
The following expression is legal:
"0123456789"[n % 10]
void printnum(long n, void (*p)()) {
if (n < 0) {
(*p)('-');
n = -n;
} }
if (n >= 10) {
printnum(n/10, p);
}
(*p)("0123456789"[n % 10]);
}
The second question is related to the situation when n<0.The above program first prints a symbol, then sets n to -n.This assignment operation may overflow, because computers based on 2's complement generally allow the range of negative numbers to be represented to be larger than the range of positive numbers.
The solution is as follows:
The most obvious method is to assign -n to a variable of type unsigned long, and then operate on this variable.However, we cannot evaluate -n because doing so would cause an overflow!
For both 1's complement and 2's complement (1's complement and 2's complement) based machines, changing the sign of a positive integer ensures that overflow does not occur.The only trouble comes when changing the sign of a minus sign.Therefore, if we can not guarantee that n is not converted to the corresponding integer, then this problem can be avoided.
Annotation: The binary representation of a signed integer can be divided into three parts, namely the sign bit, the value bit and the padding bit.Padding just fills in the blanks, it doesn't make any sense.When the sign bit vector is 1, it represents a negative number. According to the different values represented by the sign bit, it is divided into one's complement and two's complement.Assuming a total of N bits of value bits,
(1) one's complement: the lower limit of the binary representation - (2^N - 1).
(2) two's complement: the lower limit of the binary representation -2^N.
We can handle positive and negative numbers in the same way, but print a negative sign when n is negative.To do this, the program forces n to be negative after printing the negative sign, and makes all arithmetic operations on negative numbers.
The printnum function only checks if n is negative, and if so, prints a negative sign.
The printneg function takes the inverse of the absolute value of n as an argument.In this way, the printneg function satisfies the condition that n is always negative or zero.
void printneg(long n, void (*p)()) {
if (n <= -10) {
printneg(n/10, p);
} }
(*p)("0123456789"[-(n % 10)]);
}
void printnum(long n, void (*p)()) {
if (n < 0) {
(*p)('-');
printneg(n, p);
} else {
printneg(-n, p);
}
}
Use n/10 and n%10 to represent the first and last digits of n, of courseChange the symbols appropriately.
To solve this problem, we can create two temporary variables to hold the quotient and remainder respectively.After the division operation is complete, check if the remainder is within a reasonable range; if not, adjust the two variables appropriately.What needs to be changed is the printneg function.
void printneg(long n, void (*p)()) {
long q;
int r;
q = n / 10;
r = n % 10;
if (r > 0) {
r -= 10;
q++;
}
if (n <= -10) {
printneg(q, p);
}
(*p)("0123456789"[-r]);
}
The reason is where we areIt's a world where programming environments are constantly changing, and while software doesn't seem as real as hardware, most software lives longer than the hardware on which it runs.Efforts to improve the portability of software actually extend the life of the software.
边栏推荐
- 仿牛客论坛项目
- kubernetes各名词缩写
- LeetCode
- 漏洞分析丨HEVD-0x6.UninitializedStackVariable[win7x86]
- WeChat applet cloud development | personal blog applet
- LinkedList源码分享
- Godaddy domain name resolution is slow and how to use DNSPod resolution to solve it
- MySQL 中出现的字符编码错误 Incorrect string value: ‘\x\x\x\x‘ for column ‘x‘
- sizeof的详细解说和与strlen的区别
- Go Atomic
猜你喜欢
Godaddy domain name resolution is slow and how to use DNSPod resolution to solve it
宝塔搭建PESCMS-Ticket开源客服工单系统源码实测
R语言进行相关的操作
微服务负载均衡器Ribbon
Pytorch学习记录(八):生成对抗网络GAN
MySQL Syntax Basics
STAHL触摸屏维修一体机显示屏ET-316-TX-TFT常见故障
An online JVM FullGC made it impossible to sleep all night and completely crashed~
JS Improvement: Handwritten Publish Subscriber Model (Xiaobai)
Questions I don't know in database kernel interview(1)
随机推荐
kubernetes各名词缩写
Go Atomic
tiup mirror genkey
线上一次JVM FullGC搞得整晚都没睡,彻底崩溃~
SkiaSharp 之 WPF 自绘 五环弹动球(案例版)
Pytorch框架学习记录8——最大池化的使用
Kubernetes 如何实现组件高可用
R语言 数据的关系探索
excel高级绘图技巧100讲(二十二)-如何对不规则数据进行分列
[译] 容器和 Kubernetes 中的退出码完整指南
LeetCode
Internet使用的网络协议是什么
Protocol Buffer 使用
网红驼背矫正产品真的管用吗?如何预防驼背?医生说要这样做
封装一个管理 url 状态的 hook
相亲模型与有限状态机
图的邻接矩阵存储
面试突击70:什么是粘包和半包?怎么解决?
响应式织梦模板清洁服务类网站
idea实用快捷键合集——持续更新