我是一名中级Python程序员,但我正在努力学习C.到目前为止,这是一次非常令人沮丧的经历。
为什么这个简单的代码...
#include <stdio.h>
#include <string.h>
char name[15] = "George Lopez"; /* string representing your name */
char birthday[6] = "01-30-92"; /* string representing your bday */
int phone_number; /* declair int representing phone number */
int main() {
phone_number = 2222223333; /* int representing your phone number */
printf("You said your name was: %s\n", name);
printf("And your birthday is %s?\n", birthday);
printf("And, so I can call you, your number is %d\n", phone_number);
return(0); /* exit program normally */
}
当电话号码为2222223333:
时产生此输出You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is -2072743963
当电话号码为9992223333时输出
error: 4_1_myinfo.c:16:3: warning: overflow in implicit constant conversion [-Woverflow]
phonenumber = 9992223333;
当电话号码为1112223333时输出:
You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is 1112223333
我怀疑这与C处理整数的方式有关。也许,C中的int的最大长度小于python中的int,这导致了wanky输出?
答案 0 :(得分:3)
这里有几个主要问题。
首先,在使用C字符串时,如果可以,请避免定义缓冲区的大小,如下所示:
char name[] = "George Lopez"; /* string representing your name */
char birthday[] = "01-30-92"; /* string representing your bday */
如果您必须预先定义最大字符串长度,请使用公共限制,如下所示:
#define MAX_STR_LEN 256
char name[MAX_STR_LEN] = "George Lopez"; /* string representing your name */
char birthday[MAX_STR_LEN] = "01-30-92"; /* string representing your bday */
如果您以后不打算修改它们,请按以下方式const
进行修改:
const char* name = "George Lopez"; /* string representing your name */
const char* birthday = "01-30-92"; /* string representing your bday */
在您的情况下,您定义了一个只能容纳6个字符的字符数组,但尝试在其中填充9个字符&#34; 01-30-92&#34;,加上包含尾随的\0
字符自动。大错。
第二个主要问题是您试图将整数文字放入无法容纳它的数据类型中。在C中,最大带符号32位值2,147,483,647
在INT_MAX
中定义为<limits.h>
。您应该像这样编写代码:
long long int phone_number = 2222222222L;
注意尾随的数字文字后缀L
?为了创建一个可以实际存储值本身的变量,必须允许编译代码并使用long long int
。
最后,您应该考虑使用字符串来保存电话号码。你没有对它进行任何代数/数学操作,因此不需要使用整数数据类型来表示它。
代码清单(已修改)
#include <stdio.h>
#include <string.h>
char name[] = "George Lopez"; /* string representing your name */
char birthday[] = "01-30-92"; /* string representing your bday */
long long int phone_number; /* declair int representing phone number */
int main() {
phone_number = 2222223333L; /* int representing your phone number */
printf("You said your name was: %s\n", name);
printf("And your birthday is %s?\n", birthday);
printf("And, so I can call you, your number is %lld\n", phone_number);
return(0); /* exit program normally */
}
示例输出
You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is 2222223333
答案 1 :(得分:1)
我认为处理电话号码的更好方法是将它们视为一个字符串。您需要一个字符串类型来“格式化”您的输出,并在考虑用户输入时验证电话号码是否遵循某个“正则表达式”。
答案 2 :(得分:0)
在C中,所有数据类型都具有固定大小。通常,int
是32位值(但不一定是这样),因此它的最大值为2,147,483,647。
您的值9,992,223,333超过此值,这就是您收到警告的原因。您需要使用更大的数据类型,如64位数。如果您在Windows上,这通常是long long
,如果您在Linux上,则通常是long
。
答案 3 :(得分:0)
要了解为什么会发生这种情况,您需要了解数字在内存中的表示方式。我将尝试让您一瞥他们的基本工作方式以及一些您感兴趣的进一步参考。由于计算机只能理解0和1,因此基数2是显而易见的选择。但是代表负数存在问题。有一些表示,比如符号幅度表示(基本上,有一个代表符号的位 - 如果设置,数字是负数),这非常简单。问题是这种表示有两种表示0的方式:+ 0和-0。因此,使用了一种称为二进制补码的聪明表示。对于二进制数abcd(其中a,b,c,d表示其位),基数10值是a * 2 ^ 3 + b * 2 ^ 2 + c * 2 ^ 1 + d * 2 ^ 0。如果该数字是2的补码4比特表示,则其基数10值将是-a * 2 ^ 3 + b * 2 ^ 2 + c * 2 ^ 1 + d * 2 ^ 0。因此,在两个补码中,第一位具有负权重。在4位二进制补码表示中,如果你有0111(十进制7)并且你试图加1,你将得到1000,即-8。这称为溢出。只有在添加具有相同符号的数字并获得不同符号的结果时才会出现溢出(添加2个正数会产生负数或添加2个负数会产生正数)。
在你的程序中,会发生类似的事情。唯一的区别是int有32位,而不是4位。
进一步参考: http://en.wikipedia.org/wiki/Binary_number http://en.wikipedia.org/wiki/Signed_number_representations
答案 4 :(得分:0)
带符号的32位整数的范围是[-2147483648,2147483647]。您尝试将您的电话号码表示为有符号整数。
a. When phone num is 1112223333, it's less than the max 2147483647, so you get theright output.
b. 2222223333 is greater than the max 2147483647, but can still be represented as a 32-bit number, you get the 2's complement number which is -2072743963
c. 9992223333 cannot be represented by a 32-bit number, i.e. it's even bigger than (2^32 - 1), that's why you such error.