文章目录
前言一,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.cint g_val = ;//test.cint main(){printf("%d\n", g_val);return 0; }
观察执行结果:
A : 代码1正常打印 原因是 : 一个全局变量在整个工程的其他文件内能被使用。是因为全局变量具有外部链接属性。
Q:如果观察这段代码,我们还会和代码1一样打印出g_val的值吗?
//代码2//add.cstatic int g_val = ;//test.cint main(){printf("%d\n", g_val);return 0; }
我们看执行结果:
A :代码2在编译的时候会出现连接性错误,这是因为一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。当一个全局变量被static修饰的时候,这个变量的外部链接属性就变成了内部连接属性,使得这个全局变量只能在自己所在的源文件内部使用,其他文件不能再使用,static 修饰全局变量,让全局变量的外部链接属性变成了内部链接属性,作用域变小了 生命周期不变。
(3)修饰函数
Q : 我们接下来看这两段代码?请问代码会运行吗?
//代码1//add.cint Add(int x, int y) {return c+y; }
//test.cint main(){printf("%d\n", Add(2, 3));return 0;}
我们看运行结果:
A : 我们会发现,代码一正常运行,这是因为函数本来也是具有外部链接属性的
Q:那代码二还会正常运行吗?
//代码2//add.cstatic int Add(int x, int y) {return c+y; }//test.cint 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+Yint main() {//4*2+3printf("%d\n", 4 * ADD(2, 3));//执行结果:11return 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));//执行结果:20return 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;}
运行结果:
****正文结束****
———————————————————————————————————————————
总结
本节内容结束,由于本人技术水平有限,若各位大佬发现错误,还望各位读者及时纠正。