C语言 DAY09 指针02

1.指针的指针

又名二维指针

语法:数据类型  **p;

示例:        

        void fun()
        {
                int a=10;
                int *p1 = &a;
                int **p2 = &p1;
                printf("p1的地址是:%p\n",p1);
                printf("p2的存储的地址是:%p\n",*p2);
                printf("p2的地址是:%p\n",p2);
        }

2.const与指针

1.指针常量

概念

        不能改变其指向变量的地址, 即地址将保持不变如果一个常量指针指向某个变量, 那么它不能指向其他变量 ,但是可以该指针修改其指向的地址中的数据 ,其本质是一个常量

语法

        数据类型   * const  指针变量名

示例

void fun()

{

int num = 10;

int num1 = 5;

int *  const p = #

// 指针常量不能修改其指向的地址
//p = &num1;

*p = 100;//可以修改值

printf("num=%d\n",*p);

}

2.常量指针

概念      

        指向常量的指针,本质是一个指针,不能通过指针改变其指向的地址中的数据,但是可以改变其存储的地址

语法

        const  数据类型 * 指针变量名  or    数据类型  const  *  指针变量名

示例      

void fun()

{

int num = 10;

int num1 = 5;

const int *  p = #

// 指针常量能修改其指向的地址
p = &num1;

//*p = 100;//不可以修改值

printf("num=%d\n",*p);

}

3.常量指针常量

概念

        指向的地址与指向的地址中的数据都不能被修改

语法

        const  数据类型 * const  指针变量名

        数据类型 const  * const  指针变量名

示例

        

void fun()

{

int num = 10;

int num1 = 5;

const int * const  p = #

// 指针常量不能修改其指向的地址
//p = &num1;

//*p = 100;//不可以修改值

printf("num=%d\n",*p);

}

4.注意

        以上名称在网上有所不同,以上为主流说法

3.指针与数组元素

概述

        数组,是多个相同类型的变量的集合, 每个变量都占内存空间,都有地址编号 ,指针变量当然可以存放数组元素的地址

注意

       只有两个相同类型的指针指向同一个数组的元素的时候,比较大小才有意义 ,指向前面元素的指针小于指向后面元素的指针

示例

        

void fun04()
{int nums[] = {1,3,5,7,9,2,4,6,8,0};int *p = &nums[3];printf("%d\n",*p);
//因为数组在内存中是连续开辟的
//所以我们可以通过对指针的加减使其指向数组中不同位置的元素printf("%d\n",*(p+1));printf("%d\n",*(p+2));printf("%d\n",*(p-1));printf("%d\n",*(p-2));
//指针变量存储的地址编号,地址编号是一个十六进制的数printf("%p\n",&nums[0]);printf("%p\n",&nums[1]);
//因为地址编号是一个十六进制的数所以我们可以对其使用关系运算符if(&nums[0] < &nums[1]){printf("nums[0]在前\n");}else{printf("nums[1]在前\n");}
//两个相同类型的地址相差,使用十六进制数相差之后得到的数值 除以其数据类型的字
节大小,为最终结果printf("%ld\n",&nums[0] - &nums[1]);
}

4.指针与数组

概述

        

1, 数组名其实是数组中首元素的地址
2, 数组名可以赋值给一个指针变量 , 此时该指针指向一个数组 , 被称为数组指针 , 其本质是一个指针
指向一维数组指针的语法
        数据类型 * 指针名 ;
指向二维数组指针的语法
        数组类型 (* 指针名 )[ 二维数组中一维数组的长度 ];
指向三维数组指针的语法
        数组类型 (* 指针名 )[ 三维数组中二维数组的长度 ][ 二维数组中一维数组的长度];
3, 数组名本质上是一个指针常量 , 顾其指向的地址无法进行修改
4, 字符数组与字符串指针的区别
字符数组 : 在内存(栈、静态全局区)中开辟了一段空间存放字符串 , 将其首元素地址赋值给数组名,是个指针常量
字符串指针:
如果指向在文字常量区中存放字符串,会将字符串的首地址付给指针变量,此时该指针是个常量指针
如果指向栈、静态全局区中存放的字符数组 , 那么则是一个普通的指针变量
5, 指针变量是一个变量 , 数组可以存储多个类型相同的变量的容器 , 顾数组可以存储多个指针变量, 此时该数组称为指针数组 , 其本质是一个数组

语法

        数据类型 * 数组名 [ 长度 ];
示例:
void fun05()
{
//指针与一维数组
int nums[10] = {1,3,5,7,9,2,4,6,8,0};
//数组名其实是数组中首元素的地址
printf("%p\n",nums);
printf("%p\n",&nums[0]);
//数组名可以赋值给一个指针变量
int * p1 = nums;
char str[] = "hello";
char * p2 = str;
//此时我们可以理解为指针变量就等价与其指向的数组的数组名
//顾我们可以通过指针变量名[下标]获取其指向的数组中指定位置的元素
printf("%d\n",p1[1]);
printf("%c\n",p2[1]);
//指针与二维数组
int numss[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int (*p3)[5] = numss;
printf("%d\n",p3[1][2]);
char strs[5][50] = {"hello","world","c++","python","c"};
char (*p4)[50] = strs;
printf("%c\n",p4[1][2]);
printf("%s\n",p4[1]);
}
//遍历数组元素
void fun06()
{
int nums[10] = {1,3,5,7,9,2,4,6,8,0};
//数组名就是数组第一个元素的的地址
int *p = nums;
for(int i = 0; i < 10; i++)
{
// printf("num[%d] = %d\n",i,*(p + i));
// printf("num[%d] = %d\n",i,*(nums + i));
// printf("num[%d] = %d\n",i,*(p++));
//注意数组的变量名是一个指针常量
//printf("num[%d] = %d\n",i,*(nums++));
}
}void fun07()
{
char str01[] = "hello";
char *str02 = "hello";
//指针常量能修改其指向地址的元素,但是不可以修改其指向的地址
str01[0] = 'H';
printf("str01=%s\n",str01);
//会产生段错误
//常量指针不能修改其指向地址的元素,但是可以修改其指向的地址
//str02[0] = 'H';
//printf("str01=%s\n",str02);
str02 = "world";
函数与指针
printf("str02=%s\n",str02);
//使指针变量指向栈中的字符数组
char *str03 = str01;
str03[0] = 'H';
printf("str03=%s\n",str03);
str03 = "world";
printf("str03=%s\n",str03);
}void fun08()
{
int a = 1,b = 2,c = 3;
int * p[] = {&a,&b,&c};
printf("%d\n",*(p[0]));
printf("%d\n",*(p[1]));
printf("%d\n",*(p[2]));
}

5.函数与指针

概述

        

1, 函数名本身就是函数在代码区存储该函数的地址 , 顾可以赋值给一个指针变量 , 但是因为其在代码区的地址不可修改, 顾该指针是一个指针常量
语法 :
        函数指针的定义与初始化
        返回值类型 (* 指针名称 )( 指向的函数的形参列表的数据类型 ) = 函数名;
注意 :
        指向的函数的形参列表的数据类型可以忽略不写
调用其指向的函数
        指针名( 实参列表 );
        变量名 = 指针名 ( 实参列表 );
注意 :
        实参列表可以忽略不写
2, 指针变量是一个变量 , 顾可以作为函数的形参 , 此时传递的是指针变量的地址
3, 字符串指针作为实参 , 将指针指向常量区的内容传递函数。函数内部修改指针内容时 ,不会影响函数外部的值。
4, 将字符指针的指针作为函数的实参 , 函数的形参使用 **q( 指针的指针 ), 函数内部可以修改字符指针地址, 即可以函数外部的结果
5, 数组作为实参传递可以用指针变量接收 , 传递的是地址
6, 字符指针数组作为实参时,函数的形参的写法: 1) char *q[] 2)
7, 函数中局部指针变量做为函数的返回值, 函数执行完毕后 , 其局部指针变量指向的地址也将被释放, 外部无法使用 . 导致段错误
如需外部使用可以将局部指针变量修改为静态局部指针变量

示例

void test01()
{
printf("test01函数被调用\n");
}void test02(int a,int b)
{
printf("test02函数被调用\n");
}void test03(int a,int b)
{
printf("test03函数被调用\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
}int test04(int a,int b)
{
printf("test04函数被调用\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
return a+b;
}void fun09()
{
void (*p1)() = test01;
p1();
void (*p2)() = test02;
p2();
void (*p3)(int,int) = test03;
p3(10,12);
int (*p4)(int,int) = test04;
int num = p4(10,12);
printf("num=%d\n",num);
}void changNum(int *p)
{
*p = 20;
}void fun10()
{
int num = 10;
changNum(&num);
printf("num=%d\n",num);
}void changName(char *p)
{
p = "高三石";
}void fun11()
{
char *name = "高磊";
changName(name);
printf("name=%s\n",name);
}
void changName02(char **p)
{
*p = "高山石";
}void fun12()
{
char *name = "高磊";
changName02(&name);
printf("name=%s\n",name);
}
void set(int*nums)
{
nums[0] = 10;
}void fun13()
{
int nums[5] = {0};
printf("set 前 nums[0]=%d\n",nums[0]);
set(nums);
printf("set 后 nums[0]=%d\n",nums[0]);
}
void getName01(char * ns[],int i)
{
printf("%s\n",ns[i]);
}
void getName02(char ** ns,int i)
{
printf("%s\n",*(ns+i));
}
void setName(char ** ns,int i,char * newName)
{
*(ns+i) = newName;
}void fun14()
{
char * names[3] = {"c","c++","sql"};
getName01(names,1);
getName02(names,2);
char * name = "cplusplus";
setName(names,1,name);
getName01(names,1);
}
int *getNums01()
{
int nums[3] = {1,2,3};
return nums;
}
int *getNums02()
{
static int nums[3] = {1,2,3};
return nums;
}void fun15()
{
//int *p01 = getNums01();
//printf("%d\n",*(p01+1));
int *p02 = getNums02();
printf("%d\n",*(p02+1));
}

6.指针名称总结

野指针
        局部变量定义的指针没有赋初值
        如:
        int *p;
空指针
        指针的值为NULL
        如:
        int *p = NULL;
空类型指针 ( 万能指针 )
        指针类型为void * 的指针
        如:
        int num = 0;
        void *p = #
指针的指针
        存储指针地址的指针
        如:
        int num = 0;
        int *p = #
        int **p2 = &p;
指针常量 本质是一个常量 , 该指针变量不能修改指向的地址 , 但是可以修改地址中的值
        如:
        int num = 0;
        int * const p = #
常量指针
        本质上是一个指针, 指向常量 , 所以可以修改其指向的地址 , 但是不能修改其指向地址的值
        如:
        const char *p = "name";
        常量指针常量
指针常量与常量指针的结合体 , 既不能修改地址 , 也不能修改值
        如:
        const char * const p = "name";
数组指针
        指向数组的指针, 本质是一个指针
        如:
        一维数组指针
        int *nums;
二维数组指针
        int (*nums)[5];
指针数组
        本质是一个数组, 存储的元素的数据类型为指针
        如:
        int a=1,b=2,c=3;
        int *nums={&a,&b,&c};
        char *names[3] = {"hello","world","c"};
函数指针
        本质是个指针, 存储函数在代码区的地址
        如:
        void test(){
        }
void (*p)();
        返回值为指针的函数声明
        声明一个返回值为指针的函数
        extern int *test();
        int *test()
        {
        static int num = 10;
        return #
        }

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

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

相关文章

Maven Repository使用

1.Maven Repository网站 https://mvnrepository.com/https://mvnrepository.com/ 2.查询需要的依赖 3.参考例子 <!-- https://mvnrepository.com/artifact/org.freeswitch.esl.client/org.freeswitch.esl.client --> <dependency> <groupId>org.freesw…

【k8s】资源管理命令-陈述式

一、资源管理介绍 1、资源管理概念 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。 //kubernetes的本质就是一个集群系统&#xff0c;用户可以在集群中部署各种服务&#xff0c;起始就是在kubernetes集群中运行一个个…

科技驱动教育!将名师智慧资产固定在系统中

文章目录 每日一句正能量前言未来教育教育趋势一、在线教育&#xff1a;打破时间和空间的限制二、混合式学习&#xff1a;结合线上和线下的优势三、项目式学习&#xff1a;以问题为导向&#xff0c;以项目为载体 科技驱动教育模式在线教育人工智能教育虚拟现实/增强现实教育游戏…

React事件处理

目录 前言 1. 添加事件处理函数 2. 传递参数 使用箭头函数 使用bind方法 3. 阻止默认行为和冒泡 阻止默认行为 阻止事件冒泡 4. 最佳实践 前言 React是一个流行的JavaScript库&#xff0c;用于构建用户界面。在React中&#xff0c;事件处理是非常重要的一部分&#xf…

非递归(迭代)遍历二叉树

前言 在树结构中我们经常使用递归算法&#xff0c;但是递归本身的特质会带来很多疑难痛点&#xff0c;比如递归过深导致爆栈&#xff0c;或者是逻辑复杂... 本文将以树的前序遍历为例&#xff0c;浅析迭代算法如何模拟递归过程。

tasks.json、launch.json、c_cpp_properties.json配置

tasks.json //tasks.json是辅助程序编译的模块&#xff0c;执行类似于在命令行输入“gcc hello.c -o hello”命令的操作 {"version": "2.0.0","tasks": [{"type": "cppbuild", //任务类型&…

Linux开源存储方案系统介绍

文章目录 开源云计算数据存储平台怎么理解云计算 存储管理和软件定义存储软件定义存储开源项目OpenSDSLibvirt Storage Management&#xff1a;OHSM&#xff08;Online Hierarchical Storage Manager&#xff09; 开源分布式存储什么是分布式存储元数据服务器数据服务器客户端 …

“深入理解Nginx的负载均衡与动静分离“

目录 引言一、Nginx简介1. Nginx的基本概念2. Nginx的特点3. Nginx的安装配置 二、Nginx搭载负载均衡三、前端项目打包四、Nginx部署前后端分离项目&#xff0c;同时实现负载均衡和动静分离总结 引言 在现代互联网应用中&#xff0c;高性能和可扩展性是至关重要的。Nginx作为一…

django 下载与安装

#django安装 pip3 install django#创建工程 django-admin startproject 名称 如&#xff1a;django-admin startproject bookmanager#django启动 python manage.py runserver python manage.py runserver 127.0.0.1:8081#数据迁移 生成迁移文件&#xff1a;python manage.py ma…

吴恩达《机器学习》2-2->2-4:代价函数

一、代价函数的概念 代价函数是在监督学习中用于评估模型的性能和帮助选择最佳模型参数的重要工具。它表示了模型的预测输出与实际目标值之间的差距&#xff0c;即建模误差。代价函数的目标是找到使建模误差最小化的模型参数。 二、代价函数的理解 训练集数据&#xff1a;假设我…

操作系统 (1)

进程的概念 进程同步/进程互斥 进程互斥的软件实现 进程互斥的硬件实现 信号量机制 生产者消费者问题 以下wei8最终情况,不可调换位置,否则会发生死锁 预防死锁 避免死锁

警惕!当心AI诈骗!

本文参照材料有&#xff1a; 鄂尔多斯新闻公众号、澎湃新闻网、搜孤新闻、腾讯网等 AI换脸诈骗实例&#xff08;就发生在近期&#xff09; 事例一&#xff1a; 近期 “AI换脸”新型诈骗频发和你视频对话的可能不是本人&#xff01; 近日&#xff0c;东胜市民李女士遭遇了冒充…

CentOS一键部署Docker

Docker官网&#xff1a;https://www.docker.com/ CentOS&#xff08;7.6&#xff09; Docker&#xff08;18.06.1&#xff09;一键安装脚本 #!/bin/bash echo "1、安装依赖..." yum -y install gcc yum -y install gcc-c##验证gcc版本 gcc -vecho "2、卸载老…

Linux shell编程学习笔记18:while循环语句

上回我们研究和探讨了Linux shell编程中for 循环语句&#xff0c;与在C/C中一样&#xff0c;for 循环语句Linux shell编程中有很多灵活的用法。今天我们来研究和探讨while循环语句。 一、数字条件循环 我们继续以for循环语句中的例子&#xff0c;计算 从1到10与2的乘积 并输出…

【论文阅读】Iterative Poisson Surface Reconstruction (iPSR) for Unoriented Points

文章目录 声明作者列表核心思想归纳算法流程机器翻译声明 本帖更新中如有问题,望批评指正!如果有人觉得帖子质量差,希望在评论中给出建议,谢谢!作者列表 FEI HOU(侯飞)、CHIYU WANG、WENCHENG WANG:中国科学院大学 HONG QIN CHEN QIAN、YING HE 核心思想归纳 当一条从…

浅述青犀AI算法人体攀爬行为检测的应用场景及解决方案

人体攀爬行为检测是指利用计算机视觉技术对人类攀爬物体的行为进行识别和分析。该技术主要依靠图像和视频数据进行分析&#xff0c;通过识别人类身体的各个部位&#xff0c;以及其在攀爬过程中的动作和姿态&#xff0c;实现对攀爬行为的检测和跟踪。该技术的场景应用比较广泛&a…

航空领袖《波音公司》被攻击勒索

全球航空航天业的领袖公司-波音竟然被黑客攻击勒索了&#xff1f;相比很多小伙伴对波音并不熟悉&#xff0c;波音公司是世界上最大的民用和军用飞机制造商之一。其客户分布在全球90多个国家&#xff0c;像国内很多民航都用的是波音。那就有小伙伴担心了那我做飞机不是就很危险了…

(2)STM32单片机上位机

使用VX小程序开发上位机&#xff0c; 样式如何创建&#xff1f; 在你所在页面 开辟空间 使用 view 在view 中 输入class 就是样式&#xff0c;在编辑样式的时候&#xff0c;如何寻找哪一块的样式 就是通过这个class寻找的 按钮使用switch

算法训练 第五周

一、多数元素 本题给了我们一个数组&#xff0c;要求我们找出这个数组中出现次数大于这个数组元素总量一半的那个元素&#xff0c;也可以理解为找出数组中出现次数最多的那个元素&#xff0c;本题的解决方法有很多&#xff0c;在此我们主要讨论三种解决思路。 1.Hash表 我们可…

opencv中绘制图像的函数

常用函数简介 OpenCV 中用于绘制不同图形的 C 函数的简要介绍&#xff1a; 绘制矩形框&#xff1a; cv::rectangle(image, cv::Point pt1, cv::Point pt2, cv::Scalar color, int thickness); image&#xff1a;目标图像pt1 和 pt2&#xff1a;矩形的对角线顶点坐标color&…