用指针实现求出其最高位数
时间: 2024-06-18 16:06:04 浏览: 84
用指针实现求出其最高位数可以通过以下步骤实现:
1. 定义一个指向整数的指针,指向要求最高位数的整数。
2. 通过循环,将指针指向的整数不断地除以10,直到整数小于10为止。
3. 循环结束后,指针指向的整数就是原始整数的最高位数。
以下是示例代码:
```
int get_highest_digit(int* num_ptr) {
while (*num_ptr >= 10) {
*num_ptr /= 10;
}
return *num_ptr;
}
```
相关问题
问题抽还 设计一个程序实现两个任意长的整数求和运算。 基本要求 利用双向循环链表实现长整数的存储,每个结点含一个整型变量。任何整型变量的范围是 -(21*-1)~(21*-1)。 输入和输出形式:每4位- -组, 组间用逗号隔开。 测试数据 (1)0和0,应输出“0”。 (2) -2345,6789,-7654,3211, 应输出“-10000,0000”。 (3) 9999.9999,,000000000, 应输出9999,000,0001”。 录 (4) 1,001,000,-1,001,0001, 应输出“0”。 (5) 1,00,0001, -1 ,00,0000,应输出“1”。 实现提示 (1)每个结点中可以存放的最大整数为219-1=32767,这样才能保证两数相加不会溢出。但若按 32 768进制数存放,在+进制数与32768进制数之间的转换十分不方便,故可以在每个结点中仅存放十 进制数的4位,即不超过9 999的非负整数,整个链表视为万进制数。 (2)可以利用头结点数据域的符号代表长整数的符号。用其绝对值表示元素结点数目。相加过程 中不要破坏两个操作数链表。两操作数的头指针存于指针数组中是简化程序结构的一一种方法。 不能给 长整数位数规定上限。
以下是一个基于双向循环链表实现长整数求和的示例程序。程序的实现思路如下:
1. 定义一个双向循环链表结构体,每个节点存储4位十进制数,头结点的符号位表示长整数的符号,链表长度存储在头结点的绝对值中。
2. 读入两个长整数,并将它们存储到两个双向循环链表中。
3. 将两个链表从低位到高位逐位相加,将结果存储到一个新的链表中。
4. 对于新链表中每个节点的值,如果大于等于10000,则需要向高位进位,并将当前节点的值减去10000;如果小于0,则需要向高位借位,并将当前节点的值加上10000。
5. 最后输出新链表表示的长整数。
```C++
#include <iostream>
#include <string>
using namespace std;
const int BASE = 10000; // 每个节点存储的数值的最大值
const int DIGITS = 4; // 每个节点存储的数值的位数
// 定义双向循环链表节点结构体
struct ListNode {
int val; // 当前节点存储的数值
ListNode* prev; // 前驱指针
ListNode* next; // 后继指针
ListNode(int x = 0) : val(x), prev(nullptr), next(nullptr) {}
};
// 定义双向循环链表结构体
struct LinkedList {
ListNode* head; // 头结点
LinkedList() : head(new ListNode()) { head->prev = head->next = head; }
~LinkedList() { // 销毁链表
ListNode* cur = head->next;
while (cur != head) {
ListNode* next = cur->next;
delete cur;
cur = next;
}
delete head;
}
void insert(int x) { // 在链表末尾插入一个节点
ListNode* node = new ListNode(x);
node->prev = head->prev;
node->next = head;
head->prev->next = node;
head->prev = node;
++(head->val); // 链表长度加1
}
void print() { // 输出链表表示的长整数
if (head->val == 0) { // 长整数为0
cout << "0" << endl;
return;
}
if (head->val < 0) { // 长整数为负数
cout << "-";
}
ListNode* cur = head->prev;
while (cur != head) {
cout.width(DIGITS);
cout.fill('0');
cout << abs(cur->val);
cur = cur->prev;
if (cur != head) {
cout << ",";
}
}
cout << endl;
}
};
// 将一个字符串转换为长整数的双向循环链表表示
LinkedList stringToList(const string& s) {
LinkedList list;
int sign = 1;
int start = 0;
if (s[0] == '-') { // 字符串表示的长整数为负数
sign = -1;
start = 1;
}
int num = 0;
int len = 0;
for (int i = s.length() - 1; i >= start; --i) {
num += (s[i] - '0') * pow(10, len++);
if (len == DIGITS || i == start) { // 每4位一组,转换为一个节点存储
list.insert(sign * num);
num = 0;
len = 0;
}
}
return list;
}
// 两个双向循环链表相加
LinkedList add(const LinkedList& a, const LinkedList& b) {
LinkedList sum;
ListNode* curA = a.head->next;
ListNode* curB = b.head->next;
int carry = 0; // 进位
while (curA != a.head || curB != b.head) {
int valA = curA != a.head ? curA->val : 0;
int valB = curB != b.head ? curB->val : 0;
int val = valA + valB + carry;
sum.insert(val % BASE);
carry = val / BASE;
if (curA != a.head) {
curA = curA->next;
}
if (curB != b.head) {
curB = curB->next;
}
}
if (carry != 0) { // 如果最高位有进位
sum.insert(carry);
}
return sum;
}
// 对链表表示的长整数求相反数
LinkedList negate(const LinkedList& list) {
LinkedList neg;
neg.head->val = -list.head->val;
ListNode* cur = list.head->next;
while (cur != list.head) {
neg.insert(-cur->val);
cur = cur->next;
}
return neg;
}
// 比较两个链表表示的长整数的大小(绝对值)
int compare(const LinkedList& a, const LinkedList& b) {
if (a.head->val != b.head->val) {
return a.head->val > b.head->val ? 1 : -1;
}
ListNode* curA = a.head->prev;
ListNode* curB = b.head->prev;
while (curA != a.head && curB != b.head) {
if (curA->val != curB->val) {
return curA->val > curB->val ? 1 : -1;
}
curA = curA->prev;
curB = curB->prev;
}
return 0;
}
// 计算两个链表表示的长整数的差(假设a>=b)
LinkedList subtract(const LinkedList& a, const LinkedList& b) {
LinkedList diff;
ListNode* curA = a.head->next;
ListNode* curB = b.head->next;
int borrow = 0; // 借位
while (curA != a.head || curB != b.head) {
int valA = curA != a.head ? curA->val : 0;
int valB = curB != b.head ? curB->val : 0;
int val = valA - valB - borrow;
if (val < 0) {
borrow = 1;
val += BASE;
}
else {
borrow = 0;
}
diff.insert(val);
if (curA != a.head) {
curA = curA->next;
}
if (curB != b.head) {
curB = curB->next;
}
}
while (diff.head->prev != diff.head && diff.head->prev->val == 0) { // 去掉高位的0
ListNode* node = diff.head->prev;
node->prev->next = diff.head;
diff.head->prev = node->prev;
delete node;
--(diff.head->val);
}
return diff;
}
int main() {
string s1, s2;
cin >> s1 >> s2;
LinkedList a = stringToList(s1);
LinkedList b = stringToList(s2);
LinkedList sum;
if (a.head->val >= 0 && b.head->val >= 0) { // 两个长整数都为非负数
sum = add(a, b);
}
else if (a.head->val < 0 && b.head->val < 0) { // 两个长整数都为负数
sum = add(negate(a), negate(b));
sum.head->val = -sum.head->val;
}
else { // 两个长整数符号不同
if (compare(a, b) >= 0) { // |a| >= |b|
sum = subtract(a, b);
}
else {
sum = subtract(b, a);
sum.head->val = -sum.head->val;
}
}
sum.print();
return 0;
}
```
汇编语言实现按键申请外部中断,中断一次,数码管显示的数加1,用2位数码管动态显示计数,计数到12归0
好的,下面是用汇编语言实现的按键计数器程序,使用外部中断来实现按键功能,使用定时器0中断来实现数码管显示。代码注释中有详细说明。
```assembly
; 定义数码管的I/O口
DIO equ P1.0
CLK equ P1.1
; 定义计数器、按键标志、计时器计数值
data segment
counter db 0 ; 计数器
key_pressed db 0 ; 按键标志
timer dw 0 ; 计时器计数值
data ends
; 定义中断向量
org 0
ljmp start
; 定义定时器0中断处理函数
org 0bh
timer0_isr:
push acc ; 保存寄存器
push dph
push dpl
mov dpl, #0 ; 重新设置计时器初值
mov dph, #0
djnz timer, skip ; 倒计时未完成,跳过
mov timer, #500 ; 重新设置计时器计数值
inc counter ; 计数器加1
cjne counter, #13, skip2 ; 如果计数器不等于13,则跳过
mov counter, #0 ; 计数器清零
skip2:
mov a, counter ; 显示计数器的个位数
mov dpl, a
call display
mov a, counter / 10 ; 显示计数器的十位数
mov dpl, a
call display
skip:
clr TF0 ; 清除定时器0中断标志
pop dpl ; 恢复寄存器
pop dph
pop acc
reti ; 退出中断处理函数
; 定义外部中断0处理函数
org 003h
key_isr:
push acc ; 保存寄存器
push dph
push dpl
mov key_pressed, #1 ; 设置按键标志
pop dpl ; 恢复寄存器
pop dph
pop acc
reti ; 退出中断处理函数
; 显示数字子程序
display:
push psw ; 保存寄存器
push acc
push dph
push dpl
mov dph, #table / 0x100 ; 计算表格地址
mov dpl, a
add a, a ; 计算在表格中的偏移量
add a, dph
mov a, @a+dptr ; 读出对应数字的码值
mov dph, #0 ; 开始显示
mov r2, #8 ; 显示8位
clr C ; 清除进位标志
loop:
movx a, @dptr ; 读出下一位数码管的数据
rlc a ; 取出最高位
jnc skip1 ; 如果最高位为0,跳过
setb DIO ; 如果最高位为1,设置DIO为1
skip1:
setb CLK ; CLK上升沿
clr CLK ; CLK下降沿
djnz r2, loop ; 循环8次
pop dpl ; 恢复寄存器
pop dph
pop acc
pop psw
ret
; 程序入口
start:
mov sp, #0ffh ; 初始化堆栈指针
mov dptr, #timer ; 设置计时器初值
movx a, @dptr
mov dptr, #TH0 ; 设置定时器初值
mov @dptr, a
mov dptr, #TL0
mov @dptr, #0
mov tmod, #1 ; 设置定时器0为模式1
setb et0 ; 允许定时器0中断
setb ea ; 允许中断
setb tr0 ; 启动定时器0
setb EX0 ; 允许外部中断0
setb IT0 ; 设置外部中断0为下降沿触发
loop:
jnb key_pressed, loop ; 如果按键标志为0,一直循环
mov key_pressed, #0 ; 清除按键标志
mov timer, #500 ; 重新设置计时器计数值
sjmp loop ; 跳转回循环
; 数码管显示数字表
table:
db 0c0h, 0f9h, 0a4h, 0b0h, 099h, 092h, 082h, 0f8h, 080h, 090h
```
这个程序使用了外部中断0来实现按键功能,使用定时器0中断来实现数码管显示。在外部中断处理函数中,设置按键标志。在定时器0中断处理函数中,先检测计时器是否为0,如果为0,则计数器加1,然后重新设置计时器计数值。如果计数器到达13,则清零计数器,并且显示器显示00。显示函数也在中断处理函数中调用,显示计数器的值。程序的入口处启动定时器0和外部中断0,并且允许定时器0中断、外部中断0和全局中断。循环中检测按键标志,如果为1,则重新设置计时器计数值,并且清除按键标志,否则一直循环。
阅读全文