#2020学习打卡##C程序设计语言# Long类型在windows和Mac(类unix)系统下的差异分析

zkbhj 发表了文章 • 0 个评论 • 515 次浏览 • 2020-04-08 11:36 • 来自相关话题

在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统




 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 //查看类型占用字节数
long a;
printf("%ld", sizeof a);果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:





 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了。

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
  查看全部
在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统

QQ截图20200408111541.jpg

 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 
//查看类型占用字节数
long a;
printf("%ld", sizeof a);
果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 
Type           ILP64   LP64   LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64
ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:

QQ截图20200408113111.jpg

 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
 

#2020学习打卡##C程序设计语言# 原码、反码和补码

zkbhj 发表了文章 • 0 个评论 • 391 次浏览 • 2020-04-07 23:27 • 来自相关话题

今天学习C程序设计语言的时候,遇到了一个概念,叫补码。其实这个概念在大学学习计算机基础的时候应该有学习过,但是还是基本上忘记的差不多了,需要重新补充回忆和学习一下。
 一. 机器数和真值

在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

1、机器数

一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

那么,这里的 00000011 和 10000011 就是机器数。

2、真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
 
二. 原码, 反码, 补码的基础概念和计算方法

在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式. 
1. 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]



[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

反码的表示方法是:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

补码的表示方法是:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
 
三. 为何要使用原码, 反码和补码

在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.

现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

[+1] = [00000001]原 = [00000001]反 = [00000001]补

所以不需要过多解释. 但是对于负数:

[-1] = [10000001]原 = [11111110]反 = [11111111]补

可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?

首先, 因为人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

为了解决原码做减法的问题, 出现了反码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].


因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.
 
数学概念和求证:
https://blog.csdn.net/zl10086111/article/details/80907428
  查看全部
今天学习C程序设计语言的时候,遇到了一个概念,叫补码。其实这个概念在大学学习计算机基础的时候应该有学习过,但是还是基本上忘记的差不多了,需要重新补充回忆和学习一下。
 一. 机器数和真值

在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

1、机器数

一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

那么,这里的 00000011 和 10000011 就是机器数。

2、真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
 
二. 原码, 反码, 补码的基础概念和计算方法

在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式. 
1. 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]



[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

反码的表示方法是:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

补码的表示方法是:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
 
三. 为何要使用原码, 反码和补码

在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.

现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

[+1] = [00000001]原 = [00000001]反 = [00000001]补

所以不需要过多解释. 但是对于负数:

[-1] = [10000001]原 = [11111110]反 = [11111111]补

可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?

首先, 因为人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

为了解决原码做减法的问题, 出现了反码:

计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)


使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].



因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.
 
数学概念和求证:
https://blog.csdn.net/zl10086111/article/details/80907428
 

#2020学习打卡##C程序设计语言# 怎么解决gcc编译后windows shell输出中文乱码问题?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 1689 次浏览 • 2020-04-07 22:29 • 来自相关话题

#2020学习打卡##C程序设计语言# 二进制、八进制、十进制、十六进制关系及其转换

zkbhj 发表了文章 • 0 个评论 • 631 次浏览 • 2020-04-07 13:55 • 来自相关话题

首先,我们先看下“进制”的定义:

进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tally mark计数)。 对于任何一种进制---X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。

这么多进制中,我们最熟悉的是“十进制”,由于人类解剖学的特点,双手共有十根手指,故在人类自发采用的进位制中,十进制是使用最为普遍的一种。成语“屈指可数”某种意义上来说描述了一个简单计数的场景,而原始人类在需要计数的时候,首先想到的就是利用天然的算筹——手指来进行计数。
 
接下来,一一讲解各个进制:
 
一、二进制:是计算机唯一使用的进制。
 
二进制是计算机唯一使用的进制,因为计算机的根本是电路,电路只能表示两种情况,一种情况为没有电,可以表示数字0,一种情况为有电,可以表示数字1,再无第三种情况,所以很自然的,只有两个数字符号(0,1)的进制,就是二进制。二进制的基数是2,它的最大数码也是基数减1,就是1,最小数码是0。如果需要用二进制来表示一个数,只能是不断的01001001001111011等(想学代码的都知道摩尔定律以及集成电路,晶体管等等,一个集成电路板上面有几十亿个晶体管,所以你不用担心二进制表示数制会有限制,它可以是很大,超出你的想象),不可能出现第三个数字符号。如果出现了,就绝对不是二进制表示。
 
二、八进制、十六进制:主要作用就是将数值的识别和表达简单化。 
八进制在编程语言范围内没有固定的使用情形,它的基数是8,总共有8个数字符号(0,1,2,3,4,5,6,7),八进制的最大数码是基数减1,就是7,最小数码是0,如果你要确切表示一个数是八进制的,可以这么表示(12565)O或者是(12565)Q,在C和C++中八进制的表示是额外在数值前面加一个0,比如123是十进制,而0123就是八进制。

十六进制在编程语言范围内也没有固定的使用情形(计算机网络中最新的IPv6地址使用的就是十六进制,计算机系统的注册表也会用到),它的基数是16,总共有16个数字符号(0,1,2,3,4,5,6,7,8,9,A[表示10],B[表示11],C[表示12],D[表示13],E[表示14],F[表示15]),因为0-9不够用,所以就借了6个字母,字母不区分大小写,对比前面几种进制,只要一个数的表示中出现了字母,就一定是16进制。十六进制的最大数码也是基数减1,就是15(F),最小数码也是0,如果你需要确切表示一个数是十六进制的,可以这么表示(56BBA)H,在C和C++中,十六进制的表示是额外在数值前面加一个0x,比如123是十进制,0x123是十六进制。

互相转换
 
1.1 十进制转二进制
 
十进制整数转二进制

十进制整数转换成二进制采用“除2倒取余”,十进制小数转换成二进制小数采用“乘2取整,顺序排列”。

例题: 135D = ______ B

**解析:**如下图所示,将135除以2,得余数,直到不能整除,然后再将余数从下至上倒取。得到结果:1000 0111B.





 
十进制小数转二进制

十进制小数转换成二进制小数采用 “乘2取整,顺序排列” 法。

具体做法是:

用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数 部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,或者达到所要求的精度为止。

然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。

例题: 0.68D = ______ B(精确到小数点后5位)

**解析:**如下图所示,0.68乘以2,取整,然后再将小数乘以2,取整,直到达到题目要求精度。得到结果:0.10101B.





 
1.2 十进制转八进制
 
思路和十进制转二进制一样,参考如下例题:

例题: 10.68D = ______ Q(精确到小数点后3位)

**解析:**如下图所示,整数部分除以8取余数,直到无法整除。小数部分0.68乘以8,取整,然后再将小数乘以8,取整,直到达到题目要求精度。得到结果:12.534Q.





 
1.3 十进制转十六进制

思路和十进制转二进制一样,参考如下例题:

例题: 25.68D = ______ H(精确到小数点后3位)

**解析:**如下图所示,整数部分除以16取余数,直到无法整除。小数部分0.68乘以16,取整,然后再将小数乘以16,取整,直到达到题目要求精度。得到结果:19.ae1H.





 
2.1 二进制转十进制
 
 **方法为:**把二进制数按权展开、相加即得十进制数。(具体用法如下图)





 
2.2 八进制转十进制

八进制转十进制的方法和二进制转十进制一样。

例题: 26Q = ______ D

**解析:**如下图所示。得到结果:22D.





 
2.3 十六进制转十进制

例题: 23daH = ______ D

**解析:**如下图所示。得到结果:9178D.





 
 
参考文档:
https://baike.baidu.com/item/%E8%BF%9B%E5%88%B6/317457
https://blog.csdn.net/ruidianbaihuo/article/details/87797979
https://blog.csdn.net/yuanxiang01/article/details/82503568
  查看全部
首先,我们先看下“进制”的定义:


进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tally mark计数)。 对于任何一种进制---X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。


这么多进制中,我们最熟悉的是“十进制”,由于人类解剖学的特点,双手共有十根手指,故在人类自发采用的进位制中,十进制是使用最为普遍的一种。成语“屈指可数”某种意义上来说描述了一个简单计数的场景,而原始人类在需要计数的时候,首先想到的就是利用天然的算筹——手指来进行计数。
 
接下来,一一讲解各个进制:
 
一、二进制:是计算机唯一使用的进制。
 
二进制是计算机唯一使用的进制,因为计算机的根本是电路,电路只能表示两种情况,一种情况为没有电,可以表示数字0,一种情况为有电,可以表示数字1,再无第三种情况,所以很自然的,只有两个数字符号(0,1)的进制,就是二进制。二进制的基数是2,它的最大数码也是基数减1,就是1,最小数码是0。如果需要用二进制来表示一个数,只能是不断的01001001001111011等(想学代码的都知道摩尔定律以及集成电路,晶体管等等,一个集成电路板上面有几十亿个晶体管,所以你不用担心二进制表示数制会有限制,它可以是很大,超出你的想象),不可能出现第三个数字符号。如果出现了,就绝对不是二进制表示。
 
二、八进制、十六进制:主要作用就是将数值的识别和表达简单化。 
八进制在编程语言范围内没有固定的使用情形,它的基数是8,总共有8个数字符号(0,1,2,3,4,5,6,7),八进制的最大数码是基数减1,就是7,最小数码是0,如果你要确切表示一个数是八进制的,可以这么表示(12565)O或者是(12565)Q,在C和C++中八进制的表示是额外在数值前面加一个0,比如123是十进制,而0123就是八进制。

十六进制在编程语言范围内也没有固定的使用情形(计算机网络中最新的IPv6地址使用的就是十六进制,计算机系统的注册表也会用到),它的基数是16,总共有16个数字符号(0,1,2,3,4,5,6,7,8,9,A[表示10],B[表示11],C[表示12],D[表示13],E[表示14],F[表示15]),因为0-9不够用,所以就借了6个字母,字母不区分大小写,对比前面几种进制,只要一个数的表示中出现了字母,就一定是16进制。十六进制的最大数码也是基数减1,就是15(F),最小数码也是0,如果你需要确切表示一个数是十六进制的,可以这么表示(56BBA)H,在C和C++中,十六进制的表示是额外在数值前面加一个0x,比如123是十进制,0x123是十六进制。

互相转换
 
1.1 十进制转二进制
 
十进制整数转二进制

十进制整数转换成二进制采用“除2倒取余”,十进制小数转换成二进制小数采用“乘2取整,顺序排列”。

例题: 135D = ______ B

**解析:**如下图所示,将135除以2,得余数,直到不能整除,然后再将余数从下至上倒取。得到结果:1000 0111B.

QQ截图20200407134759.jpg

 
十进制小数转二进制

十进制小数转换成二进制小数采用 “乘2取整,顺序排列” 法。

具体做法是:

用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数 部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,或者达到所要求的精度为止。

然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。

例题: 0.68D = ______ B(精确到小数点后5位)

**解析:**如下图所示,0.68乘以2,取整,然后再将小数乘以2,取整,直到达到题目要求精度。得到结果:0.10101B.

QQ截图20200407134847.jpg

 
1.2 十进制转八进制
 
思路和十进制转二进制一样,参考如下例题:

例题: 10.68D = ______ Q(精确到小数点后3位)

**解析:**如下图所示,整数部分除以8取余数,直到无法整除。小数部分0.68乘以8,取整,然后再将小数乘以8,取整,直到达到题目要求精度。得到结果:12.534Q.

QQ截图20200407134954.jpg

 
1.3 十进制转十六进制

思路和十进制转二进制一样,参考如下例题:

例题: 25.68D = ______ H(精确到小数点后3位)

**解析:**如下图所示,整数部分除以16取余数,直到无法整除。小数部分0.68乘以16,取整,然后再将小数乘以16,取整,直到达到题目要求精度。得到结果:19.ae1H.

QQ截图20200407135038.jpg

 
2.1 二进制转十进制
 
 **方法为:**把二进制数按权展开、相加即得十进制数。(具体用法如下图)

QQ截图20200407135215.jpg

 
2.2 八进制转十进制

八进制转十进制的方法和二进制转十进制一样。

例题: 26Q = ______ D

**解析:**如下图所示。得到结果:22D.

QQ截图20200407135300.jpg

 
2.3 十六进制转十进制

例题: 23daH = ______ D

**解析:**如下图所示。得到结果:9178D.

QQ截图20200407135328.jpg

 
 
参考文档:
https://baike.baidu.com/item/%E8%BF%9B%E5%88%B6/317457
https://blog.csdn.net/ruidianbaihuo/article/details/87797979
https://blog.csdn.net/yuanxiang01/article/details/82503568
 

#2020学习打卡##C程序设计语言# 怎么理解对于内部名而言,至少前31个字符是有效的这段话?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 1011 次浏览 • 2020-04-07 11:01 • 来自相关话题

#2020学习打卡##C程序设计语言# ASCII是啥?

zkbhj 发表了文章 • 0 个评论 • 522 次浏览 • 2020-04-06 20:14 • 来自相关话题

ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符 。

 




  查看全部


ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符 。


 
e850352ac65c103880a07b53bc119313b17e8941.png

 

#2020学习打卡##C程序设计语言# 什么是ANSI C语言?

zkbhj 发表了文章 • 0 个评论 • 442 次浏览 • 2020-04-06 00:15 • 来自相关话题

在学习C语言的过程中,我注意到教程中多次提到了ANSI C,这个名词。这个名词在2011年大学学习C语言时从未提及过,那么这个名词代表的含义是什么呢?在网上查询之后,有了一个相对规范的认识。
 
什么是ANSI?
 
首先,它是一个多含义词。学习计算机编程的程序员们都不会对它陌生,其中一个广为大家熟识的是,ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。 
除此之外,它还有一个意思:美国国家标准学会,American National Standards Institute的英文首字母简称。ANSI的标准是自愿采用的。美国认为,强制性标准可能限制生产率的提高。但被法律引用和政府部门制订的标准,一般属强制性标准。
 
什么是ANSI C?
 

ANSI C是美国国家标准协会(ANSI)对C语言发布的标准。使用C的软件开发者被鼓励遵循ANSI C文档的要求,因为它鼓励使用跨平台的代码。

 




C 的第一个标准是由ANSI发布的。虽然这份文档后来被国际标准化组织(ISO)采纳并且ISO发布的修订版也被ANSI采纳了,但名称ANSI C(而不是 ISO C)仍被广泛使用。一些软件开发者使用ISO C,还有一些使用 Standard C。
 
C标准经历了C89、C90、C99、C11四次迭代升级,目前最新的标准是C11。在2011年12月,ANSI采纳了ISO/IEC 9899:2011标准。这个标准通常即C11,它是C程序语言的现行标准。 
所以,遵循C语言标准,那么编写跨平台的代码就容易多了。具备跨平台的代码需要如下两个条件满足:
 
代码中没有依赖针对具体硬件的代码;编译器要支持C标准;

这样在A硬件平台上写的代码,无需或者只需做极小的改动,经过编译器的编译,就可以移植到B硬件平台上了。 
学习一门语言,了解规范很重要! 查看全部
在学习C语言的过程中,我注意到教程中多次提到了ANSI C,这个名词。这个名词在2011年大学学习C语言时从未提及过,那么这个名词代表的含义是什么呢?在网上查询之后,有了一个相对规范的认识。
 
什么是ANSI?
 
首先,它是一个多含义词。学习计算机编程的程序员们都不会对它陌生,其中一个广为大家熟识的是,ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。 
除此之外,它还有一个意思:美国国家标准学会,American National Standards Institute的英文首字母简称。ANSI的标准是自愿采用的。美国认为,强制性标准可能限制生产率的提高。但被法律引用和政府部门制订的标准,一般属强制性标准。
 
什么是ANSI C?
 


ANSI C是美国国家标准协会(ANSI)对C语言发布的标准。使用C的软件开发者被鼓励遵循ANSI C文档的要求,因为它鼓励使用跨平台的代码。


 
0e2442a7d933c895cbf4689cda1373f08302004a.jpg

C 的第一个标准是由ANSI发布的。虽然这份文档后来被国际标准化组织(ISO)采纳并且ISO发布的修订版也被ANSI采纳了,但名称ANSI C(而不是 ISO C)仍被广泛使用。一些软件开发者使用ISO C,还有一些使用 Standard C。
 
C标准经历了C89、C90、C99、C11四次迭代升级,目前最新的标准是C11。在2011年12月,ANSI采纳了ISO/IEC 9899:2011标准。这个标准通常即C11,它是C程序语言的现行标准。 
所以,遵循C语言标准,那么编写跨平台的代码就容易多了。具备跨平台的代码需要如下两个条件满足:
 
  1. 代码中没有依赖针对具体硬件的代码;
  2. 编译器要支持C标准;


这样在A硬件平台上写的代码,无需或者只需做极小的改动,经过编译器的编译,就可以移植到B硬件平台上了。 
学习一门语言,了解规范很重要!

#2020学习打卡##C程序设计语言# C语言IDE的选择推荐(Mac篇)

zkbhj 发表了文章 • 0 个评论 • 1050 次浏览 • 2020-04-03 11:09 • 来自相关话题

上一篇文章介绍了Windows环境下的C语言IDE选择,这篇文章介绍下Mac环境下,哪些IDE是相对比较优秀的!
 
Mac电脑作为类Unix类操作系统的代表,C语言也是天生具备的。很多Mac电脑即便不用于软件开发,也会因为各种免费开源软件的使用,在依赖包中自动安装了gcc的支持,从而具备了C语言的开发环境。 
在Mac电脑上进行C语言开发有两种方式,一是使用图形界面(GUI)进行开发,这种情况使用苹果自主开发的Xcode开发工具。二是使用纯命令行的开发工具gcc或者clang配合vim编辑器。前者适合大规模项目的开发,后者简洁高效,相对来说适合开发小规模的程序或者应急的修修补补。
 
(1)Xcode
 
Xcode 是苹果公司开发的编程软件,是开发人员建立OS X 和 iOS 应用程序的最快捷的方式。Xcode 具有统一的用户界面设计,编码、测试、调试都在一个简单的窗口内完成。在windows上类似这种能编c语言的还有微软出的visual studio。





 
安装Xcode唯一合法的方法是在Mac电脑打开App Store程序,在右上角搜索框中输入"Xcode",从搜索到的结果中一般前1、2位就是Xcode,然后点选“获取”或者“安装”。Xcode容量比较大,一般安装包都在4.5G-6G之间,依据网络的情况,需要等待不短的时间。安装完成后,第一次运行Xcode会提示安装命令行工具,按照提示就会自动安装clang命令行开发工具。命令行开发包一般是100多M,下载安装都会比较快。
 
(2)Visual Studio Code
 
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。该编辑器支持多种语言和文件格式的编写,截止2019年9月,已经支持了如下37种语言或文件:F#、HandleBars、Markdown、Python、Java、PHP、Haxe、Ruby、Sass、Rust、PowerShell、Groovy、R、Makefile、HTML、JSON、TypeScript、Batch、Visual Basic、Swift、Less、SQL、XML、Lua、Go、C++、Ini、Razor、Clojure、C#、Objective-C、CSS、JavaScript、Perl、Coffee Script、Dockerfile。





 
下载地址:https://code.visualstudio.com/Download
 
(3)命令行下进行程序开发
 
这种方式适用于学习阶段,大型项目还是更倾向于使用IDE。
 
Mac的命令行C语言开发工具主要有两种,clang及gcc,前者是苹果官方推荐的,Xcode也使用Clang进行编译。后者则是GNU开源社区推荐的,并且被大多数linux支持。两者在语法的兼容性上几乎没有差别。而Clang在于错误信息、编译速度等方面有很多优势。
 
通常的命令行操作为:
vi 1.c
gcc 1.c //生成a.out可执行文件
gcc -o my.out 1.c//可以指定生成的可执行文件名
./a.out
./my.out

  查看全部
上一篇文章介绍了Windows环境下的C语言IDE选择,这篇文章介绍下Mac环境下,哪些IDE是相对比较优秀的!
 
Mac电脑作为类Unix类操作系统的代表,C语言也是天生具备的。很多Mac电脑即便不用于软件开发,也会因为各种免费开源软件的使用,在依赖包中自动安装了gcc的支持,从而具备了C语言的开发环境。 
在Mac电脑上进行C语言开发有两种方式,一是使用图形界面(GUI)进行开发,这种情况使用苹果自主开发的Xcode开发工具。二是使用纯命令行的开发工具gcc或者clang配合vim编辑器。前者适合大规模项目的开发,后者简洁高效,相对来说适合开发小规模的程序或者应急的修修补补。
 
(1)Xcode
 
Xcode 是苹果公司开发的编程软件,是开发人员建立OS X 和 iOS 应用程序的最快捷的方式。Xcode 具有统一的用户界面设计,编码、测试、调试都在一个简单的窗口内完成。在windows上类似这种能编c语言的还有微软出的visual studio。

QQ截图20200403104902.jpg

 
安装Xcode唯一合法的方法是在Mac电脑打开App Store程序,在右上角搜索框中输入"Xcode",从搜索到的结果中一般前1、2位就是Xcode,然后点选“获取”或者“安装”。Xcode容量比较大,一般安装包都在4.5G-6G之间,依据网络的情况,需要等待不短的时间。安装完成后,第一次运行Xcode会提示安装命令行工具,按照提示就会自动安装clang命令行开发工具。命令行开发包一般是100多M,下载安装都会比较快。
 
(2)Visual Studio Code
 
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。该编辑器支持多种语言和文件格式的编写,截止2019年9月,已经支持了如下37种语言或文件:F#、HandleBars、Markdown、Python、Java、PHP、Haxe、Ruby、Sass、Rust、PowerShell、Groovy、R、Makefile、HTML、JSON、TypeScript、Batch、Visual Basic、Swift、Less、SQL、XML、Lua、Go、C++、Ini、Razor、Clojure、C#、Objective-C、CSS、JavaScript、Perl、Coffee Script、Dockerfile。

QQ截图20200403105149.jpg

 
下载地址:https://code.visualstudio.com/Download
 
(3)命令行下进行程序开发
 
这种方式适用于学习阶段,大型项目还是更倾向于使用IDE。
 
Mac的命令行C语言开发工具主要有两种,clang及gcc,前者是苹果官方推荐的,Xcode也使用Clang进行编译。后者则是GNU开源社区推荐的,并且被大多数linux支持。两者在语法的兼容性上几乎没有差别。而Clang在于错误信息、编译速度等方面有很多优势。
 
通常的命令行操作为:
vi 1.c
gcc 1.c //生成a.out可执行文件
gcc -o my.out 1.c//可以指定生成的可执行文件名
./a.out
./my.out

 

#2020学习打卡##C程序设计语言# C语言IDE的选择推荐(Windows篇)

zkbhj 发表了文章 • 0 个评论 • 781 次浏览 • 2020-04-03 10:41 • 来自相关话题

确定好了学习目标,选择好了学习教程,制定好了学习计划,那么接下来,你需要做的就是搭建一套学习C语言的环境。我们无外乎基本上大多使用的操作系统是Windows和MACOS,所以在这里整理了一些IDE和C语言编译环境搭建的方法和经验供大家参考。这篇为Windows篇,下一篇文章分享MAC上有哪些优良实践。(文末为大家附上了各个IDE的下载地址)
 
IDE的选择
 
IDE,又称集成开发环境,顾名思义,他是一个编辑器 + 编译器的集合。所以对于接触一门新语言的“门外汉”来讲,最方便快捷的方式,就是选择一个IDE来完成这项工作。那么我们可以选择哪个IDE作为学习C语言以及以后开发C语言程序的最佳工具呢?Windows 下的C语言 IDE 众多,多如牛毛,初学者往往不知道该如何选择。我们可以综合自己的实际情况,根据这些IDE的特点来进行对自己最合适的选择。 
(1)Visual Studio
 Windows 下首先推荐大家使用微软开发的 Visual Studio(简称 VS),它是 Windows 下的标准 IDE,实际开发中大家也都在使用。为了适应最新的 Windows 操作系统,微软每隔一段时间(一般是一两年)就会对 VS 进行升级。VS 的不同版本以发布年份命名,例如 VS2010 是微软于 2010 年发布的,VS2019 是微软于 2019 年发布的。





 
当然,这款IDE也有MAC版本,且它是windows官方推出的IDE环境,功能方面自不用说,非常之强大。但是有一个缺点就是看起来相对“臃肿”,可能有很多初学者用不上的工具也会在其中提供,安装包略大,约2~3GB大小,安装时间预计半个小时左右。

优点:功能强大,微软官方维护的IDE,更新及时,操作简单方便;
缺点:略臃肿,安装包大,安装时间长,占用系统资源较多;
选择:如果你的机器性能还可以的话,建议选择该IDE。

 
(2)Visual Studio Code
 
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。该编辑器支持多种语言和文件格式的编写,截止2019年9月,已经支持了如下37种语言或文件:F#、HandleBars、Markdown、Python、Java、PHP、Haxe、Ruby、Sass、Rust、PowerShell、Groovy、R、Makefile、HTML、JSON、TypeScript、Batch、Visual Basic、Swift、Less、SQL、XML、Lua、Go、C++、Ini、Razor、Clojure、C#、Objective-C、CSS、JavaScript、Perl、Coffee Script、Dockerfile。
 
相对于 Visual Studio,这款IDE更轻便,支持的语言也更丰富。

优点:跨平台、官方支持、多语言支持、界面美观、操作方便、容易上手
缺点:暂未发现
建议:首选推荐安装

 
(3)Dev C++
 
如果比较讨厌“VS”的复杂性,那么Dev C++是一个不错的选择。Dev C++ 是一款免费开源的 C/C++ IDE,内嵌 GCC 编译器(Linux GCC 编译器的 Windows 移植版),是 NOI、NOIP 等比赛的指定工具。Dev C++ 的优点是体积小(只有几十兆)、安装卸载方便、学习成本低,缺点是调试功能弱。

NOI 是National Olympiad in Informatics的缩写,译为“全国青少年信息学奥林匹克竞赛”;NOIP 是National Olympiad in informatics in Provinces的缩写,译为“全国青少年信息学奥林匹克联赛”。NOI、NOIP 都是奥林匹克竞赛的一种,参加者多为高中生,获奖者将被保送到名牌大学或者得到高考加分资格。


优点:轻巧、方便,对机器性能要求不高,安装卸载方便,学习成本低
缺点:调试功能相对较弱
选择:如果机器性能较弱,建议选择这个IDE

 
(4)Visual C++ 6.0
 
哈哈,之所以把这个IDE放在这里强调下,纯属想要怀念一下,因为大学期间学C语言就是用的这款IDE呀呀呀呀!!!不知道你还记不记得下面这些界面~










 
唉呀妈呀,仿佛还记得炎炎夏日在大学机房用那种方方正正的大脑袋电脑敲代码的日子……
Visual C++ 6.0(简称VC 6.0)是微软开发的一款经典的 IDE,很多高校都以 VC 6.0 为教学工具来讲解C和C++。但VC 6.0是1998年的产品,很古老了,在 Win7、Win8、Win10 下会有各种各样的兼容性问题,甚至根本不能运行,所以不推荐使用。

优点:可以用来回忆
缺点:太多不知从何说起
建议:强烈不建议,如果你想安装,我也拦不住

 
(5)其它 IDE
 
除了上面提到的三款 IDE,Windows 平台下还有很多其他的 IDE,它们各有特点,例如:
Code::Blocks 是一款开源、跨平台、免费的 C/C++ IDE,它和 Dev C++ 非常类似,小巧灵活,易于安装和卸载,不过它的界面要比 Dev C++ 复杂一些,不如 Dev C++ 来得清爽。Turbo C 是一款古老的、DOS 年代的C语言开发工具,程序员只能使用键盘来操作 Turbo C,不能使用鼠标,所以非常不方便。但是 Turbo C 集成了一套图形库,可以在控制台程序中画图,看起来非常炫酷,所以至今仍然有人在使用。C-Free 是一款国产的 Windows 下的C/C++ IDE,最新版本是 5.0,整个软件才 14M,非常轻巧,安装也简单,界面也比 Dev C++ 漂亮。C-Free 的缺点也是调试功能弱。可惜的是,C-Free 已经多年不更新了,组件都老了,只能在 XP、Win7 下运行,在 Win8、Win10 下可能会存在兼容性问题。
 
所以,综合对比之下,如果电脑性能不错,就是用VS,否则,选择Dev C++。
 
赶紧去下载体验吧~~~
 
纯命令行下通过指令操作
 
没有IDE,不代表就不能写代码了!当然你还有“更程序员”的方式,通过命令行执行进行操作。下面介绍windows10下如何使用cmd命令进行GCC编译的几个步骤:
 
首先了解下什么是GCC?

GCC是以GPL许可证所发行的自由软件,也是GNU计划的关键部分。GCC的初衷是为GNU操作系统专门编写一款编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,甚至在微软的Windows上也可以使用GCC。GCC支持多种计算机体系结构芯片,如x86、ARM、MIPS等,并已被移植到其他多种硬件平台。
GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。

 1、安装gcc编译器,需要到MinGW 的主页 www.mingw.org,进入 MinGW 下载页面,下载最新版本的 MinGW64 安装程序。或者到:https://sourceforge.net/projects/mingw-w64/files/   ,下载 Download mingw-get-setup.exe (86.5 kB)。不过这个国外网站下载速度超慢,建议进入国内网站下载离线包:https://www.jb51.net/softs/696088.html 

2、运行 Download mingw-get-setup.exe ,点击"运行",continue等,注意记住安装的目录,我的是 F:\MinGw,下面修改环境变量时还会用到。






3、安装好后,需要设置编译器的路径环境变量

选择计算机—属性---高级系统设置---环境变量,在系统变量中找到 Path 变量,在后面加入 min-gw的安装目录,我的是 F:\MinGw\bin






 
 
4、在开始菜单中,点击"运行",输入 cmd,打开命令行:输入 mingw-get,如果弹出 MinGw installation manager 窗口,说明安装正常。此时,关闭 MinGw installation manager 窗口,否则接下来的步骤会报错;
 
5、在cmd中输入命令 mingw-get install gcc,等待一会,gcc 就安装成功了。
 
以上是常规的方式,但是不翻墙可能难以进行下去,所以直接下载离线包,然后把解压后的路径设置到环境变量中即可。





 
这个时候,打开cmd,输入gcc -v 即可查看是否安装成功。





 
然后你就可以在命令行里进行编译和执行c程序啦~
#include <stdio.h>

void main()
{
printf("hello, world! My name is zhengkai!\n");
} gcc 1.c
a.exe




 
 
附件:
VS最新版下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
VSC最新版下载地址:https://code.visualstudio.com/Download 
Dev C++下载地址:https://bloodshed-dev-c.en.softonic.com/ 查看全部
确定好了学习目标,选择好了学习教程,制定好了学习计划,那么接下来,你需要做的就是搭建一套学习C语言的环境。我们无外乎基本上大多使用的操作系统是Windows和MACOS,所以在这里整理了一些IDE和C语言编译环境搭建的方法和经验供大家参考。这篇为Windows篇,下一篇文章分享MAC上有哪些优良实践。(文末为大家附上了各个IDE的下载地址)
 
IDE的选择
 
IDE,又称集成开发环境,顾名思义,他是一个编辑器 + 编译器的集合。所以对于接触一门新语言的“门外汉”来讲,最方便快捷的方式,就是选择一个IDE来完成这项工作。那么我们可以选择哪个IDE作为学习C语言以及以后开发C语言程序的最佳工具呢?Windows 下的C语言 IDE 众多,多如牛毛,初学者往往不知道该如何选择。我们可以综合自己的实际情况,根据这些IDE的特点来进行对自己最合适的选择。 
(1)Visual Studio
 Windows 下首先推荐大家使用微软开发的 Visual Studio(简称 VS),它是 Windows 下的标准 IDE,实际开发中大家也都在使用。为了适应最新的 Windows 操作系统,微软每隔一段时间(一般是一两年)就会对 VS 进行升级。VS 的不同版本以发布年份命名,例如 VS2010 是微软于 2010 年发布的,VS2019 是微软于 2019 年发布的。

QQ截图20200403102513.jpg

 
当然,这款IDE也有MAC版本,且它是windows官方推出的IDE环境,功能方面自不用说,非常之强大。但是有一个缺点就是看起来相对“臃肿”,可能有很多初学者用不上的工具也会在其中提供,安装包略大,约2~3GB大小,安装时间预计半个小时左右。


优点:功能强大,微软官方维护的IDE,更新及时,操作简单方便;
缺点:略臃肿,安装包大,安装时间长,占用系统资源较多;
选择:如果你的机器性能还可以的话,建议选择该IDE。


 
(2)Visual Studio Code
 
Microsoft在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。该编辑器支持多种语言和文件格式的编写,截止2019年9月,已经支持了如下37种语言或文件:F#、HandleBars、Markdown、Python、Java、PHP、Haxe、Ruby、Sass、Rust、PowerShell、Groovy、R、Makefile、HTML、JSON、TypeScript、Batch、Visual Basic、Swift、Less、SQL、XML、Lua、Go、C++、Ini、Razor、Clojure、C#、Objective-C、CSS、JavaScript、Perl、Coffee Script、Dockerfile。
 
相对于 Visual Studio,这款IDE更轻便,支持的语言也更丰富。


优点:跨平台、官方支持、多语言支持、界面美观、操作方便、容易上手
缺点:暂未发现
建议:首选推荐安装


 
(3)Dev C++
 
如果比较讨厌“VS”的复杂性,那么Dev C++是一个不错的选择。Dev C++ 是一款免费开源的 C/C++ IDE,内嵌 GCC 编译器(Linux GCC 编译器的 Windows 移植版),是 NOI、NOIP 等比赛的指定工具。Dev C++ 的优点是体积小(只有几十兆)、安装卸载方便、学习成本低,缺点是调试功能弱。


NOI 是National Olympiad in Informatics的缩写,译为“全国青少年信息学奥林匹克竞赛”;NOIP 是National Olympiad in informatics in Provinces的缩写,译为“全国青少年信息学奥林匹克联赛”。NOI、NOIP 都是奥林匹克竞赛的一种,参加者多为高中生,获奖者将被保送到名牌大学或者得到高考加分资格。



优点:轻巧、方便,对机器性能要求不高,安装卸载方便,学习成本低
缺点:调试功能相对较弱
选择:如果机器性能较弱,建议选择这个IDE


 
(4)Visual C++ 6.0
 
哈哈,之所以把这个IDE放在这里强调下,纯属想要怀念一下,因为大学期间学C语言就是用的这款IDE呀呀呀呀!!!不知道你还记不记得下面这些界面~

QQ截图20200403103514.jpg


timg.gif

 
唉呀妈呀,仿佛还记得炎炎夏日在大学机房用那种方方正正的大脑袋电脑敲代码的日子……
Visual C++ 6.0(简称VC 6.0)是微软开发的一款经典的 IDE,很多高校都以 VC 6.0 为教学工具来讲解C和C++。但VC 6.0是1998年的产品,很古老了,在 Win7、Win8、Win10 下会有各种各样的兼容性问题,甚至根本不能运行,所以不推荐使用。


优点:可以用来回忆
缺点:太多不知从何说起
建议:强烈不建议,如果你想安装,我也拦不住


 
(5)其它 IDE
 
除了上面提到的三款 IDE,Windows 平台下还有很多其他的 IDE,它们各有特点,例如:
  1. Code::Blocks 是一款开源、跨平台、免费的 C/C++ IDE,它和 Dev C++ 非常类似,小巧灵活,易于安装和卸载,不过它的界面要比 Dev C++ 复杂一些,不如 Dev C++ 来得清爽。
  2. Turbo C 是一款古老的、DOS 年代的C语言开发工具,程序员只能使用键盘来操作 Turbo C,不能使用鼠标,所以非常不方便。但是 Turbo C 集成了一套图形库,可以在控制台程序中画图,看起来非常炫酷,所以至今仍然有人在使用。
  3. C-Free 是一款国产的 Windows 下的C/C++ IDE,最新版本是 5.0,整个软件才 14M,非常轻巧,安装也简单,界面也比 Dev C++ 漂亮。C-Free 的缺点也是调试功能弱。可惜的是,C-Free 已经多年不更新了,组件都老了,只能在 XP、Win7 下运行,在 Win8、Win10 下可能会存在兼容性问题。

 
所以,综合对比之下,如果电脑性能不错,就是用VS,否则,选择Dev C++。
 
赶紧去下载体验吧~~~
 
纯命令行下通过指令操作
 
没有IDE,不代表就不能写代码了!当然你还有“更程序员”的方式,通过命令行执行进行操作。下面介绍windows10下如何使用cmd命令进行GCC编译的几个步骤:
 
首先了解下什么是GCC?


GCC是以GPL许可证所发行的自由软件,也是GNU计划的关键部分。GCC的初衷是为GNU操作系统专门编写一款编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,甚至在微软的Windows上也可以使用GCC。GCC支持多种计算机体系结构芯片,如x86、ARM、MIPS等,并已被移植到其他多种硬件平台。
GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。


 1、安装gcc编译器,需要到MinGW 的主页 www.mingw.org,进入 MinGW 下载页面,下载最新版本的 MinGW64 安装程序。或者到:https://sourceforge.net/projects/mingw-w64/files/   ,下载 Download mingw-get-setup.exe (86.5 kB)。不过这个国外网站下载速度超慢,建议进入国内网站下载离线包:https://www.jb51.net/softs/696088.html 

2、运行 Download mingw-get-setup.exe ,点击"运行",continue等,注意记住安装的目录,我的是 F:\MinGw,下面修改环境变量时还会用到。

QQ截图20200403113153.jpg


3、安装好后,需要设置编译器的路径环境变量


选择计算机—属性---高级系统设置---环境变量,在系统变量中找到 Path 变量,在后面加入 min-gw的安装目录,我的是 F:\MinGw\bin



QQ截图20200403121319.jpg

 
 
4、在开始菜单中,点击"运行",输入 cmd,打开命令行:输入 mingw-get,如果弹出 MinGw installation manager 窗口,说明安装正常。此时,关闭 MinGw installation manager 窗口,否则接下来的步骤会报错;
 
5、在cmd中输入命令 mingw-get install gcc,等待一会,gcc 就安装成功了。
 
以上是常规的方式,但是不翻墙可能难以进行下去,所以直接下载离线包,然后把解压后的路径设置到环境变量中即可。

QQ截图20200403121018.jpg

 
这个时候,打开cmd,输入gcc -v 即可查看是否安装成功。

QQ截图20200403121453.jpg

 
然后你就可以在命令行里进行编译和执行c程序啦~
#include <stdio.h>

void main()
{
printf("hello, world! My name is zhengkai!\n");
}
 
gcc 1.c
a.exe

QQ截图20200403122249.jpg

 
 
附件:
VS最新版下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
VSC最新版下载地址:https://code.visualstudio.com/Download 
Dev C++下载地址:https://bloodshed-dev-c.en.softonic.com/