C语言,char类型转为short、int类型转为char类型,计算机存储:#include <stdio.h>int main(){ char c = ‘\xFE‘; in

#include <stdio.h>
int main()
{   
    short c = '\xFE';
    int a = 0xFE;
    char b = 389;
    printf("%d  %d", c, b);
}

        要弄明白上面这段代码,首先要知道:在计算机的数据存储中,不管是正数还是负数都是以补码的形式储存的。

计算机中的数据存储

        要弄明白补码是怎么来的,就要知道原码反码。

原码

        原码形式很简单,就是将给的这个数展开为2进制,然后根据他的数据类型在不足的位置补0。

        其中 int 类型是占4个字节32位,short类型站2个字节 16位,char类型占1个字节8位。

        例如下表:

变量定义(正数)2进制展开
int a = 70000 0000 0000 0000 0000 0000 0000 01111
char a = 70000 0111
short a = 70000 0000 0000 0111
变量定义(负数)2进制展开
int a = -71000 0000 0000 0000 0000 0000 0000 0111
char a = -71000 0111
short a = -71000 0000 0000 0111

        其中,2进制展开的最左边一位(最高位)也就是符号位,正数最高位为0,负数最高位为1。

反码

       正数的反码是原码本身,负数的反码是除去最高位符号位,其它位0 变 1,1 变 0。

变量反码形式
int a = 70000 0000 0000 0000 0000 0000 0000 0111
short a = -71111 1111 1111 1000
char a = -71111 1000
补码

        正数的补码是原码本身,负数的补码是在它本身反码的基础上+1。

变量补码形式
int a = 70000 0000 0000 0000 0000 0000 0000 0111
short a = -71111 1111 1111 1001
char a = -71111 1001

结论 

          总结为以下:

        正数的补码就是本身自己的原码。负数的补码=自己原码取反+1=反码+1

题目讲解

        现在知道了数据在计算机中都是以补码的形式存在的。

        #include <stdio.h>

#include <stdio.h>
int main()
{   
    short c = '\xFE';
    int a = 0xFE;
    char b = 389;
    printf("%d  %d", c, b);
}
           short c='\xFE';  

          题目之中 short c = '\xFE','\xFE'是什么?注意,它外面有单引号,就像'a'、'B'一样,'\xFE'整体是一个字符(char类型),而'\xFE'这种表示是一种16进制输入,用前缀:\x来表示16进制不同于0x,前者表示16进制整体必须带' '双单引号,0x则不用。

        FE的展开是1111 1110,上面提到了char类型的长度是一个字节(8位),则它的最高位为1,表示这个数被char类型接入的时候是一个负数,负数在计算机中的储存方式上面提到了,现在要做的就是将其表示为补码形式,1111 1110>1000 0001(反码)>1000 0010(补码),而它最终就表示为了看到的运行框中的-2。

        上面说了'\xFE'首次被计算机接收并处理为了-2,也就是8位1000 0010(因为char类型只有8位),接受它的参数是short c,shot是2个字节,16位,当把char类型表示给short类型的参数时,之后输出结果中仍然是-2,因为接受的参数为16位,大于后面的char类型,所以计算机这时候在处理的时候,只会在不足16位的地方补0,即0000 0000 1000 0010。这个值就是'\xFE'最终在计算机中的表示方式。

        char b=389;

        首先,在不考虑前方接受参数类型的情况下,389的二进制展开形式是1 1000 0101,这个时候,因为它的长度是9位,而char类型是8位,所以最高位的1会被“吞掉”,只剩下1000 0101,由于最高位是1,负数,它的补码表示形式是1111 1100,不看最高位符号位,它所表示的数是123,最终计算机存储的所表示出来就是-123。

        int a=0xFE;

        这钟情况下,后面的0xFE就相当于一个数,就比如平常见到的int a=5之类的,由于有符号int类型的范围是2^(-31)~2^31-1;只要这个输入的数不超过这个范围,输出的数就不会发生变化,若大于这个范围,还是和上述一样,“吞掉”多余位+补码表示。

最终运行结果在devc++。希望对大家有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <linux/socket.h> //#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <errno.h> void handle_tcp_client(int connfd); /* struct sockaddr_in { sa_family_t sin_family; // 指定协议族 u_int16_t sin_port; //端口号 struct in_addr sin_addr; //ip地址 char sin_zero[8]; //填充8个字节,为了和其他协议族地址结构体大小一样。 }; struct in_addr { in_addr_t s_addr; }; typedef u_int32_t in_addr_t; */ int create_socket(short port, char *ipstr) { int ret; //1. 创建一个套接字 int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { perror("socket error"); return -1; } // 2. 指定本机的ip地址: ip + port struct sockaddr_in local; local.sin_family = AF_INET; //指定协议族 local.sin_port = htons(port); //指定端口号 local.sin_addr.s_addr = inet_addr(ipstr); //指定ip地址 ret = bind(sock, (struct sockaddr *)&local, sizeof(local)); if (ret == -1) { perror("bind error"); goto err_return; } //3. 进入监听模式: ret = listen(sock, 10); if (ret == -1) { perror("listen error"); goto err_return; } return sock; //返回一个创建的(已经准备好)的监听套接字 err_return: close(sock); return -1; } // tcp_server port ip_str int main(int argc, char *argv[]) { int sock; sock = create_socket( atoi(argv[1]), argv[2]); if (sock == -1) { printf("failed to create_socket\n"); return -1; } while (1) { struct sockaddr_in client; socklen_t len = sizeof(client); int connfd = accept(sock, (struct sockaddr*)&client, &len); if (connfd == -1) { perror("accept error:"); continue; } // 打印一下新连接的客户端的地址信息 //printf("%s port %d new connection established\n", // inet_ntoa(client.sin_addr), ntohs(client.sin_port) ); pid_t pid = fork(); if (pid == 0) { handle_tcp_client(connfd); exit(0); } else if (pid > 0) { close(connfd); } else { close(connfd); perror("fork error"); continue; } } }
07-15
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值