5

我刚刚开始从 KN King 的 C Programming: A Modern Approach (2ndEdn) 中自学 C。

我很喜欢它,但我希望在适当的时候在这里发布这个奇怪的问题以征求意见,因为不幸的是我没有导师,而且有些问题会引发更多的问题,然后他们会回答!

我正在做一个关于输入整数并以八进制显示的问题。它说有一种简单的方法可以做到这一点,但这将在本书的后面部分介绍。我想出了以下几点:

// Convert a number to octal

int n, n2, n3, n4, n5, n6;

printf("Enter a number between 0 and 32767: ");

scanf("%d", &n);

n6 = n % 8;
n5 = (n / 8) % 8;
n4 = ((n / 8) / 8) % 8;
n3 = (((n / 8) / 8) / 8) % 8;
n2 = ((((n / 8) / 8) / 8) / 8) % 8;

printf("%d%d%d%d%d", n2, n3, n4, n5, n6);

它工作正常,但我不擅长数学,想知道是否有更有效的方法来做到这一点,或者我是否以唯一可能的方式做到了......

如果其他人有这本书,那就是 Q4 p.71。

谢谢你的时间。安德鲁

PS 我确实查看了搜索引擎,但找不到任何以这种“慢”方式进行的操作!

4

9 回答 9

5

每个人都说有一种内置的方法可以做到这一点是正确的printf。但是自己做呢?

首先想到的是一个八进制数字恰好是三位。因此,您可以通过以下方式进行转换:

  • 环形while n != 0
  • 将最左边的 3 位分离nd并打印d
  • 左移n3 位

代码很简单,但我没有提供它,所以您可以自己做(您需要熟悉按位移位 运算符才能做到)。

于 2011-03-19T11:25:35.073 回答
4

简单的方法可能是使用printf()'s%o 格式说明符

scanf("%d", &n);
printf("%o", n);
于 2011-03-19T11:21:30.497 回答
3

其他人已经发布了真实的生产代码答案,现在我从您的评论中看到您还没有完成循环。也许你的书试图教你递归:

void print_oct(int n)
{
    if (n != 0) {
        print_oct(n / 8);
        printf("%d", n % 8);
    }
}

这适用于 n > 0。

于 2011-03-19T11:34:27.410 回答
1

使用循环,您可以像这样汇总五个非常相似的行:

for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
    printf("%d", n / d % 8);
printf("\n");

d将从 开始8 * 8 * 8 * 8,这是您使用的除数n2,然后逐步执行8 * 8 * 88 * 88最后1是 的除数n6,沿途打印每个数字。

一个好的编译器实际上会通过将它展开为五行来优化它,所以你会得到几乎和你开始时一样的东西。把它写成循环的好处是你不能只在其中一行中出错。

编译器还将负责将除以 8 替换为移位 3 位。两者都以二进制形式给出相同的结果,但后者更快。

于 2011-03-19T12:12:15.390 回答
1
/* Converts a positive base_10 into base_b */
int DecimalToBase(int n, int b)
{
    int rslt=0, digitPos=1;
    while (n)
    {
        rslt += (n%b)*digitPos;
        n /= b;
        digitPos *= 10;
    }
    return rslt;
}
于 2013-01-19T16:00:21.297 回答
0

由于只介绍了基础知识,因此您不希望(至少在这一点上)使用函数、循环、按位运算符、%o格式说明符和所有这些东西。这是我的基本解决方案:

int n, d1, d2, d3, d4, d5, o;

printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);

d5 = n % 8;
n /= 8;
d4 = n % 8;
n /= 8;
d3 = n % 8;
n /= 8;
d2 = n % 8;
n /= 8;
d1 = n % 8;

o = 10000 * d1 + 1000 * d2 + 100 * d3 + 10 * d4 + d5;

printf("In octal, your number is: %.5d\n", o);

请注意,由于n在输出中不需要,您可以为每一步修改(除)它(从而节省除法,这在计算上且相对昂贵)。你是安全的32767(八进制:)77777,因为32768(8*8*8*8*8 = 8^5 = (2^3)^5 = 2^15) 是第一个数字,需要六位八进制: 100000.

这个变量并不是真正需要的,而且它在16 位签名o时不起作用(在一些古老的系统上),所以从这一点开始最好只打印单独的数字。int

于 2014-05-29T12:43:34.003 回答
0

在里面使用%o格式说明符printf

printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
printf("%o", n);
于 2011-03-19T11:24:54.433 回答
0

现有的答案对我来说不够干净。这是我的:

#include <stdio.h>

#define OCTALBASE    8
#define OCTALSIZE    8

int main(int argc, char **argv) {
  int indecimal = 1337;
  char output[OCTALSIZE + 1];
  output[OCTALSIZE] = '\0';

  int outindex = OCTALSIZE;
  int outdigit = 0;
  int outvalue = indecimal;
  while (--outindex >= 0) {
    outdigit = outvalue % OCTALBASE;
    if (outvalue > 0 || outdigit > 0)
      { output[outindex] = '0' + outdigit; }
    else { output[outindex] = ' '; }
    outvalue /= OCTALBASE;
  }

  fprintf(stdout, "{ DEC: %8d, OCT: %s }\n", indecimal, output);
  fflush(stdout);

  return 0;
}

结果:

{ DEC:     1337, OCT:     2471 }
于 2014-11-21T07:18:55.870 回答
0

C语言十进制转八进制

#include<stdio.h>
#include<conio.h>
void main()
{
    A:
    long int n,n1,m=1,rem,ans=0;
    clrscr();
    printf("\nEnter Your Decimal No :: ");
    scanf("%ld",&n);

    n1=n;
    while(n>0)
    {
        rem=n%8;
        ans=(rem*m)+ans;
        n=n/8;
        m=m*10;
    }

    printf("\nYour Decimal No is :: %ld",n1);
    printf("\nConvert into Octal No is :: %ld",ans);

    printf("\n\nPress 0 to Continue...");
    if(getch()=='0')
        goto A;
    printf("\n\n\n\tThank You");
    getch();
}
于 2015-08-27T10:29:59.640 回答