【简单地过一遍C语言基础部分】所有知识点,点到为止!(仅一万多字)(四)

简介: 就在前几天,C语言入门到进阶部分的专栏——《维生素C语言》终于完成了。全文共计十八个章节并附带三张笔试练习篇,美中不足的是,第一章和第二章是以截图形式展现的。由于本人一开始是在有道云笔记上写的初稿,当时想方便省事(有道云排版个人感觉确实比较美观)就直接以截图的形式完成了第一章和第二章。本人考虑到因为是截图,不能复制文中出现的代码,不方便读者进行复制粘贴,所以我打算重新写一下第一章和第一章的内容,并且重新进行了排版。

九、关键字


0x00 常见关键字

📚 C语言提供的关键字:


1. C语言提供的,不能自己创建关键字


2. 关键字不能做变量名

a2044d1cb5fd760ec4ff725710167bed_20210924144607268.png


这里我们来简单地介绍几个:


💬 auto - 自动的


int main()
{
    {
        int a = 10; //自动创建,自动销毁的 - 自动变量
        // auto省略掉了
        auto int a = 10;
        // auto新的C语言中也有其它用法 - 暂时不考虑
    }
    return 0;
}

💬 register - 寄存关键字


int main()
{
    // 大量/频繁使用的数据,想放在寄存器中,提升效率
    register int num = 100; //建议num的值存放在寄存器中
    //是不是最终放到寄存器中是编译器说的算
    // 其实现在编辑器已经很聪明了,
    // 就算你不主动加register,它也会帮你存到寄存器中。
    return 0;
}

💬 typedef - 类型重命名


// 这种罗里吧嗦的变量我们可以把它重命名一下
typedef unsigned int u_int;
int main()
{
    unsigned int num = 100;
    u_int num2 = 100; //和上面是等价的
    return 0;
}

📚 static - 静态的


1. static修饰局部变量


2. static修饰全局变量


3. static修饰函数


💬 static修饰局部变量


函数中局部变量:


声明周期延长:该变量不随函数结束而结束


初始化:只在第一次调用该函数时进行初始化


记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值


存储位置:不会存储在栈上,放在数据段


void test() {
    static int a = 1; //不销毁,生命周期变长了
    a++;
    printf("%d ", a);
}
int main()
{
    int i = 0;
    while(i<10) {
        test();
        i++;
    }
    return 0;
}


🚩 运行结果: 2 3 4 5 6 7 8 9 10 11

5451fa99a7b908b8343930c7a4386d2a_20210924144830872.png


💬 static修饰全局变量


改变该变量的链接属性,让该变量具有文件作用域,即只能在当前文件中使用。


① Global.c:


static int g_val = 2021;
// static 修饰全局变量,
// 使得这个全局变量只能在自己所在的源文件(.c)内部可以使用
// 其他的源文件不能使用!
// 全局变量,在其他原文件内部可以被使用,是因为全局变量具有外部链接属性
// 但是被static修饰之后,就变成了内部链接属性,
// 其他的源文件就不能链接到这个静态的全局变量了!

② test.c:


extern int g_val;
int main()
{
  printf("%d\n", g_val);
  return 0;
}

🚩 运行结果: test.obj : error LNK2001: 无法解析的外部符号 _g_val

c96fddf81eab2a51da40e2e77e6baf83_20210924145009647.png


💬 static修饰函数


改变该函数的链接属性,让该函数具有文件作用域,即只能在当前文件中使用。


① Add.c:


//static修饰函数,
static int Add(int x, int y) {
  return x + y;
}

💬 test1.c:


extern int Add(int, int); //声明外部函数
int main()
{
  int a = 10;
  int b = 20;
  int sum = Add(a, b);
  printf("sum = %d\n", sum);
  return 0;
}

🚩 运行结果:


test.obj : error LNK2019: 无法解析的外部符号 _Add,该符号在函数 _main 中被引用

fc42b30828b9ec67ca668cdcda541939_20210924145142931.png


0x01 define

📚 define 是一个预处理指令:


1. define 定义标识符常量


2. define 定义宏


💬 define 定义标识符常量:


#define MAX 1000
int main()
{
    printf("%d\n", MAX);
    return 0;
}

💬 define 定义宏:


#define ADD(X, Y) X+Y
#define ADD1(X, Y) ((X)+(Y))
int main()
{
    printf("%d\n", 4*ADD(2, 3));
    //             4*2+3 = 11
    printf("%d\n", 4*ADD1(2, 3));
    //             4*(2+3) = 20
    return 0;
}

十、指针初探


0x00 指针介绍

❓ 什么是指针?


指针就是地址,地址就是指针。


指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。

457d2ef79c86ad08953e2469e9394b5e_20210924145439953.png

💬 变量都有地址,取出变量的地址如下:

int main()
{
    int a = 10; // a在内存中要分配空间 - 4个字节
    &a; // 取出num的地址
    printf("%p\n", &a); //%p - 以地址的形式打印
    return 0;
}

🚩 打印出来的是a的地址

e4ba72e849679eb60a7f6a58e2f9b7ff_20210924145528648.png


💬 定义指针变量,存储地址


* 说明 pa 是指针变量


int 说明 pa 执行的对象是 int 类型的


int main()
{
    int a = 10;
    int* pa = &a; // pa是用来存放地址的,在C语言中叫pa的是指针变量
    char ch = 'w';
    char* pc = &ch;
    return 0;
}

0x01 解引用操作

如果把定义指针理解为包装成快递,那么“解引用操作”就可以理解为是拆包裹


拆出来的值就是那个变量的值,甚至还可以通过“解引用”来修改它的值。


💬 解引用操作用法:


int main()
{
    int a = 10;
    int* pa = &a;
    *pa = 20; // * 解引用操作   *pa就是通过pa里边的地址,找到a
    printf("%d\n", a); //20
    return 0;
}

0x02 指针的大小

📚 指针的大小


“指针的大小是相同的”


❓ 为什么相同?


“因为指针是用来存放地址的,指针需要多大空间,取决于地址的存储需要多大空间”


📺 指针是一种复合数据类型,指针变量内容是一个地址,因此一个指针可以表示该系统的整个地址集合,故按照32位编译代码,指针占4个字节,按照64位编译代码,指针占8个字节(注意:不是64位系统一定占8个字节,关键是要按照64位方式编译)。


32位 - 32bit - 4byte


64位 - 64bit - 8byte


💬 sizeof 计算指针的大小:


int main()
{
    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(long*));
    printf("%d\n", sizeof(long long*));
    printf("%d\n", sizeof(float*));
    printf("%d\n", sizeof(double*));
    return 0;
}

32位下都是 4         64位下都是 8


十一、结构体


0x00 什么是结构体

📚 结构体可以让C语言创建出新的类型


“结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂的类型”


💬 使用结构体描述学生 / 描述书:


// 创建一个学生的类型
struct Stu {
    char name[20]; // 姓名
    int age; // 年龄
    double score; // 分数
};  // ← 不要忘了加分号
// 创建一个书的类型
struct Book {
    char name[20];
    float price;
    char id[30];
};

💬 结构体的初始化:


点操作符和箭头操作符


. 结构体变量.成员


-> 结构体指针->成员


struct Stu {
    char name[20]; // 姓名
    int age; // 年龄
    double score; // 分数
};
struct Book {
    char name[20];
    float price;
    char id[30];
};
int main()
{
    struct Stu s = {"张三", 20, 85.5}; // 结构体的创建和初始化
    // 点操作符
    printf("1: %s %d %lf\n", s.name, s.age, s.score);
    struct Stu* ps = &s;
    printf("2: %s %d %lf\n", (*ps).name, (*ps).age, (*ps).score); // ❎ 可以但不推荐
    // 箭头操作符
    printf("3: %s %d %lf\n", ps->name, ps->age, ps->score); // ✅ 推荐
    return 0;
}
相关文章
|
7月前
|
C语言
C语言初阶⑧(结构体)知识点和笔试题
C语言初阶⑧(结构体)知识点和笔试题
83 0
|
2月前
|
C语言
C语言学习笔记-知识点总结上
C语言学习笔记-知识点总结上
99 1
|
7月前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
57 0
|
7月前
|
存储 编译器 C语言
C语言初阶⑦(指针初阶)知识点+笔试题(上)
C语言初阶⑦(指针初阶)知识点+笔试题
52 0
|
7月前
|
算法 程序员 编译器
C语言初阶③(函数)知识点+编程作业(递归模拟strlen,pow)
C语言初阶③(函数)知识点+编程作业(递归模拟strlen,pow)
55 0
|
5月前
|
存储 编译器 C语言
|
6月前
|
编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
56 3
|
6月前
|
存储 编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
45 1
|
5月前
|
前端开发 C语言
C语言08----注释扩展知识点,注释快捷键:ctrl+k,ctrl + C,取消快捷键 ctrl + K,ctrl + U
C语言08----注释扩展知识点,注释快捷键:ctrl+k,ctrl + C,取消快捷键 ctrl + K,ctrl + U
|
6月前
|
C语言
C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)
C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)