程序员C语言快速上手——基础篇(二)

本文主要介绍C语言相关知识。首先讲解GCC编译命令,包括指定生成文件名和输出详细信息的参数。接着阐述数据类型,如标准C基础类型、C99新增类型,以及修饰数值类型。还介绍基本数据类型的打印占位符和获取类型长度的方法。最后说明变量需先声明并建议零值初始化,常量可用const修饰或宏定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本专栏已发布配套视频,请查看公众号视频专辑《程序员的C》B站视频

该系列博客也已升级第二版,新版内容请访问 这里


GCC 编译命令初探

编写测试代码 hello.c

#include <stdio.h>

int main(void){
    printf("hello world!\n");
}

在代码目录下打开cmd命令行或打开VSCode中的命令行,VS Code快捷键是【Ctrl】+【~】
在这里插入图片描述

输入编译命令进行编译

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 Coderun那就脱离了我们学习GCC以及GNU工具链的本意了,对我们去理解C语言没有任何好处,初学时,多多手敲这些命令,熟悉他们,对我们来说是有很大好处的,否则你根本不知道编译器C程序时,IDE到底干了些什么事。

数据类型

在这里插入图片描述

对于通常表示数值的类型,重点是关注它的范围大小,因为C语言数据类型的大小是不完全固定的,在不同的硬件平台,会有区别,尤其是一些嵌入式设备。下面给出一个通常情况下的表示范围

类型字节二进制位表示范围
char18 − 2 7 -2^7 27 ~ ( 2 7 − 1 ) (2^7 -1) (271)
short216 − 2 15 -2^{15} 215 ~ ( 2 15 − 1 ) (2^{15} -1) (2151)
int432 − 2 31 -2^{31} 231 ~ ( 2 31 − 1 ) (2^{31} -1) (2311)
long4 /832 /64 − 2 31 -2^{31} 231 ~ ( 2 31 − 1 ) (2^{31} -1) (2311) − 2 63 -2^{63} 263 ~ ( 2 63 − 1 ) (2^{63} -1) (2631)
float432 − 1 0 38 -10^{38} 1038 ~ 1 0 38 10^{38} 1038
double864 − 1 0 308 -10^{308} 10308 ~ 1 0 308 10^{308} 10308

以上就是标准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) 2321),如果不加关键字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在声明的同时进行了初始化,而ab均未初始化,在后续中可能会导致未对其初始化就使用了。建议在声明时都进行零值初始化

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程之路从0到1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值