在C中将字符串存储在整数变量中

时间:2018-07-02 06:22:41

标签: c

#include <stdio.h>
int main()
{
    int a = "Hi";
    char b = 'F';

    int c = a + b;

    printf("%d",a);        /* (1) */
    printf("%d",c);        /* (2) */ 
}

指令(1)的输出为何为18537? 如何按照ANSI标准存储值

说明(2)很清楚,因为我们基本上在18537上加了70,即为18607

可以用字符串来详细说明如何将值存储在整数变量中吗?

3 个答案:

答案 0 :(得分:6)

编译器警告!

$ cc -Wall -Wextra e.c 
e.c: In function ‘main’:
e.c:4:13: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
     int a = "Hi";
             ^~~~

您将字符串文字的内存地址分配给变量a。好吧,在许多情况下,您都可以这样做。但是,这不能保证并且存在潜在的问题。例如,int可能不足以容纳整个地址。

可能值得指出的是,这不是有效的C代码,因此请不要这样做。根据{{​​3}}(感谢@Lundin提供链接):

  

应满足以下条件之一:112)

     
      
  • 左操作数具有原子,合格或不合格的算术类型,而右操作数具有算术类型;
  •   
  • 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;
  •   
  • 左操作数具有原子,合格或不合格的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),两个操作数都是指向兼容类型的合格或不合格版本的指针,并且由左侧具有右侧所指类型的所有限定词;
  •   
  • 左操作数具有原子,合格或不合格的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的void,并且左侧指向的类型具有右侧指向的类型的所有限定符;
  •   
  • 左操作数是原子,限定或不限定的指针,右是空指针常量;或
  •   
  • 左操作数的类型为atomic,qualified或unqualified _Bool,而右侧是指针。
  •   

有关如何强制编译器不接受无效代码的信息,请参见https://port70.net/~nsz/c/c11/n1570.html#6.5.16.1p1

答案 1 :(得分:5)

int a = "Hi";不是有效的C代码,并且推测在非标准编译器上可能会执行的操作不是很有意义。

该代码违反了简单分配规则6.5.16.1的约束。没有强制转换,您不能将char*隐式地分配给int

(如果您想阻止无效的C代码在gcc编译器上进行编译,请使用-std=c11 -pedantic-errors。)

答案 2 :(得分:1)

发生的事很奇怪:

int a = "Hi" // you allocate 4 bytes and put in the chars ('H' [0x48], 'i'[0x69], '\0' [0x0], 1_byte_of_rubbish) so is OK
//a = 0x 00 00 48 69

请注意,第一位被解释为int上的“信号”。 还请记住,内存中的值应为0X [rubbish] 004869

char b= 'F' //you allocate 1 byte and give value F [0x46] (unsigned)
// b=0x46
printf("%d",a) // print what is inside variable a (as SIGNED integer)
 int c = a + b // you add a (signed) and b (unsigned) and put result in c (signed) -> 0x[00]004869 + 46 = 0x000048AF 
//c=0x000048AF

printf("%d",c) // you print the content of c interpreted as signed int

请注意,大多数编译器会将变量初始化为0,因此您会得到00 [004869],如果编译器不这样做,则会由于无法初始化int的第一个字节而导致无法预测的结果

还请记住字节序->首先使用LSB读取intel(小字节序)计算机上的int,因此打印%d将为您提供错误的值(在您的情况下,[48] [69] [00] [00] = 26952读为小尾数法

编辑: 我的建议是始终“十六进制”调试这些情况,以便您可以确切地看到每个字节中的内容,有时(涉及排序的时候)分贝数很少。