文章目录
前言
本节主要记录初识C语言第四节内容。
内容包括:static关键字------#define 定义常量和宏---------初识别指针
——————————————————————————————————————————— ****正文开始****
一,static关键字
static--静态的
(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;
}
运行结果:
****正文结束****
———————————————————————————————————————————
总结
本节内容结束,由于本人技术水平有限,若各位大佬发现错误,还望各位读者及时纠正。