程序员C语言快速上手——基础篇(二) 迷南。 2022-01-27 01:49 285阅读 0赞 ### 文章目录 ### * * GCC 编译命令初探 * 数据类型 * * 修饰数值类型 * 基本数据类型的打印 * 获取数据类型的长度 * 变量与常量 * * 变量 * 常量 * 欢迎关注我的公众号:编程之路从0到1 **本专栏已发布配套视频内容,请查看公众号视频专辑《程序员的C》** ## GCC 编译命令初探 ## 编写测试代码 `hello.c` #include <stdio.h> int main(void){ printf("hello world!\n"); } 在代码目录下打开cmd命令行或打开VSCode中的命令行,VS Code快捷键是【Ctrl】+【~】 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9hcmN0aWNmb3guYmxvZy5jc2RuLm5ldA_size_16_color_FFFFFF_t_70] 输入编译命令进行编译 gcc hello.c 然后输入`dir`查看,可以看到生成了个叫`a.exe`的可执行文件,在命令行输入`a`即可运行它,看到打印了`hello world!` 以上就是最简单的`gcc`编译命令,它每次都会默认生成一个`a.exe`程序,如果我们想指定生成的程序名字,只需要加上一个参数`-o`指定即可,`o`表示`out`,用于指定生成的程序名,如下 gcc hello.c -o hello 这次再查看,生成的就是`hello.exe`,输入`hello`即可运行它。 有时候我们写的程序有语法错误,我们希望编译的时候编译器能给出详细的提示信息,这时候就可以加上另一个参数`-Wall`,让编译器在编译器时输出更多更详细的的信息,建议每次编译都加上这个参数,这样有什么错误也好查 gcc hello.c -Wall -o hello 以上就是我们本篇学习的编译命令,总结一下就是两个参数 * `-o` 指定生成的文件名 * `-Wall` 让编译器工作时输出更多详细信息 到这里肯定有人要说了,每次都手敲这些命令好麻烦,直接使用`VS Code`中的`run`编译不就好了?如果直接使用`VS Code`去`run`那就脱离了我们学习GCC以及GNU工具链的本意了,对我们去理解C语言没有任何好处,初学时,多多手敲这些命令,熟悉他们,对我们来说是有很大好处的,否则你根本不知道编译器C程序时,IDE到底干了些什么事。 ## 数据类型 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lpbmdzaHVrdW4_size_16_color_FFFFFF_t_70_pic_center] 对于通常表示数值的类型,重点是关注它的范围大小,因为C语言数据类型的大小是不完全固定的,在不同的硬件平台,会有区别,尤其是一些嵌入式设备。下面给出一个通常情况下的表示范围 <table> <thead> <tr> <th>类型</th> <th>字节</th> <th>二进制位</th> <th>表示范围</th> </tr> </thead> <tbody> <tr> <td>char</td> <td>1</td> <td>8</td> <td><span><span><span> − 2 7 -2^7 </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span>7</span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> ( 2 7 − 1 ) (2^7 -1) </span><span><span><span style="height: 1.06411em; vertical-align: -0.25em;"></span><span>(</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span>7</span></span></span></span></span></span></span></span><span style="margin-right: 0.222222em;"></span><span>−</span><span style="margin-right: 0.222222em;"></span></span><span><span style="height: 1em; vertical-align: -0.25em;"></span><span>1</span><span>)</span></span></span></span></span></td> </tr> <tr> <td>short</td> <td>2</td> <td>16</td> <td><span><span><span> − 2 15 -2^{15} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>1</span><span>5</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> ( 2 15 − 1 ) (2^{15} -1) </span><span><span><span style="height: 1.06411em; vertical-align: -0.25em;"></span><span>(</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>1</span><span>5</span></span></span></span></span></span></span></span></span><span style="margin-right: 0.222222em;"></span><span>−</span><span style="margin-right: 0.222222em;"></span></span><span><span style="height: 1em; vertical-align: -0.25em;"></span><span>1</span><span>)</span></span></span></span></span></td> </tr> <tr> <td>int</td> <td>4</td> <td>32</td> <td><span><span><span> − 2 31 -2^{31} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>1</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> ( 2 31 − 1 ) (2^{31} -1) </span><span><span><span style="height: 1.06411em; vertical-align: -0.25em;"></span><span>(</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>1</span></span></span></span></span></span></span></span></span><span style="margin-right: 0.222222em;"></span><span>−</span><span style="margin-right: 0.222222em;"></span></span><span><span style="height: 1em; vertical-align: -0.25em;"></span><span>1</span><span>)</span></span></span></span></span></td> </tr> <tr> <td>long</td> <td>4 /8</td> <td>32 /64</td> <td><span><span><span> − 2 31 -2^{31} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>1</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> ( 2 31 − 1 ) (2^{31} -1) </span><span><span><span style="height: 1.06411em; vertical-align: -0.25em;"></span><span>(</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>1</span></span></span></span></span></span></span></span></span><span style="margin-right: 0.222222em;"></span><span>−</span><span style="margin-right: 0.222222em;"></span></span><span><span style="height: 1em; vertical-align: -0.25em;"></span><span>1</span><span>)</span></span></span></span></span>或<span><span><span> − 2 63 -2^{63} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>6</span><span>3</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> ( 2 63 − 1 ) (2^{63} -1) </span><span><span><span style="height: 1.06411em; vertical-align: -0.25em;"></span><span>(</span><span><span>2</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>6</span><span>3</span></span></span></span></span></span></span></span></span><span style="margin-right: 0.222222em;"></span><span>−</span><span style="margin-right: 0.222222em;"></span></span><span><span style="height: 1em; vertical-align: -0.25em;"></span><span>1</span><span>)</span></span></span></span></span></td> </tr> <tr> <td>float</td> <td>4</td> <td>32</td> <td><span><span><span> − 1 0 38 -10^{38} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span>1</span><span><span>0</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>8</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> 1 0 38 10^{38} </span><span><span><span style="height: 0.814108em; vertical-align: 0em;"></span><span>1</span><span><span>0</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>8</span></span></span></span></span></span></span></span></span></span></span></span></span></td> </tr> <tr> <td>double</td> <td>8</td> <td>64</td> <td><span><span><span> − 1 0 308 -10^{308} </span><span><span><span style="height: 0.897438em; vertical-align: -0.08333em;"></span><span>−</span><span>1</span><span><span>0</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>0</span><span>8</span></span></span></span></span></span></span></span></span></span></span></span></span> ~ <span><span><span> 1 0 308 10^{308} </span><span><span><span style="height: 0.814108em; vertical-align: 0em;"></span><span>1</span><span><span>0</span><span><span><span><span style="height: 0.814108em;"><span style="top: -3.063em; margin-right: 0.05em;"><span style="height: 2.7em;"></span><span><span><span>3</span><span>0</span><span>8</span></span></span></span></span></span></span></span></span></span></span></span></span></td> </tr> </tbody> </table> 以上就是标准C中的基础数据类型,要记住,C中没有`long long`类型,很多人将C语言与C++语言搞混,切记! 以上表中,`long`类型有两种情况,使用32位编译器编译,则`long`为4字节,占32位,如果使用64位编译器,则`long`为8字节,占64位二进制。当然这个也不是绝对的,仍然与系统环境有关。 补充说明: 在C99新标准中,对C语言进行了扩展,其中提供了几种新的类型 1. 新增复数类型(`_Complex`)和虚数类型(`_Imaginary`) 2. 新增布尔类型(`_Bool`) 3. 新增整数类型`long long int`,该类型用于表示64位整数,共8字节,请注意与C++中的`long long`区分 **在C99 版本以前,C语言中是没有这些类型的,然而,在以前C99并不是一个被广泛支持的C语言版本,例如微软旗下最新的VC编译器就不完全兼容C99,这些阻碍导致C99没有被重视和完全普及,使得C语言新特性被割裂。** 在今天,C99标准已经被大部分编译器支持,例如gcc和clang,在不考虑极端兼容情况下,使用新特性语法并不会造成什么副作用,最后提一句,我们使用的GCC编译器是支持C99标准的,它不仅支持C99,它还支持C11标准。 ### 修饰数值类型 ### 除了直接使用这些类型,通常还会使用一个关键字`unsigned`来修饰,它表达的意思是无符号,例如: unsigned int len = 10; 我们以前讲过,计算机中,最高位是符号位,例如32位,只有31位是有效位,因为最高位要用来表示符号,为0表示正数,1则表示负数。这样一来能用于表示的实际范围就变小了,有时候我们根本不需要使用负数,这时候就可以使用`unsigned`关键字来提升表示的范围,例如用`unsigned`修饰`int`后,就能将32位都有效的用于表示范围,则变量`len`能表示的范围变成了0 ~ ( 2 32 − 1 ) 2^\{32\}-1) 232−1),如果不加关键字`unsigned`,则默认被`signed`修饰,即`int len = 10;` 等价于`signed int len = 10;`,通常我们当然是用简洁写法,什么都不写啦。 ### 基本数据类型的打印 ### 在第一个示例中,我们已经使用`printf`函数打印了`hello world`,这里print是打印的意思,那么`f`是什么意思呢?其实这里的`f`是缩写,是`format`的意思,代表格式化打印。既然是格式化打印,那一定会有格式占位符了,例如我要打印`“”He is 18 years old"`这句话,显然18是一个变量,他今年18,明年就是19,所以在这句话中需要把一个变量拼进去,这个时候就可以使用占位符,占位符的作用就是先把位置占着,到合适的时候在替换,这就像拿个水杯到图书馆占座一样。根据输入输出的变量的类型不同,占位符也不同,这里介绍最常用的几个 * `%d` 有符号十进制整数 * `%f` 浮点数 * `%s` 字符串 * `%c` 单个字符 * `%x` 十六进制整数 #include<stdio.h> int main(void){ printf("He is %d years old",18); printf("He is %s years old","18"); } ### 获取数据类型的长度 ### 前面已经说过,在不同的硬键平台上,不同的编译器下,这些类型的实际长度可能都有出入,那么如何才能确切的指定当前某个数据类型的实际长度到底是多少呢?答案就是使用`sizeof`运算符 #include<stdio.h> int main(void){ printf("char size = %d\n",sizeof(char)); printf("short size = %d\n",sizeof(short)); printf("int size = %d\n",sizeof(int)); printf("long size = %d\n",sizeof(long)); printf("float size = %d\n",sizeof(float)); printf("double size = %d\n",sizeof(double)); } 输出: char size = 1 short size = 2 int size = 4 long size = 4 float size = 4 double size = 8 可以看到,`long`类型仍然是4字节,然而在我的Mac OS电脑上测试,64位GCC编译出来的`long`输出的是8字节,在其他类Unix操作系统上一致,可见Windows系统上的C存在很多奇怪的特殊现象。所以再次建议尽量使用类Unix系统学习C语言,如Mac OS、Ubuntu系统等。 ## 变量与常量 ## ### 变量 ### 在C语言中,**变量必须先声明后使用**,没有先声明的变量无法访问 #include<stdio.h> int main(void){ /* 声明变量 */ int width; int height; float price; // 初始化变量 width = 100; height = 200; /* 对于浮点数,其字面量应带后缀f 这不是必须的,但应具备这样的编码规范 */ price = 15.6f; } 注意,声明变量后没有初始化就使用,会造成一些不可预知的结果,因为未初始化的变量可能会具有一些随机值,而且这不是良好的C语言编程习惯,应当被批判。声明的变量没有预初始化为零值,这是C语言的一个缺陷!推荐的良好的编程范式,是在**声明的同时对变量进行零值初始化**。 int main(void){ /* 声明的同时进行零值初始化 不同类型的变量,其零值不同 */ int width = 0; int height = 0; float price = 0.0f; } C语言还有一种在一行声明多个变量并初始化的方式,请警惕这其中的陷进 int a, b, c=10; 以上代码中,只有变量`c`在声明的同时进行了初始化,而`a`、`b`均未初始化,在后续中可能会导致未对其初始化就使用了。建议在声明时都进行零值初始化 int a = 0, b = 0, c = 10; 为什么在大量的C教材中,都存在先声明,后初始化的代码范例呢?这是因为在早期C语言版本中,不能在声明变量的同时初始化,换句话说,就是变量声明和初始化必须分开两行写,在大量陈旧落伍教材和书籍中存在这样的写法,这些不合时宜的写法对现在的C学习者造成极大误导。 ### 常量 ### C语言中使用`const`关键字修饰的就是常量,常量是不能修改的。C语言中,约定使用变量名大写来表示常量,多个单词则使用下划线分隔,例如`MD_MARK`,这只是一种编码风格,不是必须的,但是建议遵守它,否则你可能会受到同行的鄙视。这样的好处是看的人一眼能识别出这是一个常量,而且能避免一些命名冲突。 const int PI = 3.14; 在C语言中,还有一种方式来定义常量 #include<stdio.h> // 定义一个宏 PI #define PI 3.14 int main(void){ printf("%f",PI); } 注意,以上实际上是定义了一个宏,它并不是我们所说的那种真正意义上的常量,但它的效果等同于常量,而且在某种时候这种方式比使用`const`关键字定义常量性能更好,这也是为什么许多C语言高手都喜欢使用宏的一个原因。定义宏时,是没有等号的,请留意。 ## 欢迎关注我的公众号:编程之路从0到1 ## ![编程之路从0到1][0_1] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9hcmN0aWNmb3guYmxvZy5jc2RuLm5ldA_size_16_color_FFFFFF_t_70]: /images/20220127/9f9ddb09d88e408eaf947ef5a5304780.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lpbmdzaHVrdW4_size_16_color_FFFFFF_t_70_pic_center]: /images/20220127/fe9eb133cca24cd193afe90731fed69f.png [0_1]: /images/20220127/6d608a4b87f146d6aec844bcf49a54bf.png
相关 程序员C语言快速上手——基础篇(三) 文章目录 小拓展:C语言中int的正确使用姿势 语法基础 表达式 算术运算符 关系运算符 待我称王封你为后i/ 2022年01月23日 00:19/ 0 赞/ 282 阅读
相关 程序员C语言快速上手——高级篇(九) 文章目录 高级篇 结构体 背景 结构体的声明与使用 结构体变量的初始化 太过爱你忘了你带给我的痛/ 2021年12月09日 20:55/ 0 赞/ 352 阅读
还没有评论,来说两句吧...