变量和作用域、指针

news/2024/10/22 19:40:10

变量和作用域、指针

指针变量

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

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

声明指针时的类型名称用来表示指针适合与什么类型的存储区捆绑,可以在一条语句里声明多个类型的指针变量,这个时候必须在每个指针变量名称前单独加 *。没有捆绑的指针分为两种,一种叫做空指针,它固定记录空地址(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 

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

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

相关文章

PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展

检查并开启 sqlite3 扩展打开 PHPStudy Pro 软件。 导航至设置 -> 配置文件 -> php.ini。 选择你当前使用的 PHP 版本(例如 php7.3.4nts)并点击打开 php.ini 文件。 在 php.ini 文件中搜索 extension=sqlite3。 如果该行被注释掉(前面有分号 ;),则去掉分号以启用扩展…

PbootCMS上传空间后前台打开内页显示404错误怎么解决

检查 URL 规则配置登录 PbootCMS 后台。 导航至 配置参数 -> URL规则。 选择 伪静态模式 并保存。添加伪静态规则根据你的服务器环境,选择合适的伪静态规则文件。 一般情况下,Apache 环境使用 .htaccess 文件。Apache 环境配置将 rewrite 文件夹中的 .htaccess 文件复制到…

例题2.3

例题2.3代码 L = [abc, 12, 3.45, python, 2.789] print(L) print(L[0]) L[0] = a L[1:3] = [b, Hello] print(L) L[2:4] = [] print(L)

习题2.5

习题2.5代码 import numpy as np import pandas as pd import sympy as sp sp.init_printing(use_unicode=True) import matplotlib.pyplot as plt plt.rcParams[font.sans-serif]=[Times New Roman + SimSun + WFM Sans SC] plt.rcParams[mathtext.fontset]=cm Times New Roma…

高等数学 7.7常系数齐次线性微分方程

在二阶齐次线性微分方程 \[y + P(x)y + Q(x)y = 0 \tag{1} \]中,如果 \(y, y\) 的系数 \(P(x), Q(x)\) 均为常数,即 \((1)\) 式成为 \[y + py + qy = 0 \tag{2} \]其中 \(p, q\) 是常数,那么称 \((2)\) 为二阶常系数齐次线性微分方程。如果 \(p, q\) 不全为常数,就称 \((1)…

线性代数--线性方程组

线性方程组有解的判定 {x1+x2+x3=1x1−x2−x3=−32x1+9x2+10x3=11系数矩阵:A=(1111−1−12910)增广矩阵:A=(11111−1−1−3291011) n是未知量的个数,m是方程的个数怎么判断秩是否相等步骤:通过方程,写出增广系数矩阵 只做初等行变换,化为阶梯型 看系数矩阵的秩和增广系数…

Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题

本文将从阿里云 Python 探针的接入步骤、产品能力、兼容性等方面展开介绍。并提供一个简单的 LLM 应用例子,方便测试。作者:彦鸿 背景 随着 LLM(大语言模型)技术的不断成熟和应用场景的不断拓展,越来越多的企业开始将 LLM 技术纳入自己的产品和服务中。LLM 在自然语言处理…

计算机视觉领域的实际应用有什么

计算机视觉在多个行业和应用场景中有着广泛的实际应用,主要包括医疗图像分析、自动驾驶、物体检测、人脸识别、增强现实(AR)和虚拟现实(VR)、工业自动化、农业监测等。医疗图像分析用于诊断疾病和制定治疗方案,提高医疗服务的质量和效率。其中,自动驾驶是一个相对成熟的…