【C语言进阶】 带你玩转指针

news2024/11/25 6:36:41

指针进阶

  • 一、字符指针
  • 二、指针数组
  • 三、数组指针
    • 3.1:数组指针的使用
  • 四、数组参数、指针参数
    • 4.1:一维数组传参
    • 4.2:二维数组传参
    • 4.3:一级指针传参:
    • 4.4:二级指针传参:
  • 五:函数指针

一、字符指针

一般使用:

int main()
{
	char ch = 'w';
	char* pc = &ch;
	return 0;
}

在这里插入图片描述

进阶使用:

int main()
{
	const char* p = "abcd";//字符串常量的值是首字符的地址,
	//由于p指向的是常量字符串,所以*p解引用的时候不能改变这个字符串,所以前面用const来修饰
	printf("%s\n", p);
	//打印字符串只需要知道字符串首字符的地址,然后就会一直往后打印直到遇到'\0'为止
	
	//如果这里没有const修饰,通过解引用修改字符串常量程序会崩溃
	/*char* p = "abcd";
	*p='wcvb';
	printf("%s\n", p);*/
	//这三段代码执行后,虽然程序不会报错,但是会崩溃

	//加了const修饰后,再通过解引p用去改变字符串常量程序就会报错
	//*p = "dvcb";此时程序报错
	
	return 0;
}

经典例题:

//一个例题:
int main()
{
    char str1[] = "hello word.";
    char str2[] = "hello word.";
    //这两段代码执行后会在内存中创建两个数组,这两个数组有各自的空间

    const char* str3 = "hello word.";//字符常量一般是放在内存中的只读常量区
    const char* str4 = "hello word.";
    //"hello word."是一个常量字符串,永远不可能被修改掉,所以就没有必要创建两份,大家都共用这一份
    //str3 和 str4里面存的都是 'h'的地址
   
    if (str1 == str2)//数组名表示的是首元素的地址,由于两个数组开辟了各自的空间,所以它们首元素的地址一定不相同
        printf("str1 and str2 are same\n");
    else
        printf("str1 and str2 are not same\n");


    if (str3 == str4)//str3 和 str4里面存的都是 'h'的地址,所以它们两个的值是相等的
        printf("str3 and str4 are same\n");
    else
        printf("str3 and str4 are not same\n");

    //因为str3 和 str4里面存的都是 'h'的地址,我们可以把这个地址打印出来
    //结果显示这两个地址是相同的
    printf("%p\n", str3);
    printf("%p\n", str4);

    return 0;
}
//结果:
str1 and str2 are not same
str3 and str4 are same
00C27BD8
00C27BD8

在这里插入图片描述

二、指针数组

 关于指针数组到底是指针还是数组?交给大家一个简单的方法:看后缀!这里的后缀是数组,就可以十分确定,指针数组其实就是数字。这里的指针我们可以看成是形容词,用来修饰数组的,就像整型数组:表示这个数组是用来存放整形数据的字符型数组:表示这个数组是用来存放字符型数据的。同理:指针数组就表示这个数组是用来存放指针(地址)的

字符型指针数组:

//指针数组
int main()
{
	const char* arr[4] = {"abcd","bcde","nmjh","lkju"};
	//这就是字符型指针数组,这有一个叫arr的数组,它可以存放4个元素,每个元素都是 字符指针(存放的就是字符的地址)
	//数组中的4个元素都存的是字符串常量的首字符地址,由于指向的是字符串常量,不可被修改,所以加上const修饰

	//打印出首元素的地址,发现字符串常量在内存中不是连续存放的
	/*printf("%p\n", "abcd");
	printf("%p\n", "bcde");
	printf("%p\n", "nmjk");
	printf("%p\n", "lkju");
	printf("\n");*/

	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("%s\n", arr[i]);//调用数组中的元素
	}

	return 0;
}

在这里插入图片描述

int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组

整型指针数组:

//整型指针数组
//这里有一个数组,里面存的都是整型指针(整形的地址)
int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[5] = { 6,5,4,3,2 };
	int arr3[5] = { 10,9,1,2,5 };
	//创建三个整型指针

	int* arr[3] = { arr1,arr2,arr3 };//数组名表示首元素地址
	//这里有一个数组arr,它能够存储三个元素,每一个元素的类型都是整型指针(int*)(整形的地址)
	//arr1 - 1的地址
	//arr2 - 6的地址
	//arr3 - 10的地址

	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			//printf("%d ", arr[i][j]);
			printf("%d ", *(arr[i] + j));//arr[i]拿到的是数组首元素的地址,那再加j,就是跳过j个整型,就可以访问数组中的其他元素了。
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

三、数组指针

数组指针的后缀是指针,那就说明数组指针本质上是指针,比如整型指针(int*):表示这个指针变量里面存放的是一个整型变量的地址,它指向一个整型变量字符指针(char*):表示这个指针变量里面存放的是一个字符型变量的地址,它指向一个字符变量。同理:那数组指针一定是一个指向数组的指针,换言之,这个指针变量里面存放的是数组的地址

//数组指针
int main()
{
	char ch = 'w';
	char* pc = &ch;//pc是字符指针,类型是:char*
	//这里的*交代pc是一个指针变量,char表示它指向指针

	int num = 10;
	int* pi = &num;//pi是整型指针,类型是int*
	//这里的*交代pi是一个指针变量,int表示它指向指针

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//arr的类型是int [10],如果有一个指针变量指向它,那指针变量的类型应该也是这样
	int(*pa)[10]=&arr;//&arr取到的是整个数组的地址,pa是数组指针,类型是:int(*)[10]
	//这里的*交代pa是一个指针变量,int [10]表示它指向一个类型为int [10]的数组

	//int(*pa)[10] = arr;//这种写法是错误的,arr是数组首元素的地址,也就是1的地址,1是int型,int型的地址需要用int*来接收才对


	return 0;
}

3.1:数组指针的使用

在一维数组中的使用:

//数组指针的使用
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	常规打印数组的方式
	//int* p = arr;//拿到首元素地址
	//int i = 0;
	//for (i = 0; i < 10; i++)
	//{
	//	//printf("%d ", *(p + i));//(p + i)就是偏移过i个元素,第i个元素的地址,然后解引用
	//	printf("%d ", p[i]);//通过首元素地址+下标的方式来打印
	//}

	//利用数组指针来打印
	int(*p)[10] = &arr;//拿到整个数组的地址
	printf("%p\n", p);
	printf("%p\n", (*p));
	printf("%p\n", &arr[0]);
	//三者打印出来的数据完全相同,都是首元素的地址

	printf("\n");

	printf("%p\n", p+1);//p+1跳过了整个数组,也就是40个字节
	printf("%p\n", (*p)+1);//(*p)+1只跳过了首元素,也就是4个字节
	printf("%p\n", &arr[0]+1);//&arr[0]+1也只跳过了首元素,也就是4个字节
	//这说明对数组指针解引用得到的是该指针所指向数组的首元素的地址
	//这一点就和以前有所不同
	//整型指针解引用得到的是一个整型变量
	//字符指针解引用得到的是一个字符变量
	//这里的数组指针解引用得到的是一个地址


	//有了上面的分析,我们就可以利用数组指针来打印数组了
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(*p + i));//*p得到的是首元素的地址,+i表示第i个元素的地址,然后再解引用
		printf("%d ", (*p)[i]);//既然(*p)得到的是数组首元素的地址,那就还可以通过:数组首元素地址+下标 的方式去访问数组中的每一个元素
	}

	return 0;
}

 通过上面的代码不难发现:数组指针解引用得到的该指针所指向数组的首元素的地址,这一点和其他类型的指针有所不同。通过:*p = *(&arr) = arr 也不难发现,*p最终的结果是数组名,数组名又表示首元素地址,所以数组指针解引用得到的是首元素地址

在二维数组中的使用:
 这里主要得知道:二维数组的数组名也表示首元素地址,二维数组arr首元素是二维数组中第一行那个一维数组arr[0],所以二维数组名就表示&arr[0],得到一个数组的地址

//数组指针在二维数组中的使用
void print1(int arr[3][4], int r, int l)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < l; j++)
		{
			printf("%d ", arr[i][j]);//普通打印方式
		}
		printf("\n");
	}
}

void print2(int(*p)[4],int r,int l)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < l; j++)
		{
			//printf("%d ",(*(p+i))[j]);//这里的p存放的第一行这个一位数组的地址,是一个数组指针,所以:p+i 会跳过i个数组得到第i个数组的地址,然后再对数组地址解引用得到数组首元素的地址,然后通过 数组首元素的地址+下标的方式进行访问
			printf("%d ", p[i][j]);//既然p是二维数组首元素第一行一维数组的地址,那就可以通过 首元素地址+下标i 的方式去访问二维数组第i个元素,也就是第i行一位数组的首地址
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][4] = { {1,2,3,4},{5,4,3,2},{8,9,6,7} };//创建一个二维数组
	//print1(arr, 3, 4);
	print2(arr, 3, 4);
	//printf("%p\n", arr);
	//printf("%p\n", &arr[0][0]);
	//printf("%p\n", &(arr[0]));//arr[0]是二维数组中第一行那个一维数组的数组名,&(arr[0])就是取那个一维数组的地址
	三者打印结果一样,都是arr[0][0]的地址

	//printf("\n");

	//printf("%p\n", arr+1);//跳过16个字节,也就是二维数组的一行元素
	//printf("%p\n", &arr[0][0]+1);//跳过4个字节,也就是一个整型
	//printf("%p\n", &(arr[0])+1);//跳过16个字节,也就是二维数组的一行元素
	结果表明二维数组的数组名确实表示首元素的地址,但是二维数组中的首元素是第一行那个一维数组

	return 0;
}

在这里插入图片描述
看看下面代码分别是什么意思:

int arr[5];//arr是一个整型数组,可以存储5个元素
int *parr1[10];//首先parr1先和[10]结合,说明parr1是一个数组,可以存储10个元素,数组里面存储的元素类型是int*,所以parr1是一个整型指针数组
int (*parr2)[10];//首先parr2先和*结合,说明parr2是一个指针,指向的数据类型是 int [10],这是一个可以存储10个元素的整型数组,所以parr2是一个数组指针
int (*parr3[10])[5];//首先parr3先和[10]结合,说明parr3是一个可以存储10个元素的数组,这个数组里面存的元素类型是:int(*)[5],也就是数组指针类型的数据,所以parr3是一个数组指针数组

int (*parr3[10])[5];详解:

在这里插入图片描述

四、数组参数、指针参数

4.1:一维数组传参

普通一维数组传参:

//普通一维数组传参

void test(int arr[])//形参用数组接收,可以不写数组大小
{}
void test(int arr[10])//形参用数组接收,理所当然
{}
void test(int* arr)//数组名是首元素地址,首元素是一个整型,所以用一个整型指针接收也可以
{}

int main()
{
	int arr[10] = {0};
	text(arr);//参数是一维数组名,表示首元素地址
	return 0;
}

一维指针数组:

//一维指针数组
void test2(int* arr[20])//形参用对应类型的数组来接收理所应当
{}
void test2(int* arr[])//形参用对应的数组接收,可以省略数组元素个数
{}
void test2(int** arr)//数组名表示首元素地址,整型指针数组的首元素是一个整型指针,那首元素的地址就是一个指针的地址,指针的地址就是二级指针,所以形参用一个二级指针来接收
{}

int main()
{
	int *arr[20] = { 0 };
	text(arr);//参数是一维数组名,表示首元素地址
	return 0;
}

4.2:二维数组传参

//二维数组传参
void text(int arr[3][5])//形参用对应类型的二维数组来接收,可行
{}
void text(int arr[][])//形参用对应类型的二维数组来接收,行数可以省略但是列数不可以省略
{}
void text(int arr[][5])形参用对应类型的二维数组来接收,行数可以省略但是列数不可以省略
{}
void text(int(*arr)[5])//数组名是首元素地址,二维数组的首元素是第一行那个一维数组arr[0],所以首元素的地址就是一个一维数组的地址,所以形参应该用一个数组指针来接收,这个数组类型是 int [5]
{}

//一些错误写法
void text(int *arr)//这里的形参本质上是一个一级整型指针,指向一个整型,而我们需要的是一个可以存储一维数组地址的数组指针,所以这样写肯定不行
{}
void text(int *arr[5])//这里的形参本质上是一个可以存放5个元素的一维数组,形参如果是数组的话应该是对应的二维数组,这里肯能也不对
{}
void text(int **arr)//这里的形参是一个二级指针,也就是用来存储指针的地址(一级指针的地址),而我们需要的形参是一个可以存放数组地址的变量,仅仅是一个一维指针,所以这里肯定也是错误的
{}

int main()
{
	int arr[3][5] = { 0 };
	test(arr);
	return 0;
}

4.3:一级指针传参:

//一级指针传参
void print(int* p, int sz)//一级指针作为函数的实参,形参也用一级指针来接收
{
	int i = 0;
	for(i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));//指针变量加上一个偏移量,因为这是一个整形指针,加i就跳过4*i个字节,这里也就是取第i个元素的地址,然后解引用来访问第i个元素
		printf("%d ", p[i]);//也可以通过首元素地址+下标的形式来访问数组元素
	}
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;//数组名是首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(p, sz);//一级指针p作为函数参数,传给函数
	return 0;
}

思考: 当一个函数的参数部分为一级指针的时候,函数能接收什么参数?

  • 一级指针变量
  • 一维数组的数组名
  • 变量的地址

4.4:二级指针传参:

//二级指针传参
void test(int **p)//形参直接用一个二级指针来接收
{
	printf("num=%d\n", **p);
}

int main()
{
	int n = 10;
	int* p = &n;
	int** pp = &p;
	test(pp);
	test(&p);
	return 0;
}

思考: 当一个函数的参数部分为二级指针的时候,函数能接收什么参数?

  • 二级指针变量
  • 一级指针的数组
  • 一维指针数组的数组名

五:函数指针

函数指针:就是指向函数的指针

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	printf("%p\n", &Add);
	//打印出来一个地址,说明&函数名,确实可以取出函数的地址

	//既然是地址那一定可以被存起来
	int(*p)(int, int) = &Add;//首先,&ADD得到的是一个地址,说明需要一个指针变量来存储,所以p先和*结合,说明p是指针变量,接着需要知道p这个指针所指向内容的类型,也就是这个函数的类型,函数的类型可以通过函数的声明看出来,去掉函数名剩下的就是函数类型,这里Add的函数类型为:int (int,int)
	int(*p)(int, int) = Add;
	//&函数名和函数名都是函数的地址
	//p 是一个存放函数地址的指针变量 - 函数指针
	
	//函数指针的使用
	int ret = (*p)(3, 2);//对p指针解引用得到对应的函数,然后调用它,进行传参
	int ret = p(3, 2);//这样写也是可以的,因为可以直接把Add传给p,说明Add和p是等价的,一般的函数调用就是直接通过Add函数名来调用,所以这里可以不用对p解引用,无论p前面有多少个*都无济于事
	printf("%d\n", ret);
	
	return 0;
}

注意:&函数名和函数名都是函数的地址

经典例题:

//练习1
int main()
{

	( *(void (*)())0 )();//这里:void (*)()是一个函数指针类型,指向一个没有参数,返回值为void类型的函数,这个类型被放在一个括号里,说明要进行强制类型转换,这里把0强制类型转换成(void (*)())型,此时0就成了一个地址,指向一个void ()型函数,然后再通过解引用找到这个函数,进行传参,当然这个函数没有参数,所以最后一个括号是空的
	//该代码是一次函数调用
	return 0;
}
//练习2
int main()
{
	void (*signal(int, void(*)(int))) (int);
	//signal是函数名,他有两个参数,一个是int型,一个是void(*)(int)函数指针类型,该函数指针指向一个参数为int,返回类型为void的函数
	//函数名和参数都有了,去掉函数名和参数部分剩下的就是函数的返回值类型了
	//这里signal函数的返回值类型是void(*)(int)
	//该代码是一次函数声明
	return 0;
}

//简化
typedef void(*pf_t)(int);//把void(*)(int)型重命名成pf_t,注意pf_t的位置

int main()
{
	pf_t signal(int, pf_t);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

直播 | StarRocks 联合腾讯云分享 EMR-StarRocks 的降本增效之路

极速湖仓&#xff08;Lakehouse&#xff09;是 StarRocks 构建极速统一新范式的核心支点。 用户无需将数据导入到 StarRocks 中&#xff0c;无需构建昂贵的数仓&#xff0c;即可实现亚秒级的查询速度&#xff0c;统一分析离线和实时数据&#xff0c;全面发挥湖仓架构的潜在优势…

让国外软件也害怕,4款国产黑科技软件,功能强大且实用

国外月亮不一定比国内圆&#xff0c;国外的软件也不一定比国内好&#xff0c;下面几款软件功能强大到离谱&#xff0c;甚至比国外同款软件更好用。 1、Dism 这是一款妥妥的良心电脑系统优化工具&#xff0c;虽然英文名字&#xff0c;却是由热爱软件的大学生开发&#xff0c;属于…

Android 使用dx/d8将jar转换为dex

前言 在 JDK1.8 之前我们可以通过 dx 工具将 jar 转为 dex。 为了能够支持 JDK1.8&#xff0c;目前 AGP 是通过在 D8/R8 将 class 文件编译成 dex 文件的过程中&#xff0c;对字节码进行转换来实现的&#xff0c;这个转换过程称为脱糖。 因此 JDK1.8 及以后我们需要使用 d8 工…

计算机网络笔记之物理层

文章目录比特、比特率&#xff0c;码元率&#xff08;波特率&#xff09;通信方式之单工、半双工和双工介质访问控制数据、信号、模拟信号、数字信号传输介质多模光纤和单模光纤光纤的优点无线传输卫星通信的特点参考计算机网络笔记之网络概论 物理层的主要功能是规定了接口的…

如何优化 order by 语句

order by 查询语句使用也是非常频繁&#xff0c;有时候数据量大了会发现排序查询很慢&#xff0c;本文就介绍一下 MySQL 是如何进行排序的&#xff0c;以及如何利用其原理来优化 order by 语句。 建立一张表&#xff1a; CREATE TABLE cc4 (id INT(11) NOT NULL,user_name VA…

reactHooks+TS:富文本braft-editor常见用法

react富文本braft-editor使用 阅读文档推荐&#xff1a;https://www.yuque.com/braft-editor/be、https://braft.margox.cn/demos/code-highlighter、 1、安装 # 使用npm安装 npm install braft-editor --save# 使用yarn安装 yarn add braft-editor2、基本使用 第一步&…

FGH60N60SMD 60A600V IGBT单管在工业逆变应用中的解决方案

场截止IGBT单管 60A600V FGH60N60SMD 采用新型场截止 IGBT 技术&#xff0c;为太阳能逆变器、UPS、焊接机、电信、ESS 和 PFC 等低导通和开关损耗至关重要的应用。 ONsemi安森美IGBT单管系列&#xff1a; FGH40N60SMD FGH60N60SMD FGH75T65SHD-F155 NGTB40N120FL2WG特性&…

基于pytorch的CREStereo立体匹配算法

文章目录前言一、CREStereo是什么&#xff1f;1.自适应群相关层局部特征注意力2D-1D转换局部搜索可变形的搜索窗口Group-wise相关性2.级联的网络3.叠加级联推理4.叠加级联推理损失函数二、基于pytorch的CREStereo立体匹配算法前言 CREStereo目前在middlebury上的排名第三&#…

Java高手速成 | Spring、JPA与Hibernate的整合

01、设置Spring的配置文件 在Spring的配置文件applicationContext.xml中&#xff0c;配置C3P0数据源、EntityManagerFactory和JpaTransactionManager等Bean组件。以下是applicationContext.xml文件的源程序。 /* applicationContext.xml */ <?xml version"1.0" …

【财务】FMS财务管理系统---审计流程

本文是电商系列的终结篇&#xff0c;笔者在本文介绍了审计流程及注意事项。 本篇是介绍财务审计的&#xff0c;作为电商系列的终结篇。后续计划去完成供应链后台的相关系统的梳理与学习&#xff0c;非常感谢朋友们在阅读过程中提出的问题与建议。 一、审计及流程 财务审计是每…

吴晓波年终秀原版PPT下载

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点2023年&#xff0c;如何科学制定年度规划&#xff1f;罗振宇2023年跨年演讲PPT原稿《底层逻辑》高清配图清华大学256页PPT元宇宙研究报告.pdf&#x…

nginx学习笔记2(小d课堂)

nginx目录文件讲解&#xff1a; 我们这里要去了解我们画红框了的这四个目录。 我们一般只用这两个文件&#xff0c;nginx.conf.default是nginx的默认模板。 我们先来看看这个默认模板&#xff1a; 这里面会有特别多的配置&#xff0c;我们后面的课会去学到。我们可能以后改哪个…

【实战篇】37 # 如何使用 QCharts 图表库绘制常用数据图表?

说明 【跟月影学可视化】学习笔记。 QCharts 图表库 QCharts 是一个基于 spritejs 封装的图表库&#xff0c;可以让用户以组件的形式组合出各种图表&#xff1a;https://www.qcharts.cn/#/home QCharts 图表的基本用法 最简单的方式是&#xff0c;直接通过 CDN&#xff0c;…

Mac 几款不错的文件管理工具

Default Folder X 文件快捷访问工具 Default Folder X V6.9d19 是一款 Mac 上的文件夹快捷访问工具&#xff0c;您可以访问您最近的&#xff0c;最喜欢的&#xff0c;并打开文件夹的默认文件夹X的工具栏右侧的内容。扩大你把鼠标移到他们的层次弹出菜单&#xff0c;让您浏览您…

【胖虎的逆向之路】动态加载和类加载机制详解

胖虎的逆向之路 —— 动态加载和类加载机制详解一、前言二、类的加载器1. 双亲委派模式2. Android 中的类加载机制1&#xff09;Android 基本类的预加载2&#xff09;Android类加载器层级关系及分析3&#xff09;BootClassLoader4&#xff09;Class文件加载5&#xff09;PathCl…

从 Redshift 迁移数据到 DolphinDB

AWS Redshift 是最早的云数据仓库之一&#xff0c;为用户提供完全托管的 PB 级云中数据仓库服务。用户可以使用标准 SQL 和现有的商业智能工具&#xff0c;经济高效地进行数据分析。但 AWS Redshift 上手难度较大&#xff0c;对知识储备要求较高&#xff0c;设计和优化相当复杂…

PCB设计中的屏蔽罩设计

屏蔽罩是一个合金金属罩&#xff0c;是减少显示器辐射至关重要的部件&#xff0c;应用在MID或VR产品中可以有效的减少模块与模块之间的相互干扰&#xff0c;如图3-54所示&#xff0c;常见于主控功能模块和电源模块及Wifi模块之间的隔离。图3-54 屏蔽罩的使用 01 屏蔽罩夹子一般…

前端沙箱浅析

前言 沙箱&#xff0c;即sandbox。 通常解释为&#xff1a;沙箱是一种安全机制&#xff0c;为运行中的程序提供隔离环境。常用于执行未经测试或者不受信任的程序或代码&#xff0c;它会为待执行的程序创建一个独立的执行环境&#xff0c;内部程序的执行不会影响外部程序的运行…

Go第 7 章:数组与切片

Go第 7 章&#xff1a;数组与切片 7.1 为什么需要数组 7.2 数组介绍 数组可以存放多个同一类型数据。数组也是一种数据类型&#xff0c;在 Go 中&#xff0c;数组是值类型。 7.3 数组的快速入门 我们使用数组的方法来解决养鸡场的问题. 7.4 数组定义和内存布局 对上图的总…

QA | 关于信号发生器的扫频功能,您了解多少?

在上期文章中&#xff0c;我们介绍了可编程信号发生器使用中的相关问题&#xff0c;那么关于便携式信号发生器的扫频功能您是否有很多问题呢&#xff0c;今天我们将围绕信号源扫频功能详细解答大家感兴趣的几个问题&#xff0c;快来看看吧&#xff01;Q1&#xff1a;信号源是否…