19

Stack Overflow 用许多其他语言回答了这个问题,但不是 C。所以我想我会问,因为我有同样的问题。

如何在 C 中连接两个整数?

例子:

x = 11;
y = 11;

我希望 z 如下:

z = 1111;

其他示例尝试使用字符串执行此操作。什么是没有字符串的方法?

我正在寻找一种在 C 中执行此操作的有效方法,因为在我的特定用法中,这将进入代码的时间关键部分。

提前致谢!

4

10 回答 10

44
unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}

编译/正确性/速度证明

我避免使用log10andpow函数,因为我很确定它们使用浮点并且速度很慢,所以这在您的机器上可能会更快。也许。轮廓。

于 2012-10-03T00:52:46.257 回答
9
z = x * pow(10, log10(y)+1) + y;

解释:

首先你得到应该排在第二位的变量的位数:

int digits = log10(y)+1;  // will be 2 in your example

然后你通过将另一个变量乘以 10^digits 来“移动”另一个变量。

int shifted = x * pow(10, digits);   // will be 1100 in your example

最后添加第二个变量:

z = shifted + y;   // 1111

或者在一行中:

z = x * pow(10, (int)log10(y)+1) + y;
于 2012-10-03T00:58:03.800 回答
3

这可能不是一个最佳或快速的解决方案,但没有人提到它,它是一个简单的解决方案并且可能很有用。

你可以使用sprintf()和一个strtol().

char str[100];
int i=32, j=45;
sprintf(str, "%d%d", i, j);
int result=strtol(str, NULL, 10);

您首先将数字写入一个字符串,然后是另一个数字sprintf()(就像您将打印到标准输出一样printf()),然后将结果字符串转换为数字strtol()

strtol()返回的 along可能是一个大于可存储在 a 中的值int,因此您可能需要先检查结果值。

int result;
long rv=strtol(str, NULL, 10);
if(rv>INT_MAX || rv<INT_MIN || errno==ERANGE)
{
    perror("Something went wrong.");
}
else
{
    result=rv;
}

如果返回的值strtol()不在an的范围内int(即不在(包括)INT_MIN和之间INT_MAX),则发生错误。INT_MIN并且INT_MAX来自limits.h

如果字符串中的值太大而无法在 a 中表示longerrno则会因为溢出而被设置为ERANGE(from )。errno.h

strtol() 在这里阅读。

编辑:

正如chqrlie的启发性评论所指出的那样,负数会给这种方法带来麻烦。

你可以使用这个或修改这个来解决这个问题

char str[100], temp[50];
int i=-32, j=45, result;
sprintf(temp, "%+d", j);
sprintf(str, "%d%s", i, temp+1);
long rv=strtol(str, NULL, 10);

temp首先将第二个数字及其符号打印到字符数组中。

+in将%+d导致打印数字的符号。

现在打印第一个数字和第二个数字,str但没有第二个数字的符号部分。我们通过忽略 中的第一个字符来跳过第二个数字的符号部分temp

终于strtol()完成了。

于 2017-10-02T08:05:10.460 回答
2
int myPow(int x, int p)
{
     if (p == 0) return 1;
     if (p == 1) return x;

     int tmp = myPow(x, p/2);
     if (p%2 == 0) return tmp * tmp;
     else return x * tmp * tmp;
}
int power = log10(y);
z = x*myPow(10,power+1)+y;

在这里,我无耻地从https://stackoverflow.com/a/1505791/1194873复制了 myPow

于 2012-10-03T00:51:39.473 回答
2

这是@Mooing Duck 答案的变体,它使用查找表来查找 10 的倍数(对于具有慢整数乘法的平台)它还返回 unsigned long long 以允许更大的值,并在查找表中使用 unsigned long long 来解释 @ chqrlie 关于无限循环的评论。如果可以保证组合输入不超过无符号,则可以更改这些输入。

static const unsigned long long pow10s[] = {
   10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000
};
unsigned long long concat(unsigned x, unsigned y) {
    const unsigned long long *p = pow10s;
    while (y >= *p) ++p;
    return *p * x +y;        
}
于 2017-10-05T00:34:22.530 回答
2

您还可以使用宏来连接字符串(简单的方法)

#include<stdio.h>
#define change(a,b) a##b
int main()
 {
    int y;
    y=change(12,34);
    printf("%d",y);
    return 0;
 }

它有一个缺点。我们不能在这个方法中传递参数

于 2019-03-28T06:17:37.243 回答
1

这是另一种方法:

int concat(int x, int y) {
    int temp = y;
    while (y != 0) {
        x *= 10;
        y /= 10;
    }
    return x + temp;
}

谁知道你会得到什么样的表现。只是试试看..

于 2012-10-03T11:44:34.180 回答
0

也许这会起作用:

int x=11,y=11,temp=0;
int z=x;
while(y>0)
{
    // take reciprocal of y into temp
    temp=(temp*10)+(y%10);       
    y=y/10;
}
while(temp>0)
{
    // take each number from last of temp and add to last of z
    z=(z*10)+(temp%10);      
    temp=temp/10;
}

代码很长,但很简单。如果有任何错误,请纠正我。

于 2012-10-03T03:49:07.247 回答
0

改进了@Mooing Duck@none答案的变化。

只需根据需要进行十进制移位x

unsigned concatenate2(unsigned x, unsigned y) {
  unsigned y_temp = y;
  do {  // do loop to insure at least one shift
    x *= 10;
    y_temp /= 10;
  } while (y_temp > 0);
  return x + y;  
}

可以使用更广泛的数学来减少溢出可能性。@technosaurus

#include <inttypes.h>

uintmax_t concatenate2(unsigned x, unsigned y) {
  uintmax_t x_temp = x;
  unsigned y_temp = y;
  do {  // do loop to insure at least one shift
    x_temp *= 10;
    y_temp /= 10;
  } while (y_temp > 0);
  return x_temp + y;  
}
于 2021-09-27T14:39:37.360 回答
-3
#include<iostream>
using namespace std;

int main()
{
    int a=0,b=0,count=0,c=0,t=0;
    cout<<"enter 2 no"<<endl;
    cin>>a>>b;
    t=b;

    while(b!=0)
    {
        b=b/10;
        count++;
    }

    while(count!=0)
    {
        a=a*10;
        count--;
        c=a+t;
    }

    cout<<"concate no is:"<<c;
}
于 2014-09-21T13:42:35.347 回答