编程语言可以简单的理解为一种计算机和人都能识别的语言,一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地表达在不同情况下所应当采取的行动。从语言的发展史上来说:最开始只有低级语言,也就是常说的机器语言,例如二进制:101001。后来发展出来汇编语言,即第二代计算机语言,用一些容易理解和记忆的字母,单词来代替一个特定的指令,列如用“ADD”代表数字逻辑上的加减。从20世纪60年代开始使用第三代语言,这类语言通常称为高级语言。高级语言并不是特指的某一种具体的语言,而是包括很多编程语言,如流行的C、C++、C#、Java、Python等。
C语言诞生于美国的贝尔实验室,由丹尼斯·里奇根据肯尼斯·汤普森设计的B语言为基础发展而来,在它的主体设计完成后,汤普森和里奇用它完全对UNIX操作系统的重写,且随着UNIX的发展,C语言也得到了不断的完善。为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,诞生了第一个完备的C标准,简称“C89”,也就是“ANSI C”,截至2020年,最新的C语言标准为2018年6月发布的“C18”。
C语言的编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。推荐大家使用是微软公司的开发工具MSVC,下载连接Microsoft Visual Studio,它可以理解为它是一个编辑器+编译器+调试器,Visual Studio是最流行的Windows平台应用程序的集成开发环境。
C语言是一门通用计算机编程语言,广泛应用于底层开发,底层开发可以理解成最接近于硬件的开发,是最基础最重要的开发。作为一门高级语言,C语言和其他面向对象的高级语言有着本质上差异,C语言是一门面向过程的计算机编程语言。
此段代码将会在屏幕上输出Hello World
#include
int main()
{
printf("Hello World\n");
return 0;
}
#include
作用是在编译之前把程序需要使用的关于系统定义的函数printf()的一些信息文件stdio.h包含进来。stdio是Standard input output的缩写,意味标准输入输出,“.h ”作为后缀的文件称为头文件,#include可以理解为引用,< >是标准格式,记住即可。这段代码的main
函数是程序的入口,一个工程中main函数有且仅有一个。{ }也是固定格式,这点记住即可。printf 是输出函数,是C语言的重要函数。当编译器遇到 printf( )
函数时,如果没有找到 stdio.h 头文件,会发生编译错误。此外需要注意的是,printf 中的双引号和后面的分号必须是在英文输入法下,双引号内的字符串可以是英文,也可以是中文。 "Hello World\n"
,Hello World是要输出的内容,\n是转义字符,意味着换行。 return 0
代表程序正常退出。
在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。数据类型决定了变量存储占用的空间,以及如何解释存储的位模式。如果说编程语言用来描述生活中的问题,那么存在这么多的数据类型,就是为了更加丰富的表达生活中的各种值。
常用的数据类型有:
数据类型 | 含义 |
---|---|
char | 字符数据类型 |
short | 短整型 |
int | 整形 |
long | 长整型 |
long long | 更长的整形 |
float | 单精度浮点数 |
double | 双精度浮点数 |
每种数据类型在内存中所占用的大小:
sizeof 是一个关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小
#include
int main()
{
printf("%u\n", sizeof(char));
printf("%u\n", sizeof(short));
printf("%u\n", sizeof(int));
printf("%u\n", sizeof(long));
printf("%u\n", sizeof(long long));
printf("%u\n", sizeof(float));
printf("%u\n", sizeof(double));
printf("%u\n", sizeof(long double));
return 0;
}
类型 | 存储大小 |
---|---|
char | 1字节 |
unsigned char | 1字节 |
signed char | 1字节 |
int | 4字节 |
unsigned int | 4字节 |
short | 2字节 |
unsigned short | 2字节 |
long | 4字节 |
unsigned long | 4字节 |
值得注意的是各种数据类型的存储大小与系统位数有关,但目前通用的以64位系统为主。另外C语言规定sizeof(long)>=sizeof(int)
即可,一般sizeof(long)
为4个字节。
字节是计算机中数据存储的单位,常见的存储单位主要有bit(位)、Byte(字节)、KB(千字节)、MB(兆字节)、GB(千兆字节)。一个bit可以存放一个 0/1数据,如果一个计算机的内存是 4GB,那么它能存放多少4×1024×1024×1024×8 个 0/1,这就是 4GB 内存条所能存储的数据。
它们换算关系如下:
生活中的有些值是不变的,比如:圆周率,性别,身份证号码,血型等等; 有些值是可变的,比如:年龄,体重,薪资。对于不变的值,C语言中用常量的概念来表示;对于变的值,在C语言中用变量来表示,变量其实只不过是程序可操作的存储区的名称。
变量的定义:
在C语言中,定义变量的方式为类型+名称
。变量的名称可以由字母、数字和下划线字符组成,它必须以字母或下划线开头,另外C语言对大小写敏感,所以大写字母和小写字母是不同的。
int age = 150;
float weight = 45.5f;
char ch = 'w';
变量的分类:
#include
int a = 2021; //属于1.全局变量——定义在大括号的外部
int main()
{
int b = 2022; //属于2.局部变量——定义在大括号的内部
return 0;
}
在C语言中,放到大括号里面的都是局部变量,非main函数也符合这一规则。当局部变量和全局变量命名发生冲突的时候,采用局部优先原则。
变量的作用域:
作用域是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效的,而限定这个名字的可用性的代码范围就是这个名字的作用域。局部变量的作用域是变量所在的局部范围,而全局变量的作用域是整个工程,即使是跨文件使用,只需要使用extern 变量类型 变量名
来声明外部符号,就可以使用跨文件使用。简言之:一个变量哪里可以使用, 哪里就是他的作用域。
变量的生命周期:
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。对于局部变量而言,局部变量的生命周期是从进入作用域开始,出作用域生命周期结束。对于全局变量而言,全局变量的生命周期就是是整个程序的的生命周期。
常量
C语言中,常量是固定值,在程序执行期间不会改变,它就像是常规的变量,只不过常量的值在定义后不能进行修改。C语言中的常量分为以下以下几种:1. 字面常量 、2. const 修饰的常变量、3. #define 定义的标识符常量、4. 枚举常量
#include
//括号中的MALE,FEMALE,SECRET是枚举常量
enum Sex
{
MALE,
FEMALE,
};
//#define的标识符常量
#define MAX 100
int main()
{
//字面常量
3.14;
1000;
//const 修饰的常变量
const float pai = 3.14f; //const是常属性的意思
//pai = 5.14; //const 修饰的常变量在C语言中只是在语法层面限制了变量 pai 不能直接被改变,但是 pai本质上还是一个变量的,所以叫常变量
printf("max = %d\n", MAX);
//枚举常量,枚举常量的默认是从0开始,依次向下递增1的
enum Sex s = MALE;
printf("%d\n", MALE); //0
printf("%d\n", FEMALE); //1
return 0;
}
C语言的内置类型只有字符类型,没有字符串类型。像"abc"
这种由双引号引起来的一串字符
称为字符串字面值,简称字符串。
字符串的结束标志是字符串末尾隐藏的字符 '\0'
,在计算字符串的长度的时候,\0是结束标志,不算字符串的内容。
int main()
{
char arr1[] = "hello";
char arr2[] = {'h', 'e', 'l','l','o'};
char arr3[] = {'h', 'e', 'l','l','o','\0'};
printf("%s\n", arr1); //hello hello后面隐藏了一个\0
printf("%s\n", arr2); //hello烫烫烫烫 字符串的打印默认以\0结尾,print函数会到o会面的存储空间找\0,找到了才停止打印,hello后面跟着随机字符
printf("%s\n", arr3); //hello 在字符数组结尾后面手动添加\0也可以停止打印
return 0;
}
转义字符就是转变原来的意思,简单来说就是在一些字符前加"\"
使它具有其他意义。
转义字符 | 释义 |
---|---|
\ ? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\ ’ | 用于表示字符常量 ’ |
\ \“ | 用于表示一个字符串内部的双引号 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字打印对应的ASCII值。 如: \130打印为X |
\xdd | dd表示1~2个十六进制数字打印对应的ASCII值。 如: \x30打印为0 |
八进制的130表示为十进制的88,在ASCII表中,88代表X。同理十六进制的30表示为十进制的48,在ASCII表中,48代表数字0。
注释可以注释掉代码中有不需要的代码,更重要的是注释一些难懂的代码。C语言采用的注释风格为 /*xxxxxx*/
,这样不能嵌套注释;C++采用的注释风格为 //xxxxxxxx
,这样的注释可以注释一行也可以注释多行。实际开发中,二者岂可。
C语言的选择语句允许程序在一组选项中选择一条特定的执行路径。C语言的选择语句分为两种,if
和switch
语句。
if语句:
if语句中可以包含else语句,表示在圆括号内的表达式值为零时,执行else后面的语句,其基本形式如下:
if (表达式)
语句
else
语句
switch语句:
在多条选择路径时,switch语句比if更易读,并且执行速度往往比较快。default表示上述情况都不匹配时的执行语句,default可有可无,且没有位置限制。
switch (表达式)
{
case 常量表达式:
多条语句
...
case 常量表达式:
多条语句
default:
多条语句
}
C语言是一种结构化的程序设计语言,分为:顺序结构、 选择结构、循环结构。
循环结构可以表示重复执行的代码,有3种常见的语句:while语句、for语句和do…while语句。
while语句
while(表达式)
{
循环语句;
}
for循环语句
for(初始化表达式;判断表达式;递增(递减)表达式)
{
执行语句
}
do…while()循环
do
循环语句;
while(表达式);
函数是一组一起执行一个任务的语句。函数的声明告诉编译器函数的名称、返回类型和参数。函数的定义提供了函数的实际主体。函数的特点就是简化代码,代码复用。
int Add(int x, int y)
{
int z = x+y;
return z;
}
C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
数组的定义:
在 C语言中要声明一个数组,需要指定元素的类型和元素的数量。定义数组元素的数量必须采用常量,而不能采用变量。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//定义一个整形数组,最多放10个元素
数组的下标
C语言规定,数组的每个元素都有一个下标,下标是从0开始的。数组元素可以通过下标来访问的。int arr[10] = {0} ;
如果数组10个元素,下标的范围是0~9
操作符是一种告诉编译器执行特定的数学或逻辑操作的符号:
名称 | 分类 |
---|---|
算术操作符 | + - * / % |
移位操作符 | >> << |
位操作符 | & ^ | |
赋值操作符 | = += -= *= /= &= ^= |
单目操作符 | !- + & * sizeof ~ - - + + (类型) |
关系操作符 | > >= < <= ! = == |
逻辑操作符 | && || |
条件操作符 | exp1 ? exp2 : exp3 |
逗号表达式 | exp1, exp2, exp3, …expN |
下标引用、函数调用和结构成员 | [] () . -> |
C语言提供了丰富的关键字,这些关键字是C语言本身预先设定好的,用户不能自己创建关键字。常见的关键字如下所示:
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 typedef union unsigned void volatile while
关键字 typedef
C 语言提供了 typedef 关键字,typedef 顾名思义是类型重命名,可以使用它来为类型取一个新的名字,类似于起外号。
//将unsigned int 重命名为uint, 所以uint也是一个类型名
typedef unsigned int uint;
int main()
{
unsigned int num1 = 0;
uint num2 = 0; //num1和num2,这两个变量的类型是一样的
return 0;
}
关键字static
在C语言中,static关键字用来修饰变量和函数
static修饰局部变量,实际上改变了变量的存储位置,本来一个局部变量是放在栈区,被static修饰后放在了静态区。导致出了作用域,此静态局部变量仍然此存在,该静态局部变量的生命周期变长而作用域并没有发生变化。直到到程序结束,生命周期才结束。内存可以分为栈区、堆区、静态区,如下图所示:
static修饰全局变量,一个全局变量本来可以用extern
这个关键字来声明外部符号,具有外部链接属性,但是当这个全局变量被static修饰后,外部链接属性就变成了内部链接属性,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
static修饰函数一个函数本来是具有外部链接属性的,但是被static修饰后,外部链接属性变成了内部链接属性。一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
在预处理阶段,类似define 定义的这种M符号会被替换成它的内容100,M没有类型,根据他的赋值什么都有可能。#define
定义宏,类似函数来使用。
#define M 100
#define MAX(x,y) ((x)>(y)?(x):(y))
内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的。为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。同时为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。在32位机器下,有32根地址线,通过电信号转化为数字信号,每一根地址线可以表示一个占1个字节的内存单元,而32根地址线可以表示为2^32字节的内存空间,也就是4GB。
指针
每一个变量都有一个内存位置,每一个内存位置都定义了可使用 &
运算符来访问的地址,它表示了在内存中的一个地址。指针也称为指针变量是用来存放内存地址的变量。如下代码表示定义一个变量命名为num,赋值为10。再定义一个指针变量p,将num的地址赋给它,这个时候我们通过取地址符号*
加上指针变量p就可以访问num,来改变他的数值,打印出来为20。
int main()
{
int num = 10; // *说明p是一个指针对象;int说明p指向的对象是int类型
int* p = # // p是用来存放地址(指针)的,所以把p叫做指针变量
*p = 20; // *在这里叫解引用操作符,意思是通过p中存放的地址,找到p指向的内容
printf("%d\n", num);
return 0;
}
指针变量的大小
指针变量的大小取决于地址的大小,指针大小在32位平台是4个字节,64位平台是8个字节。
#include
int main()
{
printf("%d\n", sizeof(char*)); //4/8
printf("%d\n", sizeof(short*)); //4/8
printf("%d\n", sizeof(int*)); //4/8
printf("%d\n", sizeof(double*));//4/8
return 0;
}
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。结构体是 C 语言中一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
// 结构体类型
typedef struct Stu
{
char name[20];//名字-字符串
int age; //年龄 - 整数
char sex[5]; //性别 - 字符串
char id[20]; //学号 - 字符串
}Stu;
void Print(struct Stu* ps)
{
//printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).id);
printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->id);
//-> 结构成员访问操作符
//结构体指针->结构体成员
}
int main()
{
//结构体变量
struct Stu s1 = {"张三", 18, "男", "2021060701"};//学生1
struct Stu s2 = {"如花", 45, "女", "2021060702"};//学生2
Stu s3 = {0}; //在这里给0和NULL都可以
//输入结构体数据
scanf("%s %d %s %s", s1.name, &(s1.age), s1.sex, s1.id);
//直接打印的
printf("%s %d %s %s\n", s1.name, s1.age, s1.sex, s1.id);
//. 结构成员访问操作符
//结构体变量.结构体成员
//使用函数打印
Print(&s2);
return 0;
}