当前位置:网站首页>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.
边栏推荐
猜你喜欢
随机推荐
ahooks 是怎么处理 DOM 的?
Goroutine Leaks - The Forgotten Sender
2022年秋招,软件测试开发最全面试攻略,吃透16个技术栈
JS Improvement: Handwritten Publish Subscriber Model (Xiaobai)
ISC2022 HackingClub white hat summit countdown 1 day!Most comprehensive agenda formally announced!Yuan universe, wonderful!
Pytorch学习记录(八):生成对抗网络GAN
字符串
Classification interface, Taobao classification details API
那些关于DOM的常见Hook封装(二)
C陷阱与缺陷 第8章 建议与答案 8.1 建议
移植MQTT源码到STM32F407开发板上
StringTable Detailed String Pool Performance Tuning String Concatenation
测试的意义并不是能找到全部的缺陷
Hiking, cured my mental internal friction
关键字搜索:“淘宝商品 API ”
仿牛客论坛项目
win10版本1803无法升级1903系统如何解决
响应式织梦模板清洁服务类网站
附录A printf、varargs与stdarg A.1 printf函数族
封装一个管理 url 状态的 hook