目录
一、编译/执行 C 程序
C 程序主要包括以下部分:
- 预处理器指令
- 函数
- 变量
- 语句 & 表达式
- 注释
#include <stdio.h>
int main()
{
/* 我的第一个 C 程序 */
printf("Hello, World! \n");
return 0;
}
#include<stdio.h> 是预处理器指令,告诉 C 编译器在实际编译之前要包含 stdio.h 文件。
stdio 表示系统文件库, 也可以声明其它的。
.h 表示头文件,因为这些文件都是放在程序各文件的开头。
#include导入头文件的预编译指令,告诉预处理器将指定头文件的内容插入到预处理器命令的相应位
<> 表示系统自带的库
也可以写成" " 表示用户自定义的库
如果写成" "并且自定义的库里面没有这个文件系统会自动查找自带的库,如果还是没有就报错
int main() 程序的入口
int 表示数字格式,返回一个数字
main()主函数 表示程序的入口,所有的 C 语言程序都需要包含 main() 函数,一个程序有且只能有一个main()函数的存在,代码从 main() 函数开始执行。
{ 程序从这里开始运行
/* ... */ 用于注释说明。
printf() 用于格式化输出到屏幕。printf() 函数在 "stdio.h" 头文件中声明。
printf("Hello, World! \n"); 打印一个Hello, World!
return 0; 返回一个整数0,因为它是int类型,所以只能返回整数
} 程序从这里结束
二、C基本语法
C 的令牌
C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。例如,下面的 C 语句包括五个令牌:
printf("Hello, World! \n");
这五个令牌分别是:
printf
(
"Hello, World! \n"
)
;
分号
在 C 程序中,分号是语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。
例如,下面是两个不同的语句:
printf("Hello, World! \n");
return 0;
注释
C 语言有两种注释方式:
// 单行注释
以 // 开始的单行注释,这种注释可以单独占一行。
/* 单行注释 */
/*
多行注释
多行注释
多行注释
*/
/* */ 这种格式的注释可以单行或多行。
注意:不能在注释内嵌套注释,注释也不能出现在字符串或字符值中。
标识符
C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。
- 一个标识符只能由字母,数字,下划线_组成
- 区分大小写
- 只能字母或下划线开头
- 不能与关键字重名
关键字
/*
auto 声明自动变量
break 跳出当前循环
case 开关语句分支
char 声明字符型变量或函数返回值类型
const 定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
continue 结束当前循环,开始下一轮循环
default 开关语句中的"其它"分支
do 循环语句的循环体
double 声明双精度浮点型变量或函数返回值类型
else 条件语句否定分支(与 if 连用)
enum 声明枚举类型
extern 声明变量或函数是在其它文件或本文件的其他位置定义
float 声明浮点型变量或函数返回值类型
for 一种循环语句
goto 无条件跳转语句
if 条件语句
int 声明整型变量或函数
long 声明长整型变量或函数返回值类型
register 声明寄存器变量
return 子程序返回语句(可以带参数,也可不带参数)
short 声明短整型变量或函数
signed 声明有符号类型变量或函数
sizeof 计算数据类型或变量长度(即所占字节数)
static 声明静态变量
struct 声明结构体类型
switch 用于开关语句
typedef 用以给数据类型取别名
unsigned 声明无符号类型变量或函数
union 声明共用体类型
void 声明函数无返回值或无参数,声明无类型指针
volatile 说明变量在程序执行中可被隐含地改变
while 循环语句的循环条件
*/
C 中的空格
只包含空格的行,被称为空白行,可能带有注释,C 编译器会完全忽略它。
在 C 中,空格用于描述空白符、制表符、换行符和注释。空格分隔语句的各个部分,让编译器能识别语句中的某个元素(比如 int)在哪里结束,下一个元素在哪里开始。因此,在下面的语句中:
int age;
在这里,int 和 age 之间必须至少有一个空格字符(通常是一个空白符),这样编译器才能够区分它们。另一方面,在下面的语句中:
fruit = apples + oranges; // 获取水果的总数
这里的空格字符不是必须的,只是为了增强代码的可读性而适当添加上去的。
三、C数据类型
C 中的类型可分为以下几种:
- 基本类型:
它们是算术类型,包括两种类型:整数类型和浮点类型。
- 枚举类型:
它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。
- void 类型:
类型说明符 void 表明没有可用的值。
- 派生类型:
它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。
整数类型
类型 | 存储大小 | 值范围 |
---|---|---|
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 |
为了得到某个类型或某个变量在特定平台上的准确大小,可以使用 sizeof 运算符。表达式 sizeof(type) 得到对象或类型的存储字节大小。下面的实例演示了获取 int 类型的大小:
#include <stdio.h>
#include <limits.h>
int main()
{
printf("int 存储大小 : %d \n", sizeof(int));
return 0;
}
输出结果为:
// int 存储大小 : 4
浮点类型
类型 | 存储大小 | 值范围 | 精度 |
---|---|---|---|
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 位有效位 |
#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;
}
%E 为以指数形式输出单、双精度实数
输出结果为:
/*
float 存储最大字节数 : 4
float 最小值: 1.175494E-38
float 最大值: 3.402823E+38
精度值: 6
*/
void 类型
void 类型指定没有可用的值。它通常用于以下三种情况下:
- 函数返回为空
C 中有各种函数都不返回值,或者说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status);
- 函数参数为空
C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void);
- 指针指向 void
类型为 void * 的指针代表对象的地址,而不是类型。例如,内存分配函数 void *malloc( size_t size ); 返回指向 void 的指针,可以转换为任何数据类型。
四、变量
变量是程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。
变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的。(标识符)
C 中的变量定义
变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示:
type variable_list;
在这里,type 必须是一个有效的 C 数据类型,可以是 char、w_char、int、float、double 或任何用户自定义的对象,variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明:
int i, j, k;
char c, ch;
float f, salary;
double d;
行 int i, j, k; 声明并定义了变量 i、j 和 k,这会指示编译器创建类型为 int 的名为 i、j、k 的变量。
变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示:
type variable_name = value;
下面列举几个实例:
extern int d = 3, f = 5; // d 和 f 的声明与初始化
int d = 3, f = 5; // 定义并初始化 d 和 f
byte z = 22; // 定义并初始化 z
char x = 'x'; // 变量 x 的值为 'x'
不带初始化的定义:带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。
C 中的变量声明
变量声明向编译器保证变量以指定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。
变量的声明有两种情况:
- 一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。
- 另一种是不需要建立存储空间的,通过使用extern关键字声明变量名而不定义它. 例如:extern int a 其中变量 a 可以在别的文件中定义的。除非有extern关键字,否则都是变量的定义。
extern int i; //声明,不是定义
int i; //声明,也是定义
例如:
#include <stdio.h>
// 函数外定义变量 x 和 y
int x;
int y;
int addtwonum()
{
// 函数内声明变量 x 和 y 为外部变量
extern int x;
extern int y;
// 给外部变量(全局变量)x 和 y 赋值
x = 1;
y = 2;
return x+y;
}
int main()
{
int result;
// 调用函数 addtwonum
result = addtwonum();
printf("result 为: %d",result);
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:result 为: 3
extern int a; // 声明一个全局变量 a
int a; // 定义一个全局变量 a
extern int a =0; // 定义一个全局变量 a 并给初值。一旦给予赋值,一定是定义,定义才会分配存储空间
int a =0; //定义一个全局变量 a,并给初值
声明之后你不能直接使用这个变量,需要定义之后才能使用。
第四个等于第三个,都是定义一个可以被外部使用的全局变量,并给初值。
糊涂了吧,他们看上去可真像。但是定义只能出现在一处。也就是说,不管是 int a 还是 int a=0 都只能出现一次,而那个 extern int a 可以出现很多次。
当你要引用一个全局变量的时候,你就要声明 extern int a 这时候 extern 不能省略,因为省略了,就变成 int a 这是一个定义,不是声明。
C 中的左值(Lvalues)和右值(Rvalues)
C 中有两种类型的表达式:
- 左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
- 右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。
变量是左值,因此可以出现在赋值号的左边。数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边。下面是一个有效的语句:
int g = 20;
但是下面这个就不是一个有效的语句,会生成编译时错误:
10 = 20;