简单易懂的C语言-3

在学习C语言之前我们先来了解一下一个程序应该包括哪些内容。

C语言的结构

C语言主要包括下面这几个内容:

  • 预处理器指令

  • 函数

  • 变量

  • 语句(语句块)和表达式

  • 注释
    我们看回上一节的代码

    1
    2
    3
    4
    5
    6
    7
    #include<stdio.h>

    int main()
    {
    printf("HelloWorld!"); //打印HelloWorld
    return 0;
    }
  • 第一行的 #include<stdio.h> 叫做预处理器指令,用途就是在编译的时候加入这个stdio.h文件里的内容。

  • 到下两行的int main(),这里的main指这个函数是主函数,程序都需要从主函数开始,没有写C语言程序一定要有主函数,不然就运行不起来。而main前面的int指这个函数是int类型,类型后面说到。

  • 第五行有两个部分,一个是printf("HelloWorld!");//打印HelloWorld,printf()是在stdio.h中写好的函数,用来在命令行中打印各种字符(不要忘记后面的“;”哦,没写“;”是会报错的)。右边还有一句//打印HelloWorld,主要内容是“//”,从双斜杠开始,后面的任何字符都会被编译器无视,后面写的任何内容将不会出现在编译好的程序里。

  • 下一行的return 0;,这句话代表了这个函数的结束,并返回0,所以就算你下面还有其他语句,也不会执行,因为一旦这个函数执行了return语句就会立刻结束。

如果看完上一节我相信你也掌握了编译的技巧了,如果还不懂就复习一下前面的内容。

语句的结构

这里用上面的printf("HelloWorld!");来说,这是一个语句,它应该包括五部分:

1
2
3
4
5
printf
(
"HelloWorld!"
)
;

return 0;可以看成

1
2
3
return
0
;

从两个例子可以看出所有的语句结束时均要加上;不然会报错,而函数后面均要使用(),括号里面的内容是你要传入的内容,比如printf函数输入”Fuck”就可以在命令行打印出Fuck。

注释

上面讲到了单行注释//,其实还有一个多行注释,用法是

1
2
3
4
5
/*  
窝窝头
一块钱四个
嘿嘿
*/

相当于

1
2
3
4
5
//
// 窝窝头
// 一块钱四个
// 嘿嘿
//

当然//记得双击么么哒也相当于/* 记得双击么么哒 */

你喜欢怎么用就看你了。

标识符

标识符用于给函数、变量、常量等注入灵魂(指命名),但是命名要遵循规范哦,不然也会报错,最好按照一种命名方法进行命名不然恶心到的是自己或者下一个接手这个项目的人。

规范指:

一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。C语言是区分大小写的语言所以需要注意一下,比如awsl和AWSL是不一样的哦,OI和0l也是不一样的哦(左边那个是大学的o和大写i,右边是数字零和小写的L)。

命名方法:

这里说两种最常用的命名方法,分别是驼峰命名法和下划线法。
驼峰命名法例如:printEmployeeSalay、getValueFromSQLServer、_httpListenAndServe等

下面改成下划线法:print_employee_salay,get_value_from_OS_Environment

我是比较喜欢在编程时使用驼峰命名法,在数据库中使用下划线,看你们喜欢。

不过上面命名并非最好的方法,你觉得是不是太长了,当写代码的时候如果没有自动补全会非常难受,当然也并非都是缺点,如果这是别人写的代码你可能一眼就知道是用来干什么的。

大部分情况应该要做到见名知意且简短,比如求和(sum),数值(val),圆周率(Pi)。

思考题:上面的两个标识符可以怎么简写呢?

新手写代码非常喜欢使用:a、abc、a1、a2这样子的标识符,这些标识符不应该乱用,应该仅仅用于循环的控制变量,不然代码行数一多,时间一长,你就会忘了哪个变量用来干什么。

命名规范补充

下面是不能使用的命名字符:auto、break、case 、char 、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedefunsigned、union、void、volatile、while、_Bool、_Complex、_Imaginary、inline、restrict、_Alignas、_Alignof、_Atomic、_Generic、_Noreturn、_Static_assert、_Thread_local

至于为什么不能使用,请继续学习并思考为什么不能使用这些词(从auto直到while)。

空格的使用

空格一般用于某个元素的结束,比如int age,中间的空格表示了int的结束。

空格还可以用于提高代码的可读性,比如

1
2
food = noodle + pizza;
food=noodle+pizza;

第一行和第二行效果是完全一样的,但是明显第一行好看很多。

数据类型

  1. 基本类型

    它们是算术类型,包括两种类型:整数类型和浮点类型。

  2. 枚举类型

    它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。

  3. void类型

    类型说明符 void 表明没有可用的值。

  4. 派生类型

    它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。

整数类型

类型 储存大小 值范围
char 1 字节 -128 到 127 或 0 到 255
unsigned char 1 字节 0 到 255
signed char 1 字节 -128 到 127
int 2 或 4 字节 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
unsigned int 2 或 4 字节 0 到 65,535 或 0 到 4,294,967,295
short 2 字节 -32,768 到 32,767
unsigned short 2 字节 0 到 65,535
long 4 字节 -2,147,483,648 到 2,147,483,647
unsigned long 4 字节 0 到 4,294,967,295

long float double等类型在不同平台不同编译器的储存大小可能不一样,下面实例使用sizeof运算符来得到对象或者类型的储存字节大小。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <limits.h>

int main()
{
printf("int 存储大小 : %lu \n", sizeof(int));
printf("char 存储大小 : %lu \n", sizeof(char));
printf("long 存储大小 : %lu \n", sizeof(long));

return 0;
}

浮点类型

下表列出了关于标准浮点类型的存储大小、值范围和精度的细节:

类型 | 储存大小 | 值范围 | 精度

  • | - | - |
    float | 4 字节 | 1.2E-38 到 3.4E+38 | 6 位小数
    double | 8 字节 | 2.3E-308 到 1.7E+308 | 15 位小数
    long double | 16 字节 | 3.4E-4932 到 1.1E+4932 | 19 位小数

上面我们学会了用sizeof获得整形类型的储存大小,下面实例展示了获得float的储存空间和范围值

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <float.h>

int main()
{
printf("float 存储最大字节数 : %lu \n", sizeof(float));
printf("float 最小值: %E\n", FLT_MIN );
printf("float 最大值: %E\n", FLT_MAX );
printf("精度值: %d\n", FLT_DIG );

return 0;
}

void类型

void指空类型,一般分三种:1)函数返回值为空,2)函数参数为空,3)指针指向void。后续章节会详细介绍这些类型的用法。

获得成就
这是?基本语法!:初步掌握基本语法和结构


变量和常量

上面学完了结构和数据类型并获得一项成就,是不是有点开心呢,那么你可以开始学习定义变量和使用运算符进行数据的操作了

在C语言中,如果你想使用某一个数据类型,比如int,你就需要创建一个变量来储存这个数据类型的值,这叫变量的定义或者变量的声明。

食用方法是:type variable1 variable2 ...;

这里的type是上面说到的数据类型,下面是几个实例:

1
2
3
4
int    i, j, k;
char c, ch, input;
float f, salary;
double d;

既然声明可以储存值的变量,那么就可以把值赋给变量,继续列举几个实例

1
2
3
int d = 1, i = 2;
char ch;
ch = 'a';

赋值可以在声明的时候进行,或者先声明下一句再复制。注意要赋值后再使用这个变量

运算符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号,C语言内置了非常“丰(e)富(xin)”的运算符,包括以下类型的运算符:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 杂项运算符
    下面我们先选最常用的算术、关系、逻辑、赋值运算符来讲。

算术运算符

算术运算符包括:+ - * / % ++ –
我寻思大部分人都学过数学,那么下面请跟着在编辑器里写一遍下面的实例,观察程序运行的结果,思考一下这些运算符都是什么意思。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main()
{
int a = 121;
int b = 11;
int c ;

c = a + b;
printf("使用 + - c 的值是 %d\n", c );
c = a - b;
printf("使用 - - c 的值是 %d\n", c );
c = a * b;
printf("使用 * - c 的值是 %d\n", c );
c = a / b;
printf("使用 / - c 的值是 %d\n", c );
c = a % b;
printf("使用 % - c 的值是 %d\n", c );
c = a++; // 赋值后再加 1 ,c 为 21,a 为 22
printf("使用 ++ - c 的值是 %d\n", c );
c = a--; // 赋值后再减 1 ,c 为 22 ,a 为 21
printf("使用 -- - c 的值是 %d\n", c );

}

关系运算符

我们先假设两个变量a和b,值分别233,666。

运算符 描述 实例
== 检查两个操作数的值是否相等,如果相等则条件为真。 (A == B) 不为真。
!= 检查两个操作数的值是否相等,如果不相等则条件为真。 (A != B) 为真。

| 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。
= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。

逻辑运算符

同上我们照样假设a和b,a为真和b为假,则:

运算符 描述 实例
&& 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A && B) 为假。
称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。
! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 !a为假,!(A && B) 为真。

赋值运算符

这里因为没说位运算符所以这里只讲 = 、+= 、-= 、= 、/= 、%=*

=是最简单的赋值操作符,用于把右边操作数赋给左边,比如:c = a + b,就是把a+b的值相加赋给c

c += a 相当于 c = c + a,相信聪明的你能想到+=是什么意思了吧。同理c *= a 等于c = c * a。那么其他的用法也相同。

第三章的思考题:

用上面学到的知识,声明一个变量,接收一个年分,判断是否是闰年,并在命令行输出这一年是否是闰年。(解析和答案在下面评论区)

获得成就
运算时间到!:初步掌握运算符并且能使用运算符处理一些算术问题。