[C语言]static关键字--#define 定义常量和宏--初识指针--初识C语言(四)

文章目录

  • 前言
  • 一,static关键字
  • 二,#define 定义常量和宏
  • 三,初识指针
  • 总结






前言

本节主要记录初识C语言第四节内容。

内容包括:static关键字------#define 定义常量和宏---------初识别指针

———————————————————————————————————————————                                                                     ****正文开始****

一,static关键字

static--静态的

在C语言中:
static是用来修饰变量和函数的
1. 修饰局部变量-称为静态局部变量
2. 修饰全局变量-称为静态全局变量
3. 修饰函数-称为静态函数

(1)修饰局部变量

Q : 首先我们先看这段代码,它的执行结果是什么?

void test() {
	int a = 1;
	a++;
	printf("%d\n", a);
}
int main(){
	int i = 0;
	while (i < 10) {
		test();      
		i++;
	}
	return 0;
}

Q:是10个2 还是 2-11呢?

我们看演示结果:

A:在这里我们可以看到结果是10个2,为什么是10个2呢?

原因是在这里a是局部变量,作用域在test函数内部,出了自己的作用域会销毁,所以导致每一次代码走到test函数中a的起始值都是int 定义的1 ,而不会随着a++累加,所以每次输出结果都是2。

Q : 我们再看这段代码,它的执行结果是什么?

void test() {
	static int a = 1;
	a++;
	printf("%d\n", a);
}
int main(){
	int i = 0;
	while (i < 10) {
		test();  
		i++;
	}
	return 0;
}

Q:我们可以发现这段代码和上一个代码只是在a前加了一个static,那么这段代码的执行结果10个2 还是 2-11呢?

我们看演示结果:

A:     在这里我们可以看到结果是2 -11,为什么呢?我们首先可以确定,一定是这个static起了作用,我们可以看到他的作用仿佛是让a可以累加,不会每一次执行后被销毁。

          所以这里我们了解到static的第一个作用,当static作用在局部变量时:a本来是局部变量  static 修饰局部变量的时候,其实改变了变量的存储类型(栈区存储->静态区),所以使得这个静态的局部变量出了自己的作用域也不会销毁 其实相当于改变了这个局部变量的生命周期,不销毁 作用域是test函数  生命周期变成函数的生命周期。

拓展了解:  内存是一块比较大的存储空间,在使用内存时会划分不同的功能区域,在学习编程语言的时候: 栈区:   局部变量
                     堆区:动态内存分配(malloc,free,calloc,realloc)
                 静态区:   存全局变量 和 static修饰的静态变量

所以执行结果是:2 3 4 5 6 7 8 9 10 11

(2)修饰全局变量

Q : 观察下列代码,我们会打印出g_val的值吗? 

//代码1
//add.c
int g_val = 2021;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0; }

观察执行结果:

A : 代码1正常打印 原因是 : 一个全局变量在整个工程的其他文件内能被使用。是因为全局变量具有外部链接属性。    

Q:如果观察这段代码,我们还会和代码1一样打印出g_val的值吗? 

//代码2
//add.c
static int g_val = 2021;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0; }

我们看执行结果:

 A :代码2在编译的时候会出现连接性错误,这是因为 一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。当一个全局变量被static修饰的时候,这个变量的外部链接属性就变成了内部连接属性,使得这个全局变量只能在自己所在的源文件内部使用,其他文件不能再使用,static 修饰全局变量,让全局变量的外部链接属性变成了内部链接属性,作用域变小了  生命周期不变。 

(3)修饰函数

Q : 我们接下来看这两段代码?请问代码会运行吗?

//代码1
//add.c
int Add(int x, int y) {
    return c+y; }
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

我们看运行结果:

 A : 我们会发现,代码一正常运行,这是因为函数本来也是具有外部链接属性的

Q:那代码二还会正常运行吗?

//代码2
//add.c
static int Add(int x, int y) {
    return c+y; }

//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0; }

运行结果发现:

A : 代码2在编译的时候会出现连接性错误, static修饰函数的时候,函数本来也是具有外部链接属性的,被static修饰的时候,就变成了内部链接属性。这个函数只能在自己所在的源文件内部使用,不能再其他文件内部使用, 给我们感觉是改变了作用域。

本质上:static 是讲函数的外部链接属性变成了内部链接属性!(和static修饰全局变量一样!)

二,#define 定义常量和宏

define 是一个预处理指令

(1)#define 定义标识符常量

#define 定义标识符常量
#define M 100
#define STR "hehe"
int main() {
	printf("%d\n", M);
	printf("%s\n", STR);
	return 0;
}

  (2)#define 定义宏

#define ADD(X,Y) ((X)+(Y))
int main() {
	int a = 10;
	int b = 20;
	int ret = ADD(a, b);
	printf("%d\n", ret);

	return 0;
}

Q :我们观察这段代码,他的执行结果是多少?

#define ADD(X,Y) X+Y
int main() {
	//4*2+3
	printf("%d\n", 4 * ADD(2, 3));//执行结果:11
	return 0;
}

A:他的执行结果是11 ----->  4 * 2 + 3 

Q:那么在观察这段代码?

#define ADD(X,Y) ((X)+(Y))
int main() {
	               //4*(2+3)
	printf("%d\n", 4*ADD(2, 3));//执行结果:20
	return 0;
}

这段代码的执行结果是:20  -----> 4 * ( 2 + 3 )

这是因为宏的参数是替换的。

三,初识指针

我们知道一个内存单元是一个字节  然后分配地址,一个内存单元 byte。

     &        取地址操作符
     %p     是以地址的形式打印

int      a =   10  ;   a要在内存中开辟空间

int    * p =  &a ;   p 就是一个指针变量   int是说明,

* p  --->      *  解引用操作符号

//指针:
int main() {

	int a = 10;// a 在内存中要分配空间 - 4个字节
	printf("%p\n",&a );//   %p专门用来打印地址
    int * pa = &a;//pa是用来存放地址的,在C语言中叫是指针变量
	// * 说明 pa 是指针变量
	//int 说明 pa 指向的对象是int类型的
 
	char ch = 'w';
	char * pc = &ch;

	return 0;
}
地址   ==  指针
地址是放在指针变量中

记录两个问题 : 

Q1 : 给定秒数 seconds ,把秒转化成小时、分钟和秒。

输入描述:

一行,包括一个整数,即给定的秒数。

输出描述:

一行,包含三个整数,依次为输入整数对应的小时数、分钟数和秒数(可能为零),中间用一个空格隔开。

实现代码:

int main() {
    int seconds = 0;
    scanf("%d", &seconds);
    int h = seconds / (60 * 60);
    int m = seconds / 60 - h * 60;
    int s = (seconds % 3600) % 60;
    printf("%d %d %d", h, m, s);
    return 0;
}

运行结果:

Q2 : 将一个四位数,反向输出。

输入描述:

一行,输入一个整数n(1000 <= n <= 9999)。

输出描述:

针对每组输入,反向输出对应四位数。

实现代码:

#include <stdio.h>
int main(){
    int x = 0;
    scanf("%d",&x);
    int a1 = x /1000;
    int b1 = x /100 - a1*10;
    int c1 = x /10 - a1*100 - b1*10;
    int d1 = x % 10;
    printf("%d%d%d%d",d1,c1,b1,a1);
    
    return 0;
}

运行结果:

                                                                        ****正文结束****

———————————————————————————————————————————


总结

本节内容结束,由于本人技术水平有限,若各位大佬发现错误,还望各位读者及时纠正。

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白又菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值