首页 > 其他分享 >变量和作用域、指针

变量和作用域、指针

时间:2024-10-22 19:31:42浏览次数:7  
标签:arr 变量 作用域 存储 int num printf 指针

变量和作用域、指针

指针变量

指针变量只能用来记录地址数据,因为地址数据和普通数据的使用方法不同,所以指针变量和普通变量使用方法不同,指针变量的主要用途就是找到一个普通变量的存储区(老年机打电话找智能机)。只有当指针里记录了存储区的地址后才可以通过这个指针找到那个存储区

声明指针变量的时候需要在指针变量名称前加,如果一个指针记录了一个存储区的地址就可以认为他们之间实现了捆绑关系,当一个指针记录了某个存储区的地址后就可以在指针前使用 * 操作符找到捆绑的存储区。

声明指针时的类型名称用来表示指针适合与什么类型的存储区捆绑,可以在一条语句里声明多个类型的指针变量,这个时候必须在每个指针变量名称前单独加 *。没有捆绑的指针分为两种,一种叫做空指针,它固定记录空地址(NULL),这个地址的数值就是0 ;其他没有捆绑的指针都叫做野指针

程序里不可以出现野指针指针变量必须初始化,指针变量初始化的时候*没有参与赋值过程,指针和存储区的捆绑关系可以随着程序的执行不断变化。这种使用方法里可以把指针看作存储区的某种身份或者代表了存储区的某种特征。

指针和数组关系

如果一个指针和数组里的第一个存储区捆绑就可以通过这个指针找到数组里的每个存储区,地址数据可以参与如下计算过程。

地址 + 整数 地址 - 整数 地址 - 地址

地址加减整数n实际上加减的是n个捆绑存储区的大小,数组里第一个存储区的地址加下标可以得到下标对应存储区的地址,以下写法也可以用来表示数组里的存储区

*(arr + num)

其中arr是数组名称,num是下标,地址之间做减法结果是一个整数,这个整数表示两个地址之间包含的捆绑存储区个数。可以使用指针变量作为循环变量编写for循环依次处理数组里的每个存储区。

const关键字

声明指针变量的时候可以使用const关键字,声明指针变量的时候可以把const关键字写在类型名称前,不可以通过这种指针对捆绑存储区做赋值,但是可以对这种指针本身做赋值;声明指针变量的时候可以把const关键字写在指针变量名称前,可以通过这种指针对捆绑存储区做赋值,但是不可以对这种指针本身做赋值(这种用的少)。

void关键字

声明指针变量的时候可以使用void作为类型名称,这种指针可以叫做无类型指针,这种类型的指针可以和任意类型的存储区捆绑,无法通过无类型指针知道它捆绑存储区的类型,不应该在无类型指针前直接加*,也不应该对无类型指针进行加减整数的计算

必须先把无类型指针强制转换成有类型指针然后才能使用,所有跨函数使用存储区都是通过指针实现的,数组做形式参数的时候真正的形式参数就是一个指针,如果函数不会修改指针形式参数所捆绑存储区的内容就应该在声明指针形式参数的时候在类型名称前加const关键字。

无类型指针通常用来作为形式参数使用,采用无类型指针作为形式参数可以把任意类型的数据传递给被调用函数。

练习:编写函数把主函数里两个变量内容交换

/*
 *
 *主函数变量内容交换
 *
 *
 * */
#include<stdio.h>
void swap (int *p_num,int *p_num1){
	int tmp = *p_num;
	*p_num = *p_num1;
	*p_num1 = tmp;
}
int main (){
	int num = 3, num1 = 2;
	swap (&num ,&num1);
	printf("num =%d ,num1 = %d\n",num,num1);
	return 0;
}

被调用函数使用存储区的地址做返回值可以让调用函数使用被调用函数的存储区,被调用函数需要提供一个指针类型的存储区用来存放作为返回值的地址数据。不可以把非静态局部变量存储区的地址当返回值使用。

练习:编写函数从一个数组里找到最大数字所在的存储区并把这个存储区传递给调用函数。

/*
 *
 *指针练习
 *
 * */
#include<stdio.h>
int *max (const int *p_num,int size){
	const int *p_tmp = NULL,*p_max = NULL;
	for(p_tmp = p_num;p_tmp <= p_num + size -1;p_tmp++){
		if (!p_max){
			p_max = p_tmp;
		}
	    else {
			if (*p_tmp > *p_max){
				p_max = p_tmp;
			}
		}
	}
	return (int *)p_max;
}
int main (){
	int arr[] = {1,2,3,4,5};
	int *p_num = max(arr,5);
	printf("%d\n",*p_num);
	return 0;
}
点击查看代码
#if 0
/*
 *
 *指针声明
 *
 * */
#include<stdio.h>
int main (){
	int num = 0;
	int *p_num = NULL,*p_num1 = NULL; 		// 指针变量声明
	p_num = &num;
	*p_num = 10;
	printf("%d\n",num);
	return 0;
}


#elif 0
/*
 *
 *指针演示
 *
 * */

#include<stdio.h>
int main (){
	int arr[] = {1,2,3,4,5};
	int *p_num = arr;
	int num = 0;
	for (num = 0;num <= 4;num++){
		printf("%d ",arr[num]);
		printf("%d ",p_num[num]);
		printf("%d ",*(arr + num));
		printf("%d ",*(p_num + num));
	}
	printf("\n");
	return 0;
}
#elif 0
#include<stdio.h>
int main (){
	int arr[] = {1,2,3,4,5};
	printf("arr是%p\n",arr);
	printf("arr+2是%p\n",arr + 2);
	printf("&arr[2]是%p\n",&arr[2]);
	printf("arr-2是%p\n",arr - 2);
	printf("&arr[2]-arr是%ld\n",&arr[2] - arr);
	return 0;
}

#elif 0
/*
 *
 *指针演示
 * 
 * */
#include<stdio.h>
int main (){
	int arr[] = {1,2,3,4,5};
	int *p_tmp = NULL;
	for (p_tmp = arr;p_tmp <= arr + 4;p_tmp++){
		printf("%d",*p_tmp); 
	}
	printf("\n");
	return 0;
}

#elif 0
/*
 *
 *const
 *
 * */
#include<stdio.h>
int main (){
	int num = 0;
	const int *p_num = &num;
    int * const p_num1 = &num;
	//*p_num = 10;       //只读,错误
	p_num = NULL;
	*p_num1 = 10;
	p_num1 = NULL;
	return 0;
}
#elif 0
/*
 *
 *
 *无类型指针
 *
 * */
#include<stdio.h>
int main (){
	char ch = 'r';
	int num = 23;
	float fnum = 5.4f;
	void *p_v = &ch;
	printf("%c\n",*(char *)p_v);
	p_v = &fnum;
	printf("%g\n",*(float *)p_v);
	p_v = &num;
	printf("%d\n",*(int *)p_v);
	return 0;
}


#elif 0
/*
 *
 *指针形式参数
 *
 * */
#include<stdio.h>
void print (const int *p_num,int size){ 			//const为了告诉调用函数给的存储区内容不会修改
	int num = 0;
	for (num = 0;num <= size - 1;num++){
		printf("%d ",*(p_num + num));
	}
	printf("\n");
}
int main (){
	int arr[] = {1,2,3,4,5};
	print(arr,5);
	return 0;
}
#elif 0
/*
 *指针形式参数
 *
 * */
#include<stdio.h>
void print (const void *p_v,int type){
	if (!type){
		printf("%c\n",*(const char *)p_v);
	}
	else if (type == 1){
	printf("%d\n",*(const int *)p_v);
	}
	else if (type == 2){
		printf("%g\n",*(const float *)p_v);
	}
}
int main (){
	char ch = 'r';
	int num = 34;
	float fnum = 3.4f;
	print(&ch,0);
	print(&num,1);
	print(&fnum,2);
	return 0;
}

#elif 0
/*
 *
 *主函数变量内容交换
 *
 *
 * */
#include<stdio.h>
void swap (int *p_num,int *p_num1){
	int tmp = *p_num;
	*p_num = *p_num1;
	*p_num1 = tmp;
}
int main (){
	int num = 3, num1 = 2;
	swap (&num ,&num1);
	printf("num =%d ,num1 = %d\n",num,num1);
	return 0;
}
#elif 0
/*
 *
 *地址返回值演示
 *
 * */
#include<stdio.h>
/*int *read (void){
	static int num = 0;
	printf("请输入一数字");
	scanf("%d",&num);
	return &num;
}
*/

int *read (int *p_num){
	printf("请输入一数字");
	scanf("%d",p_num);
	return p_num;
}
int main (){
	//int *p_num = read();
	int num = 0;
	int *p_num  = read(&num);
	printf("%d\n",*p_num);
	return 0 ;
}
#elif 1
/*
 *
 *指针练习
 *
 * */
#include<stdio.h>
int *max (const int *p_num,int size){
	const int *p_tmp = NULL,*p_max = NULL;
	for(p_tmp = p_num;p_tmp <= p_num + size -1;p_tmp++){
		if (!p_max){
			p_max = p_tmp;
		}
	    else {
			if (*p_tmp > *p_max){
				p_max = p_tmp;
			}
		}
	}
	return (int *)p_max;
}
int main (){
	int arr[] = {1,2,3,4,5};
	int *p_num = max(arr,5);
	printf("%d\n",*p_num);
	return 0;
}
#endif 


标签:arr,变量,作用域,存储,int,num,printf,指针
From: https://www.cnblogs.com/GQH1000/p/18493590

相关文章

  • 编程时怎么把函数当做变量使用
    在编程时,把函数当做变量使用的方法包括:1.函数赋值给变量;2.函数作为参数传递;3.将函数作为返回值;4.匿名函数与Lambda表达式;5.函数式编程的应用。在编程中善于利用函数作为变量的特性,能够写出更简洁、模块化和易于维护的代码。1.函数赋值给变量在许多编程语言中,函数可以像......
  • C语言使用指针作为函数参数,并利用函数嵌套求输入三个整数,将它们按大到小的顺序输出。(
    输入三个整数,要求从大到小的顺序向他们输出,用函数实现。   本代码使用到了指针和函数嵌套。   调用指针做函数ex,并嵌套调用指针函数exx在函数ex中。(代码在下面哦!)一、关于函数 ex  1. 这个函数接受三个指针参数 int*p1 、 int*p2 和 int*p3 ,分别指......
  • Jenkins打包Unity游戏环境变量配置
    Jenkins打包Unity游戏失败,通过报错日志会查找到sdk环境有问题,解决sdk的环境问题后会出现ndk环境有问题,为了解决这两个问题导致的打包失败需要在Jenkins中配置环境变量打开Jenkins首页,选中ManagerJenkins,再点击System选项找到全局属性,勾选Environmentvariables选项点击......
  • Unity 私有变量在 Inspector 中调整其值
    在Unity中,SerializeField是一个非常有用的特性(Attribute),它主要用于将私有变量公开到Unity编辑器的Inspector界面中。下面是对SerializeField的详细解释及其用途。SerializeField 的用途公开私有变量:通常情况下,类的私有变量不会在Inspector中显示。如果你想保护......
  • VMD-DBO-CNN-BiLSTM四模型多变量时间序列光伏功率预测一键对比 Matlab代码
    基于VMD-DBO-CNN-BiLSTM、VMD-CNN-BiLSTM、VMD-BiLSTM、BiLSTM四模型多变量时间序列光伏功率预测一键对比(仅运行一个main即可)[原创未发表]Matlab代码每个模型的预测结果和组合对比结果都有!运行步骤:1.先运行main1进行VMD分解2.在运行main2进行四模型一键对比代码......
  • 定义明确的参数名/变量名--许多时候,授人以渔还真不如直接授人以鱼
    定义明确的参数名/变量名,是软件开发中的一个重要准则。但是,总这么强调,起的作用似乎并不大。许多时候,授人以渔还真不如直接授人以鱼。所以,我们具象化,看一个栗子。下面是一个业务服务类UserTagService中的一个私有方法。这个方法控制业务逻辑并调用仓储类UserTagManager实现向use......
  • Optional指南,优雅解决空指针
    Optional,该类提供了一种用于表示可选值而非空引用的类级别解决方案。作为一名Java程序员,我真的是烦透了空指针,尽管和它熟得就像一位老朋友,知道它也是迫不得已——程序正在使用一个对象却发现这个对象的值为null,于是Java虚拟机就怒发冲冠地把它抛了出来当做替罪羊。当然......
  • C/C++指针的概念
              指针作为C/C++中一个重要的概念,是每个C/C++程序员必备技能,今天就来说说它。一、指针的概念指针是一种变量,它存储的是另外一个变量的内存地址。在C/C++中,通过指针可以间接访问和操作内存中的数据。例如:intnum=0;int*ptr=&num;这里ptr是一个......
  • 如果python的类变量和实例变量名字一样会如何?
    python中类变量是属于类的,不属于具体的对象,所有对象共享一个类变量。类变量可以通过类名.变量名访问,也可以通过实例化后的对象.变量名访问。那么,如果我给对象的变量起的名字和类变量同名会如何?我们写代码测试一下:classFoo:name="hello"defset_instance_name(self,......
  • C++静态成员变量和静态成员函数的使用
    1.静态成员变量:定义在类中的静态成员,以static关键字初始化和成员变量区别:a.可以通过类名::变量名进行调用,可访问性还是由(public,private,protected)进行限制 例如下面的mystaitcClass::_id,protected属性内容无法直接进行访问,若要直接访问需要修改为public2.静态成员函数:类似可以通过......