1、初识C语言

1.1、第一个C语言程序

#include <stdio.h>  //#include 引用头文件  stdio.h 标准输出与输入,凡是使用打印输出或者输入一定要引用stdio.h

int main(void)
{
    printf("你好,C");  //打印输出到屏幕上
    return 0;
}


#计算两数之和
#include <stdio.h> 
int main(void)
{
    int i1,i2,sum;
    i1 = 2;
    i2 = 3;
    sum=i1+i 2;
    printf("sum=%d\n",sum);
    return 0;
}
转义字符 含义
\b 退格,将当前位置移到前一列
\f 换页,将当前位置移到下页开头
\n 换行,将当前位置移到下一行开头
\r 回车,将当前位置移到本行开头
\t 水平制表,跳到下一个Tab位置
\v 垂直制表
\\ 表示反斜杠本身(\)
\' 表示单引号(')
\" 表示双引号(")
\? 表示问号(?)
\0 表示空字符(NULL)
\ddd 1~3位八进制数所代表的任意字符
\xhh 1~2位十六进制数所代表的任意字符

1.2、变量与常量

变量 常量
在c语言运行过程中,需要把值存储在一个地方,方便下次直接拿出来使用,并且可以随时修改。 在c语言运行过程中,将值放入其中后,不能修改。
变量命名只能由英文字母(A-Z,a-z)、数字或者下划线组成。必须以英文字母或者下划线开头。区分大小写 常量命名一般用大写英文字母
数据类型 变量名 = 初始值 如 int i = 1 const 数据类型 常量名 = 值 const float PI=3.14<br />#define 常量名 值 #define PI 3.14
#include <stdio.h> 
#define PI 3.14
int main(void)
{
    int i1=2;
    /*
    const double PI = 3.14; */
    printf("PI=%lf",PI);
    return 0;

}

1.3、数据类型

image.png

1.4、关键字

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

2、分支与循环

2.1、分支结构

image.png

在程序运行过程中往往会遇到选择判断的,比如判断用户是否满18岁?

运算符 含义 优先级 举例 说明
! 逻辑非 !a 如果a为真,!a为假<br />如果a为假,!a为真
&& 逻辑与 a&&b 只要有一个为假,结果就为假<br />如果两个都为真,结果为真
|| 逻辑或 a||b 只要有一个为真,结果为真<br />如果两个都为假,结果为假

选择语句有if、switch

if运用于判断一个范围

#include <stdio.h> 
int main(void)
{
    int i;
    printf("你多少岁:");
    scanf("%d",&i);
    if (i >= 18) {
        printf("你是青年!");
    }
    else {
        printf("你是儿童");
    }
    return 0;
}

switch运用于判断一个确切的值

#include <stdio.h> 
int main(void)
{
    int i;
    printf("你多少岁:");
    scanf("%d",&i);
    switch (i) {
      case 20:
        printf("你是青年!");
        break;
      case 17:
        printf("你是不青年!");
        break;
      default:
          printf("什么都不是");
    }

    return 0;
}

2.2、循环结构

image.png 在程序运行过程中往往会去做一些重复的事情,这个时候就需要循环结构了。

循环语句有while、for

while运用于不知道要循环多少次的

#include <stdio.h> 
int main(void)
{
    int i=1,sum=0;
	while (i<=100)
	{
		sum = sum + i;
		i = i + 1;
	}
	printf("结果是:%d\n",sum);
    return 0;
}

for运用于知道循环的次数

#include <stdio.h> 
int main(void)
{
    

    for (int i = 0;i < 10;i++) {
        printf("jpl\n");
    }
    return 0;

}

3、数组

3.1、定义

数组用来存储同一类型的一组数据

3.2、使用

数组常与for循环语句结合使用

定义数组 :数据类型 数组名[长度] int a[6];

#include <stdio.h> 
int main(void)
{
    int a[] = {9,8,7,6,5,4,3,2,1,0};
    for (int i = 0;i < sizeof(a)/sizeof(int);i++) {
        printf("%d\n",a[i]);
    }
    return 0;
}

4、指针

4.1、定义

指针就是地址,变量存储在机器中的地址。

4.2、大小

在32位的机器上指针大小就是4个字节

在64位的机器上指针大小就是8个字节

4.3、使用

指针变量的定义

int *p;

指针数组的定义

int *a[6];

5、函数

5.1、定义

随着程序规模不断扩大,有一些代码重复、mian函数变得相当复杂,不易看懂。这个时候就需要我们去拆分main函数。按照功能将代码拆分出来,变成一个一个小模块。这些小模块就是函数

5.2、函数的分类

函数有官网给的函数,也有我们自己在写程序过程中定义的函数

//计算两数之和
#include <stdio.h> 

float cube(int x, int y) //函数的定义
{
    float result;
    result = x + y;
    return result;
}

int main(void)
{
    
    int x, y;
    int volume;
    printf("请输入x:\n");
    scanf("%d",&x);
    printf("请输入y:\n");
    scanf("%d", &y);
    volume = cube(x, y);
    printf("the volume of cube is:%d",volume);
    return 0;
}

5.3、形参与实参

函数定义时写的参数叫形参,实参就是调用函数时传进去的参数。当函数调用时,实参的值传给形参,形参只有函数被调用时才会分配内存,函数调用结束后,立即释放内存。

5.4、局部变量与全局变量

局部变量定义在函数内部的变量,只能在函数内部使用。

全局变量定义在函数之外的变量,在程序中可能多一个函数需要使用同一个变量,这个时候就可以定义全局变量

5.5、存储类型

auto 自动变量,在代码块中声明的变量默认的存储类型
register 寄存器变量,理论上是存放在CPU的寄存器中的,但因为一些原因,可能会被编辑器忽略,变成普通的自动变量。
static 修饰局部变量:局部变量初始化一次,直到程序终止,才会被销毁。<br />修饰全局变量:被修饰的变量的作用域在当前文件中,直到程序终止,才会被销毁。
extem 用于提供一个全局变量的引用,对所有程序文件可见。

5.6、内存管理

之前提到的定义变量、定义常量,其实就是向内存要一个存储空间,这个空间的大小必是由据储存类型来确定的。那么我想直接在内存要一个自定义的存储空间如何做呢?可以通过下面的方式来申请内存空间。

函数名 作用
malloc 申请动态内存空间
free 释放动态内存空间
calloc 申请并初始化一系列内存空间
realloc 重新分配内存空间

使用以上四个函数时需要引用stdlib.h这个头文件

//这个程序的意思是  使用malloc申请一块空间,然后用ptr指针指向它,随后将用户输入的数据存储在这块空间里,
#include <stdio.h> 
#include<stdlib.h>
int main(void)
{
    int *ptr;
    //void *malloc(size);  
    ptr = (int *)malloc(4);//malloc如果调用成功,返回void指针,它可以转换成任意数据类型,如果调用失败,返回NULL。
    if (ptr == NULL)
    {
        printf("分配内存失败!\n");
        exit(1);
    }
    printf("请输入一个整数:\n");
    scanf("%d", ptr);
    printf("你输入的整数是:%d\n", *ptr);
    free(ptr);//释放ptr指向的内存空间
    return 0;
}

malloc申请的空间,在不使用后,一定要用free释放空间。

如果出现第一次申请的内存空间不够,后面在去申请内存空间就很麻烦,因为无法保障malloc两次申请的空间是连续的,处理起来很麻烦。这个时候可以用realloc

#include<stdlib.h>
int main(void)
{
  。。。。。。
  void *realloc(ptr,size);   //将ptr指向的内存空间大小修改为size字节 
}
#include<stdlib.h>
int main(void)
{
  。。。。。。
  void *calloc(num,size);   //申请内存空间大小为size字节num个 
}

5.7、内存布局

image.png

代码段 存放程序执行代码的一块区域 数据段 存放已经初始化的全局变量和局部静态变量 BBS段 存放程序中未初始化的全局变量 堆 程序运行中被动态分配的内存区域,程序员手动申请。 栈 函数执行的内存区域,系统自动分配

6、结构体

6.1、定义

前面说了几个基本类型,但有时候面临的问题比较复杂,基本类型很难解决问题,就需要自己定义一个类型,这就是结构体

6.2、声明

struct  结构体名字
{
    结构体成员1;
    结构体成员2;
    结构体成员4;
}
示例
struct  People
{
    char name[20];
    int age;
    char sex;
}

6.3、示例

#include <stdio.h> 
struct  People
{
    char name[20];
    int age;
    char sex;
};
int main(void)
{
    struct People people;
    printf("请输入姓名:\n");
    scanf("%s",people.name);
    printf("请输入年龄:\n");
    scanf("%d", &people.age);
    printf("请输入性别:\n");
    scanf("%s", &people.sex);

    printf("\n======录入完毕======\n\n");
    printf("名字:%s\n",people.name);
    printf("年龄:%d\n", people.age);
    printf("性别:%s\n", &people.sex);
    return 0;

}

7、文件操作

7.1、文件的读写

7.1.1文件的打开模式

模式 描述
"r" 以只读模式打开一个文本文件,从头开始读取
"w" 以只写模式打开一个文本文件,从头开始写入,如果文件不存在则创建一个文件,如果文件存在,则写入内容覆盖原内容
"a" 以追加模式打开一个文本文件,从文件末尾追加内容,如果文件不存在,则创建新文件
"r+" 以读和写的模式打开一个文本文件,从文件头开始读取与写入,文件必须存在,写入时不会覆盖原有内容
"w+" 以读和写的模式打开一个文本文件,从文件头开始读取与写入,如果文件不存在,则创建新文件,写入时会覆盖原有内容
"a+" 以追加和读模式打开一个文本文件,如果文件不存在,则创建新文件,从头开始读取,从文件末尾追加内容
b 与上面6种模式均可结合("rb","wb","ab","r+b","w+b","a+b"),操作对象为二进制文件(图片、视频等)

普通文件在win系统上换行符为\r\n,unix(linux)换行符为\n,mac换行符为\r

//以只读的形式打开文件,并读取文件内容
#include <stdio.h> 
#include<stdlib.h>
int main(void)
{

    FILE* fp;
    int ch;
    if ((fp = fopen("D:\\1.txt", "r")) == NULL)
    {
        printf("打开文件失败!\n");
        exit(EXIT_FAILURE);
    }
    while ((ch = getc(fp)) != EOF) 
    {
        putchar(ch);
    }
    fclose(fp);
    return 0;

}
//向文件写入内容
#include <stdio.h> 
#include<stdlib.h>
int main(void)
{

    FILE* fp;
    int ch;
    if ((fp = fopen("D:\\1.txt", "w")) == NULL)
    {
        printf("打开文件失败!\n");
        exit(EXIT_FAILURE);
    }
    fputs("jpl\n",fp);
    fclose(fp);
    return 0;

}

7.2、I/O缓存区

文件并不是程序直接从设备中读取与写入的,他们中间有一个缓存区,读取与写入的数据会经过缓存区。当缓存区关闭或者写满时。数据才会到达设备或者程序

7.2.1、缓存模式

缓存区有两种模式:1、按数据块缓存,即填满缓存区才会进行实际的设备书写。2、按行缓存,即缓存区读取到换行符('\n'),就开始实际设备的读写。

8、Linux上运行c程

由于企业中c语言开发大多是在Linux上调式与运行的,在这里简单介绍一下,如何在Linux环境中运行c程序。Linux的内核基本上是有c语言编写的,c语言在Linux中很大的发挥空间。 我的linux版本为centos7 首先检查一下,系统上有没有gcc(c语言的编辑器)

//查看gcc信息
gcc -version
//安装gcc
yum -y install  gcc  gcc-c++  kernel-devel

编写程序 运行c语言程序

gcc  文件名.c  && ./a.out

image.png

由于c语言是直接运行在机器上的,所以操作系统对c语言的影响会比较大。在linux上运行的结果可能与在win上运行的结果有所偏差。