IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言学习第七章——函数 -> 正文阅读

[C++知识库]C语言学习第七章——函数

宏定义
1.终止宏定义的作用域:#undef 标识符
2.带参宏定义:#define 宏名(参数表)字符串

#include<stdio.h>
#define A 2
#define B A+A 
#define C (A+A) 
#define D(a,b) a*b
#define E(a,b) (a)*(b)
int main(void){
	printf("%d,%d,%d\n",A,B*B,C*C);	//2,8,16  2+2*2+2=8 B只是简单的替换,不涉及计算 替换完后才是真的运行计算 
	printf("%d\n",D(2,3));	//6
	printf("%d\n",D(2,2+1));	//5 	2*2+1
	printf("%d\n",E(2,2+1));	//6
	return 0;
}

宏名之间重名的问题

#include<stdio.h>
#define A 2
void f(void){
	printf("%d\n",A);
}
#define A(a,b) a-b
void g(void){
	printf("%d\n",A(5,2));
}
int main(void){
	f();	//输出2
	g();	//输出3
	return 0;
}

undef终止宏的作用域

#include<stdio.h>
#define A 2
#define B(a,b) a+b
void f(void){
	printf("%d,%d\n",A,B(4,1));
}
#undef A
#undef B
int main(void){
	f();	//输出2,5
	//printf("%d,%d\n",A,B(4,1));	//error 因为此处不属于宏名A,B的作用域 
	return 0;
}
#include<stdio.h>
#define A 2
#define B(a,b) a+b
void f(void); 
#undef A
#undef B
int main(void){
	f();	//输出2,5
	//printf("%d,%d\n",A,B(4,1));	//error 因为此处不属于宏名A,B的作用域 
	return 0;
}
void f(void){
	//printf("%d,%d\n",A,B(4,1));		//error 因为此处不属于宏名A,B的作用域 
}

宏名与函数名重名

#include<stdio.h>
void F(int a){
	printf("%d",a);
} 
#define F(a) F(a);printf("haha")
int main(void){
	F(3);	//该句会被替换为 F(a);printf("haha");  输出 3haha 
	return 0;
}

放在宏名F之后报错:

#include<stdio.h>
#define F(a) F(a);printf("haha")
void F(int a){	//如果放在宏名F之后,该函数首部会被替换为void F(int a);printf("haha") 程序最终会报错  
	printf("%d",a);
} 
int main(void){
	F(3);	//该句会被替换为 F(a);printf("haha");  输出 3haha 
	return 0;
}

函数的指针

定义指向函数的指针变量的一般形式为:类型名(*指针变里名)(函数参数表列)

#include<stdio.h>
int max(int a,int b){
	return a>b?a:b;
}
int min(int a,int b){
	return a>b?b:a;
}
int main(void){
	int (*p)(int,int);	//p是一个函数的指针变量,可以用来指向函数类型为int,函数参数为两个整型的函数。p的类型为int(*) (int,int) 
	p = max;	//p指向了max函数
	printf("%d\n",(*p)(10,5));	//(*p)(10,5)等价于max(10,5) 
	p = min;
	printf("%d\n",p(10,5));	//(*p)(10,5)和p(10,5)等价 
	return 0;
}

auto自动变量和register寄存器变量

#include<stdio.h>
int main(void){
	auto int a=3;	//int a=3; 默认情况下a就是一个自动变量,所以auto可以不加。auto只能用于修饰局部变量。 
	for(int i=0;i<10000;++i)
		;
	 register int j=2;	//register只能修饰局部变量,但该变量不一定会成为寄存器变量,需要依编译系统决定,所以一般也不使用该关键词 
	return 0;
}

extern的用法和静态外部变量

用法一:

#include<stdio.h>
extern int A;	//extern 可以在本文件内扩展一个全局变量的作用域,extern只能修饰全局变量 
int main(void){
	printf("%d\n",A); 
	return 0;
}
int A = 10

用法二:
在1.cpp中

int A = 10;
static int B = 100;		//static修饰的全局变量称作静态外部变量,其他文件不可以通过它的变量名来引用该变量。 
int *p = &B;

在2.cpp中

#include<stdio.h>
extern int A;	//extern 可以将全局变量的作用域扩展到其他文件  
extern int B;
extern int *p;
int main(void){
	printf("%d\n",A); 
	//printf("%d\n",B); 	//error因为B是静态外部变量,不可以在其他文件中通过变量名来引用它 
	printf("%d\n",*p);		//可以通过指针 间接的引用其他文件中的静态全局变量 
	return 0;
}
static int A = 14;		//编译时遇到extern先在本文件中寻找其变量的定义,没找到会在连接的时候从其他文件中寻找其变量的定义 

在3.cpp中

int A = 99;		//error 因为1.cpp中已经有了一个名字为A的非静态的全局变量 

static局部变量-静态局部变量

//静态局部变量是在编译的时候赋初值,即只赋初值一次。不会随函数调用结束后其存储单元消失。 
//自动变量是在函数调用时赋初值的,调用一次,赋一次。调用结束后其存储单元就消失。 
#include<stdio.h>
int *p; 
void f(void){
	int i=10;
	static int j;	//如果定义静态局部变量的时候没有初始化,它将有一个默认值0
	printf("%d,%d\n",i++,j++); 
	p=&j;
} 
int main(void){
	//printf("%d\n",j); 	//error 因为j的作用域不在此 
	f();	//10,0
	f();	//10,1
	f();	//10,2
	printf("%d\n",*p); 	//3 	可以通过指针引用在其他函数中定义的静态局部变量 
	return 0;
}

内部函数和外部函数
在1.cpp中

#include<stdio.h>
extern void f(void);	//extern可以省略 
void g(void); 
extern void (*p)(void);
int main(void){
	f();
	//g();	//error如果想正常运行该语句,9函数要么定义在本文件中,要么是定义在其他文件中的外部函数。我们不能企图调用一个来自其他文件中定义的内部函数g 
	(*P)();		//可以通过函数的指针间接调用来自其他文件中定义的内部函数
	return 0;
}
static void f(void){	//函数声明先从本文件中寻找函数的定义,找不到,再从其他文件中寻找外部函数的定义
	printf("1111\n");
}

在2.cpp中

#include<stdio.h> 	//因为f函数要用到printf函数 所以这里需要把stdio.h这个头文件包含进来,就相当于在该句加了printf的函数声明。在程序连接的时候会从库里找printf的函数定义 
static void g(void){	//在定义函数的时候在函数的首部加static代表这个函数是内部函数,其特点是其他文件不可以通过它的函数名来调用它
	printf("g函数运行\n");
} 
void (*p)(void)=g; 
extern void f(void){	//在定义函数的时候在函数的首部加extern代表这个函数是外部函数,extern 其实可以省略不写。外部函数可以被其他文件通过它的函数名来使用它 
	printf("haha\n");
} 

在3.cpp中

#include<stdio.h>
/*		error  因为2.cpp中已经有了一个重名的外部函数f 
void f(void){
	printf("haha\n");
} */

变量的存储方式和生存期
1.变量的存在时间即生存期,在程序运行的整个过程中都存在的变量是在内存的静态存储区存放的;有的变量则是在调用其所在函数时才临时分配存储单元,调用结束后该存储单元被释放,这种变量是存放在内存的动态存储区的。

2.每一个变量和函数都有数据类型和数据的存储类型。
在这里插入图片描述
注:建立储存空间的声明是定义声明(如: int a;),不需要建立储存空间的声明是引用声明(如:extern int a;)
undef,extern和函数声明注意的小知识点

#include<stdio.h>
#undef AB
#undef AB 	//可以多次终止同一个宏名的作用域,即使这个宏名没有被定义
extern int a;
extern int a;	//可以多次扩展同一个全局变量的作用域,即使这个变量没有被定义
void f(void);
void f(void);	//可以多次扩展同一个函数的作用域,即使这个函数没有被定义
int main(void){
	
	return 0;
}

递归
在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为递归调用。

递归求5的阶乘

#include<stdio.h>
int f(int a){
	if(a==1||a==0)
		return 1;
	else if(a>1)
		return a*f(a-1);
	else
		return -1;
}
int main(void){
	printf("%d\n",f(5));
	return 0;
}

递归求汉诺塔

#include<stdio.h>
void f(char a,char b){
	printf("从%c柱上往%c柱上挪动一个圆盘\n",a,b);
}
void g(int i,char a,char b,char c){
	if(i==2){
		f(a,b);
		f(a,c);
		f(b,c);
	}
	else if(i>2){
		g(i-1,a,c,b);
		f(a,c);
		g(i-1,b,a,c);
	}
}
int main(void){
	g(3,'A','B','C');
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-20 18:12:41  更:2021-11-20 18:14:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:00:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码