手写C语言之数组- *** 作符-关键词介绍及实战(04)

手写C语言之数组- *** 作符-关键词介绍及实战(04),第1张

目录
    • 数组
      • 数组的定义
      • 数组的下标
    • *** 作符
    • 常见关键字
      • 关键字typedef
    • 关键字register
    • static关键词
      • static 修饰局部变量
      • static 修饰全局变量
      • 定义常变量和宏
    • 每文一语

数组

什么是数组,在哪里可以用到数组?首先假设一个场景,假设你现在需要记录你的每次消费记录,每次消费都将你的消费记录存放到一个内存中,那么传统的基本语法还可以实现吗?显然有点有心无力的感觉!

C语言中给了数组的定义:一组相同类型元素的集合

数组的定义
int arr[10] = { 0 };//初始化数组
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素

这里对数组进行初始化,我们首先定义了10个空间对其进行初始化,那么也就是说这个数组里面有10个0。

数组的下标

数组的访问和Python的索引比较的类似,数组的每个元素都有一个下标,下标是从0开始的。


通过增加一行代码,就可以实现数组的变化,这里也是充分利用到数组的访问规则

这里只是简单的介绍数组的概念,至于深入的讲解,我们会在后续的文章中继续深入剖析其本质原理的。

*** 作符

算术 *** 作符

+ - * / %

简单的 *** 作符,对其进行加减乘除,需要注意的是这里的/,如果除数和被除数都是整型的那么返回是一个有很多的小数点的数字。

7/2=3.00000

如果是包含浮点数的数字,那么结果也会出现什么呢?

7/2.0=3.5

%:取模,也叫求余,一定要注意的是取模 *** 作符只能应用于整数哦,浮点数是不可以的,这点一定要注意。比如:7 % 2 = 1;(商3,余1)

移位 *** 作符

为什么叫移位 *** 作符呢?因为其作用于一个数的二进制位

>> <<

位 *** 作符

这里的“位” 指的是二进制位

按位与&:对应的二进制位有0,则为0,全1在为1;

按位或|:对应的二进制位有1,则为1,全0才为0;

按位异或^:对应的二进制位相同,则为0,相异才为1;

注意:对位 *** 作实际上是对存储在内存上的二进制位进行 *** 作的,然而整数在内存上存储的是其二进制的补码形式,所以对位 *** 作,也就是对二进制的补码进行的 *** 作。

& ^ |

赋值 *** 作符

= += -= *= /= &= ^= |= >>= <<=

单目 *** 作符

! 逻辑反 *** 作
- 负值
+ 正值
& 取地址
sizeof  *** 作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问 *** 作符(解引用 *** 作符)
(类型) 强制类型转换

关系 *** 作符

>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”

逻辑 *** 作符

&& 逻辑与
|| 逻辑或

条件 *** 作符

条件运算符,又称为三目运算符,表达式1为真,则计算表达式2的值,跳过表达式3。也就是说表达式2的结果就是整个表达式的结果;反之,若表达式1为假,跳过表达式2,直接计算表达式3的值,也就是说表达式3的结果就是整个表达式的结果。

exp1 ? exp2 : exp3

逗号表达式

注意:逗号表达式会从左向右依次计算,整个表达式的结果是最后一个表达式的结果

exp1, exp2, exp3, …expN

下标引用、函数调用和结构成员

[] () . ->
常见关键字
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 

define不是关键字

其次关键词不能自己创建,也不能作为变量名

关键字typedef

typedef 顾名思义就是类型定义,这里应该理解为类型的重命名。

typedef unsigned int uint_32;
/*由于unsigned int比较复杂,所以用typedef将它重命名为uint_32,
所以此时uint_32就是一个类型名,代表了unsigned int*/
关键字register

register—寄存器关键字

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

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

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

static关键词 static 修饰局部变量

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

修饰局部变量---静态局部变量
修饰全局变量---静态全局变量
修饰函数---静态函数
#include
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;
}

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

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

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

根据上述的结果推测出每一次调用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

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

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

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

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

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

每文一语

It’s impossible for me to listen to music while I’m studying !
it is difficult to the point impossibility for me to do listen to music while study hard !

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/717583.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存