01 第一个C语言
#include<stdio.h>
int main()
{
printf("hello world");
return 0;
}
- c语言入口函数
- include
包含的头文件(import) - 单行注释//,多行注释/ /
-
02 C语言标识符
数字字母下划线
- 数字不能开头
- 区分大小写
- 不能是关键字
| 关键字 | 说明 |
| —- | —- |
| auto | 声明自动变量 |
| break | 跳出当前循环 |
| case | 开关语句分支 |
| 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 | 循环语句的循环条件 |
03 数据类型
基本类型:它们是算术类型, 包括两种类型:整数类型和浮点类型。 |
---|
枚举类型:它们也是算术类型 |
void类型:类型说明符vold表明没有可用的值。(None) |
复合类型:指针类型、数组类型、结构类型、共用体类型和函数类型。 |
3.1 整数类型
- 通常在不同编译器上有所区别
- 使用sizeof(运算符可以获取大小 | char | 1字节 | -128到127或0到255 | | —- | —- | —- | | wchar_ t | 2字节 | -32,768到32,767 | | 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 |
3.2浮点型
float | 4字节 | 1.2E-38到3.4E+38 | 6位小数 |
---|---|---|---|
double | 8字节 | 2.3E-308到1.7E+308 | 15位小数 |
04 C语言变量
- C语言的变量在定义时就确定变量存储大小和布局
- C语言的变量需要符合标识符的命名规范
- 定义变量
#include <stdio.h>
int main()
{
//变量走义时必须指名类型,与python不同, 这个类型一 直到安量销毁
int a,b,c; //只定义变量
int n =99; //定义并赋值
char c,ch;
float f;
return 0;
}
05 运算符
| 运算符 | 描述 | 实例(A=10,B=20) | | —- | —- | —- | | + | 把两个操作数相加 | A+B将得到30 | | - | 从第一个操作数中减去第二个操作数 | A-B将得到-10 | | | 把两个操作数相乘 | AB将得到200 | | / | 分子除以分母 | B/A将得到2 | | % | 取模运算符,整除后的余数 | B%A将得到0 | | ++ | 自增运算符,整数值增加1 | A++将得到11 | | — | 自减运算符,整数值减少1 | A—将得到9 |
5.1 算数运算符
#include <stdio.h>
int main()
{
int a=10,b=20;
int C = a+b;
int d = a-b;
int e = a/b;
int f = a%b;
int x = a++;
int y = a--;//y=a;a--;
int z = ++a;//a++;z=a;
int k = --a;
}
5.2 关系运算符
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A==B)为假。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A!=B)为真. |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A>B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A<B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A>=B)为假。 |
<= | 检卉左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A<=B)为真。 |
#include <stdio.h>
int main()
{
//在c中,假用0表示,真用非0表示(-1也是真)
// python
//if x == y:
// pirnt("hello")
if(7==8){
printf("真\n");
printf("7==8");
}
else
printf("假\n");
if(7 >= 8)
printf("真\n");
else
printf("假\n");
if(7!= 8)
printf("真\n");
else
printf("假\n");
}
5.3 逻辑运算符
运算符 | 描述 | 实例 |
---|---|---|
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A&&B)为假 |
II | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (AIlB)为 真 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | (A&&B)为 真 |
#include <stdio.h>
int main()
{
int a=10;
int b=20;
if(a>10 && a<30)// &&类似python and 左右必须为真结果为真
printf("真\n");
else
printf("假\n");
if(10<a <30 ) // 18< a结果是假,假(0) <30 条件-一定满足
printf("真\n");
else
printf("假\n");
if(a>10 || a<30 ) //类似python or左右有一个为真结果为真
printf("真\n");
else
printf("真\n");
if(!a) //类似python not真为假,假为真
printf("真\n");
else
printf("假\n");
}
5.4 位运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与 | 100b &111b=100b |
| | 按位或 | 100b | 011b = 111b |
^ | 按位异或 | 100b | 011b = 111b |
>> | 右移 | 4>> 1 ==2 |
<< | 左移 | 4<<1 ==8 |
#include <stdio.h>
int main()
{
int a=3;
int c=a | 7;
int d=a & 0x0F;
int e=a ^ 8;//两个异或得到新的值
int f=e ^ a;//将新的值和其中-一个,可以得到原来的值,加密
int g = 4<<1;//<<1次等于*2
int h = 4>>1;// << 1次等于/2
}
5.5 赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C=A+B将把A+B的值赋给C |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左 边操作数 | C+=A相当于C=C+A |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左 边操作数 | C-=A相当于C=C-A |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左 边操作数 | C=A相当于C=CA |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左 边操作数 | C/=A相当于C=C/A |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C%=A相当于C=C%A |
<<= | 左移且赋值运算符 | C<<=2等同于C=C<<2 |
>>= | 右移且赋值运算符 | C>>=2等同于C=C>>2 |
&= | 按位与且赋值运算符 | C&=2等同于C=C&2 |
^= | 按位异或且赋值运算符 | C^=2等同于C=C^2 |
|= | 按位或且赋值运算符 | C|=2等同于C=C12 |
#include <stdio.h>
int main()
{
int a=3;
int b=10;
b+=1;
b*=2;
b-=10;
b/=2;
b<<=2;
}
5.6其他运算符
运算符 | 描述 | 实例 |
---|---|---|
sizeof() | 返回变量的大小。 | sizeof(a)将返回4,其中a是整数。 |
& | 返回变量的地址。 | &a;将给出变量的实际地址。 |
女 | 解引用 | *a;将指向一个变量. |
?: | 条件表达式 | 如果条件为真?则值为X:否则值为Y |
#include <stdio.h>
int main()
{
int x = sizeof(int);
int j = sizeof(x);
int y=(int)&x;//取得x的地址
int z=1>10?10:7;
}
5.7 优先级
- 与python-样
-
06 选择结构
if
- if-else
- if-else if -else
- if嵌套
```c
include
int main() { int a =10; if (a==10){ //单if判断
} if (a == 9){ // if-else判断printf("yes a == 10\n");
} else{ //中问不能有其他语句printf(" yes a == 9\n");
} if(a > 10){ // if-else if - else判断printf(" no a != 9\n");
}else if(a > 7){ // 条件1不满足,将检查条件2,如果条件1满足,不会执行后面语句printf(" yes a > 10\n");
} else{printf(" yes a > 9\n");
} if(a >10 ){ //嵌套if if(a>10 && a<40)printf(" yes a < 7\n");
} }if(a<40){
printf("a >10 and a <40");
}
- switca-case
- 只能做简单的整数判断,不能做复杂的计算
```c
#include <stdio.h>
int main()
{
int number = 7;
scanf("%d", &number); // 接收-一个整形变量
switch(number)
{
//1每个case x的值不能出现重复,
//2 case语句需要break ,否则会继续执行下一个break
//3 case中如果定义变量,需要{}包裹起来
case 1: printf("one \n");break;
case 2:printf("two \n");break;
case 3:printf("three\n");break;
default:printf("other \n");break; //当所有数据都不匹配时执行这条语句
}
return 0;
}
07 循环
#include <stdio.h>
int main()
{
// 1.初始化值,2. 循环条件 3.循环体4.循环计数器
for(int i=0; i<10; i++)
{
printf("%d \n",i);
}
}
7.1 for循环
#include <stdio.h>
int main()
{
//1循环条件,2循环体
int i =0;
while(1)
//无限循环
{
i++;
//循环计算
if(i >10)//循环条件
break; // 跳出一 -层循环
}
}
7.2 do while 循环
#include <stdio.h>
int main()
{
int i=0;
do{
printf("%d\n",i);
i++;
}while(i<10);
}
7.4 break,connitue
循环控制语句
#include <stdio.h> int main() { for(int i=0; i<10; i++) { if(i==3) continue; //跳过当前循环 if(i==8) break; //跳出整个循环 printf("%d \n",i); } }
08 函数
每个程序都是从main函数开始的,有且只有一个
- C语言的组成单位是函数
- 自定义函数
```c
include
int add(int a,int b);
int main() { printf(“10 + 20 = %d”,add(10,20)); return 0; } //函数定义 //必须与函数声明时一样,是函数具体实现 int add(int a,int b) { return a+b; }
- c标准函数
| 头文件 | 函数 | 说明 |
| --- | --- | --- |
| #include<string.h> | strcpy(),strlen(),strcat() | 字符处理相关 |
| #include<stdio.h> | printf,scanf,fopen,fread | 输入输出相关 |
| #include<math.h> . | abs(),asin() | 数学相关 |
| #include<time.h > | time(), localtime | 时间相关 |
| #include<malloc.h> | malloc,free,calloc | 堆操作 |
<a name="EWRmg"></a>
# 09 作用域
| 变量类型 | 变量说明 | 作用域 | 生周期存 |
| --- | --- | --- | --- |
| 全局变量 | 定义在函数外的变量 | 从定义的地方开始 | 整个程序结束 |
| 局部变量 | 定义在函数内的变量 | 函数中,或者{}中 | 在函数,或者{}结束 |
| 函数形参 | 函数声明时的参数也属于局部变量 | 函数中 | 函数结束 |
```c
#include <stdio.h>
//函数外的变量,全局变量,作用域从这个地方开始,生存周期整个程序
int g_global= 100;
//函数定义
int add(int a,int b){ // int a,int b是形参,作用域在函数中,生存周期在函数结束
return a+b +g_global;
}
int main()
{
int number; //局部变量
printf("10 + 20 = %d\n" ,add(10,20));
if(10 >20)
{
int a =9; // a局部变量,作用域仅在if的{}中,生成周期在{} 结束,就被释放}
}
// a无法使用,出了{}结束
return 0;
}
10 数组
- C语言支持数组数据结构,它是一 组类型相同并且在内存中是连续的变量的集合。(list)
- 数组每个元素都有一个编号,编号从0开始到最大数-1
数组的声明
//数组类型数组名数组长度 int arr[10]; //定义了一个arr数组,类型int,长度10 // 1数组定义时长度就是固定的,不能更改 // 2.数组下标从0 -9 a[0] a[1] a[2] a[3]....a[9], a[10 ]数组越界 // 3.数组下标必须是正整数的值
数组初始化
int arr[10]={1,2,3,4,5,7,8};// 定义数组时可以进行初始化,同时给每个元素赋值, //只要有初始化,那么剩余部分都会赋值为0 int arr1[]={1,2,3,4}; //有初始化时,编译器自动算出数组长度,4 int arr2[]; //没有初始化,编译器无法识别,报错 //只有在初始化时可以整体赋值数组元素,过了初始化将不能整休赋值
数组使用
char buff[]= "hello world"; //自动推算字符串的长度,并赋值 for (int i=0;i< strlen(buff);i++) //循环字符长度 { printf("%c" ,buff[i]); //输出数组中每个元素 }
11 指针
●C语言最重要部分,与其他语言最大的区别(C++除外)
●指针变量就是个变量,变量中存放着地址,通过指针可以做许多有意义的事情
●这里记住一个事情指针及地址int a =99; //整形变量 int *p = &a; //定义一个指针变量,赋值为a的地址 char* pch = &c; // 定义一个指针变量,赋值为c的地址 *p=100; // *解引用,获取指针指向的变量内容,并赋值 指针的使用
12 内存管理
C语言提供-套动态内存函数
- 有些时候你需要一个数组,这个数组大小可能由用户动态的输入,然后去定义。但是C语言中的数组本身在定义时就已经限定死了,定义之初就必须确定大小,这时模可以用动态内存来实现
管理动态内存函数在malloc.h库中 | 序号 | 函数和描述 | | —- | —- | | 1 | void calloc(int num, int size);在内存中动态地分配num个长度为size的连续空间,并将 1 每一个字节都初始化为0。所以它的结果是分配了numsize个字节长度的内存空间,并且每 个字节的值都是0。 | | 2 | void free(void address);该函数释放address所指向的内存块,释放的是动态分配的内存空间。 | | 3 | void malloc(int num);在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。 | | 4 | void realloc(void address, int newsize);该函数重新分配内存,把内存扩展newsize。 |
通常使用malloc和free就足够 ```c
include
include
void main() {
int array_length;
//数组长度
scanf("%d",&array_length);//接收用户输入的长度
//int array[array_length];c语言不允许这种语法,数组定义时必须知道长度
int *parry=(int*)malloc(sizeof(int)* array_length);//动态分配内存
for(int i=0;i<array_length; i++)
{
scanf("%d",&parry[i]);
}
for(int i=0;i<array_length; i++)
{
printf("%d\n",parry[i]);
}
//释放内存
free(parry);
parry = NULL;//空指针,不指向空(悬空指)
}
<a name="LlbLB"></a>
# 13 struct 结构体
- C数组允许定义可存储相同类型数据项的变量,**结构**是C编程中另一种用户自定义的可用的数据类型, 它允许您存储不同类型的数据项
- 学生信息
```c
struct Student{
//声明结构体
int id;
char name[20];
float score;
} stu1,stu2;
//定义两个结构体变量
struct Student obj1,obj2; // 定义两个结构体变量, C语言必须在结构体名前加structobj1.id。100;
strcpy(obj1.name,"小明",strlen("小明")+1);
obj1.score = 99.2;
}
typedef类型重命名
typedef int INT; //将int重新命名INT,之后所有的INT等价于int INT number =10; //使用重命名的INT,等价于int number; INT *p ; typedef struct Student{ //声明结构体 int id; char name[20]; float score; }STUDENT,*STUDENT; //创建两个类型名,结构体类型和指针类型 STUDENT obj1; //相当于 struct student obj1,
14 函数指针
函数指针是指向函数的指针变量。
- 函数指针可以像-般函数-样,用于调用函数、传递参数。
- 函数指针声明
```c
include
include
int fun(int a, int b){ return a+b; }
//定义一个指向上面函数的函数指针 //返回值int,函数指针类型名PFUN, 参数有两个(参数类型,参数类型) typedef int (*PFUN)(int,int); //函数指针使用 //定义一个类型为PFUN函数指针类型的变量,变量名是pfun,将上面函数赋值给这个变量 PFUN pfun = fun;
int main() { //通过这个函数指针变量调用这个函数 printf(“a+b = %d\n”,pfun(10,20)); return 0; }
<a name="zB8fH"></a>
# 15 预处理
- 程序在编译阶段中有一个预处理阶段, 预处理命令在这个阶段会被展开
- C语言的预处理命令是以#开头的
```c
#include <stdio.h> //将stdio.h 文件在这个地方展开,预处理时
undefine PI //从这个地方后的PI将不在代表3.14
- 有参宏
```c
#define fun(x,y) x*y //带参数的宏
int x = fun(5,7); //会被替换成5+7
int y = fun(5+7,3) //宏只是简单替换5+7*3 = 26
- 条件编译(宏)
#define VALUE日 //定义一个宏 #if VALUE //条件编译,判断VALUE的值是真是假 printf("value = 0\n"); #else //条件不成立 printf("value != 0\n"); #endif // #if结束时必须endif结束
#define DEBUG //定义DEBUG宏 #ifdef DEBUG //如果定了DEBUG宏,执行 printf("hello"); //输出调试信息 #endif #ifndef DEBUG //如果没有定义DEBUG就执行 printf("no define"); #endif