手写C语言之基本概念及编程技巧总结(05)

简介: 手写C语言之基本概念及编程技巧总结

关键字register

register—寄存器关键字


image.png

register int a = 10; // a是寄存器变量

1

register 是起到的是建议作用,“建议” 编译器将a放到寄存器中,不会真的放进去,它有自己的一套判断规则。


注意:不能对寄存器变量取地址


static关键词

static 修饰局部变量

C语言中,static是用来修饰变量和函数的


修饰局部变量---静态局部变量

修饰全局变量---静态全局变量

修饰函数---静态函数



#include<stdio.h>
void test()
{
  int a = 1;//局部变量a的作用域在test()中,当a出了作用域就被销毁了,下次调用test()时,又需要重新创建a
  a++;
  printf("%d ", a);
}
int main()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {
  test();
  }
  return 0;
}



猜一猜上面的结果是什么?


image.png

为什么会全部是2,想必我们在写这个函数的时候,我们需要打印出来的是2-10的数字吧!那么如何达到这个要求呢?我们就需要用到我们额static静态关键词了


只需要在函数内部加一个静态变量就可以



image.png

根据上述的结果推测出每一次调用test(),使用的a都是上一次函数调用时留下的a;第二次调用test()时,由于上次函数调用产生的a没有被销毁,所以不会再次创建a,直接跳到了下一步,a++


总而言之就是,计算机记住了上次的结果


注意:static修饰局部变量的时候,其实是改变了变量的存储类型,由栈区存储变成了静态区存储,从而使得静态的局部变量出了自己的作用域也不会被销毁,其实也就是相当于改变了这个变量的生命周期。


内存是一块比较大的空间,在使用内存的时候,会划分出不同的功能区域:栈区、堆区、静态区


static 修饰全局变量

//add.c文件
int g_val = 2018;//g_val是在add.c文件中定义的
//test.c文件
//如果想使用来自其他文件(外部文件)的全局变量,要先声明一下
extern int g_val;
//extern是一个关键字,专门用来声明外部符号的
int main()
{
  printf("%d\n", g_val);
  return 0;
}
//add.c文件
static int g_val = 2018;
//test.c文件
extern int g_val;
int main()
{
  printf("%d\n", g_val);
  return 0;
}

上面的两个代码只有一点点的不一样,但是最终的结果确实千差万别,最有一个代码会报错!


一个全局变量在整个工程中的其他子文件内部能被使用,是因为全局变量具有外部链接属性 ,什么叫外部链接属性,一个变量在一个文件中定义,但是在另一个文件中可以使用(访问)叫外部链接属性。


当一个全局变量被static修饰的时候,其外部链接属性就变成了内部连接属性;使得这个全局变量只能在只能在自己的源文件内部使用,其他文件不能再使用,因为它不再具有外部链接属性,从本质上来说就是:作用域变小了!


那么当然,局部变量只有内部连接属性


其次函数也具有外部链接属性,static修饰函数的时候,函数本来是具有外部链接属性的,但是被static修饰后,就变成了内部连接属性,导致这个函数只能在自己的源文件内部使用,给我们的感觉是改变了作用域。


定义常变量和宏

//define定义标识符常量
#define MAX 100
//define定义宏(宏和函数是非常相似的)
#define Add(x, y) ((x) + (y))


对于常变量我们知道,也就是不可修改的变量


相对于陌生的是,定义宏


#include 
#define  M(a,b,c)          a##b##c
int main(void){
  printf("the M(2,3,4) is %d\n",M(2,3,4));
 return 0;
}




运行结果是:the M(2,3,4) is 234


具体的,我们会在后面的文章进行详细的讲述的,这里只是简单的介绍一下关于宏的概念


image.png


比如我们需要在上面定义一个简单的公式宏,每一次调用的时候,就不用写复杂的公式了


#define  MAX( x, y )  ( ((x) > (y)) ? (x) : (y) )

#define  MIN( x, y )  ( ((x) < (y)) ? (x) : (y) )


传送门可以查看相关宏的知识


注意:本专栏将会从基础到入门再到精通,最后达到手写C语言的效果,要想手写C语言练得如火纯情,只有反复的练习才可以,这也是为什么前期的文章讲的很广泛,就是让我们的大脑对C语言的整体有一个大概的认识,这样在进入后续的深入学习才不会感觉知识晦涩难懂,脱节比较严重的情况!


相关文章
|
2月前
|
C语言
数据结构基础详解(C语言):图的基本概念_无向图_有向图_子图_生成树_生成森林_完全图
本文介绍了图的基本概念,包括图的定义、无向图与有向图、简单图与多重图等,并解释了顶点度、路径、连通性等相关术语。此外还讨论了子图、生成树、带权图及几种特殊形态的图,如完全图和树等。通过这些概念,读者可以更好地理解图论的基础知识。
|
3月前
|
存储 编译器 程序员
八:《初学C语言》— 函数的基本概念
【8月更文挑战第3天】本篇文章详细讲解了库函数与自定义函数的区别、函数的嵌套调用及链式访问、函数的声明和定义、static和extern等基础知识
34 1
八:《初学C语言》— 函数的基本概念
|
3月前
|
机器学习/深度学习 C语言
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
要保持最小的步数,每一次汉诺塔问题(无论是最初还是递归过程中的),如果此时初始柱盘子数为偶数,我们第一步是把最上面的盘子移动到中转柱,如果为奇数,我们第一步则是将其移动到目标柱。
76 0
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
|
3月前
|
存储 编译器 程序员
【C语言篇】C语言常见概念
编译时,注释会被替换成⼀个空格,所以min/* 这⾥是注释*/Value会变成min Value,⽽不是minValue。这是C99标准新增的语法。
40 0
|
5月前
|
IDE Unix 编译器
一:《初学C语言》— C语言常见概念
在本篇文章中,详细讲述了C语言的常见概念。意在能够让读者初步了解C语言,为后续C语言的学习做铺垫
126 5
一:《初学C语言》—  C语言常见概念
|
4月前
|
存储 Java 程序员
【C语言入门】C语言入门:探索编程世界的基础概念
【C语言入门】C语言入门:探索编程世界的基础概念
105 2
|
5月前
|
存储 算法 C语言
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
|
5月前
|
存储 自然语言处理 编译器
C语言常见概念
C语言常见概念
|
5月前
|
机器学习/深度学习 算法 C语言
详细介绍递归算法在 C 语言中的应用,包括递归的基本概念、特点、实现方法以及实际应用案例
【6月更文挑战第15天】递归算法在C语言中是强大力量的体现,通过函数调用自身解决复杂问题。递归涉及基本概念如自调用、终止条件及栈空间管理。在C中实现递归需定义递归函数,分解问题并设定停止条件。阶乘和斐波那契数列是经典应用示例,展示了递归的优雅与效率。然而,递归可能导致栈溢出,需注意优化。学习递归深化了对“分而治之”策略的理解。**
108 7
|
6月前
|
Java C语言 C++
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现(上)
从C语言到C++_28(红黑树RedBlackTree)概念+插入接口实现
52 4