首页 > 编程语言 >C/C++ 指针

C/C++ 指针

时间:2024-11-16 13:45:22浏览次数:3  
标签:p2 const int 数据类型 C++ 地址 指针

指针

内存

分类:

运行内存

存储命令

注意

当我们程序运行时系统会在运行内存中开启一片空间给当前程序使用
32位机最多给一个程序开启4G的运行内存,64位8G
将开启的内存以1字节为单位进行划分,每个字节的内存都有其对应的地址编号
这些地址编号也是数据,其数据类型为指针

程序运行内存划分

栈					可读可写   可取地址			局部变量

堆					可读可写

静态全局区			  可读可写  可取地址		 全局变量,静态变量

文字常量区			  可读				代码中编写的常量 如:10 'a' "Hello world"等

代码区					可读

B与b

B:字节
b:位

指针与指针变量

指针

概述

指针是地址的数据类型

指针变量是数据类型为指针的变量

注意

在32位平台下,地址总线是32位的,所以地址是32位编号,所以指针变量是32位的即4个字节。
在64位平台下,地址总线是64位的,所以地址是64位编号,所以指针变量是64位的即8个字节。

语法

数据类型*       

注意:此时数据类型要和指向地址中存储的值的保持一致

指针变量

使用步骤

1.声明
	extern 数据类型* 变量名;
2.定义
	数据类型* 变量名;
3.赋值
	变量名 = 值;
4.使用
	变量名

注意:

指针变量的值是地址

空指针与野指针

空指针:指针变量存储的地址为空(即0)
野指针:指针变量存储的地址不知道指向哪里

运算符

&	取地址符
		可以使用的区域,栈或静态全局区中
	语法:
		&变量名
*:取值,改值
		取值:获取指针变量存储的地址指向的(内存中存储的数据)值
			*指针变量名
		改值:修改指针变量存储的地址指向的(内存中存储的数据)值

注意

空指针或野指针操作会导致段错误
指针变量越界

*的含义
跟在数据类型后面表示这是一个指针类型

*在前表示解引用运算符,取指向地址中的值

void

作用

1.作为函数的返回值类型,表示返回值为NULL
2.万能指针

万能指针

作用

所有指针变量都可以赋值给万能指针的变量,无需强制转换

语法

void* 变量名;

注意

无法取值,因为没有指定跨度

使用

一般作为形参,可以接收任意类型的指针数据
作为函数的返回值类型,表示返回了一个地址

二级指针

概述

指向指针的指针

语法

数据类型* * 变量名 = &p;

注意:此时是指向一个一级指针变量的指针,所以为数据类型*

如:
	int a=10;
	int* p1 = &a;
	int* * p2 =&p1;
p2:p1的地址
*p2:p1中存储的地址
**p2:p1中存储的地址指向的地址中的值
#include<stdio.h>

int main(int argc, char const *argv[])
{
 //  printf("%d\n",);
 //  printf("%p\n",);
 
 int num01=10;
 int num02=20;
 //p1:指向num的地址
 int* p1=&num01;
 int* p2=&num02;
 //p2二级指针,指向的是指针p1的地址
 int* * p3 = &p1;
 //此时*p3就是p1中指向的地址
 printf("%p\n",*p3);
 printf("%p\n",p1);
 
 printf("%d\n",**p3);
 p3 = &p2;
 //此时*p3就是p2中指向的地址
 printf("%d\n",**p3);

 // printf("p1 = %d\n",*p1);
 // printf("p2 = %d\n",**p2);
 
 // printf("%p\n",p1);
 // printf("%p\n",*p2);
 // printf("%p\n",p2);
 // int num02 = 1;
 // int* p3 = &num; // p3指向num的地址
 // p2 = &p3; //p2记录的是指针p3的地址
 // *p2 = &num; //让p3记录的地址变为num的地址
 // **p2 = 1; //num=1 
 // printf("p2 = %d\n",**p2);
 // printf("num = %d\n",num);
 return 0;
}

请添加图片描述

const与指针

概述

使用const与指针变量结合

常量指针(数据类型前+const)

概念

指向常量的指针,本质上是一个指针变量

语法

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

特点

不能修改(其存储的地址指向的)值
但是可以修改其存储的地址

指针常量(变量名前+const)

概念

该指针变量是一个常量

语法

数据类型* const 指针名称;

特点

其存储的地址不可以被修改
但是(存储的地址指向的)值可以被修改

常量指针常量(都加)

概念

使用const修饰的指针变量指向一个常量

语法

const 数据类型* const 指针名称;
或
const 数据类型 * const 指针名称;

指针与数组元素

概述

数组是存储多个数据类型相同的数据的容器
故每一个数据都在数组中存储,每一个数据都有其存储的地址

#include<stdio.h>

int main()
{
	int nums[]={1,2,3,4,5};
	nums[0]=10;
	printf("%d\n",nums[0]);
	
	int x=1;
	x=10;
	printf("x = %d\n",x);
	int* p1=&x;
	//获取数组中下标为0的元素的地址
	int* p2=&nums[0];
	printf("*p2 = %d\n",*p2);
return 0;
}

指针与数组

数组指针

概念

指向数组的指针,本质是个指针

int nums[]={1,2,3,4,5};
int* p1=nums;

指针数组

概念

存储(指针)地址编号的数组,本质上是一个数组

int n01 = 1;
int n02 = 2;
int n03 = 3;
int n04 = 4;
int n05 = 5;
int* ps[] = {&n01,&n02,&n03,&n04,&n05};

int ns01[] = {11,12,13,14,15};
int ns02[] = {21,22,23,24,25};
int ns03[] = {31,32,33,34,35};
int* nss[] = {ns01,ns02,ns03};

for(int i = 0; i < 3; i++)
{
	for(int j = 0; j < 5; j++)
	{
		printf("%d\t",nss[i][j]);
	}
	printf("\n");
}

函数与指针

函数指针

本质

一个指向函数的指针

定义语法

返回值类型(*变量名)(形参列表)=函数名;

注意:此时1形参列表中变量名可以省略不写

调用指向函数的语法

变量名(实参列表);

#include<stdio.h>
void method1();
void method2(int num1,int num2);

int main(int argc, char const *argv[])
{
 //定义一个p1指向method1
 void (*p1)()=method1;
 //定义一个p2指向method2
 void (*p2)(int,int)=method2;

 //调用method1
 p1();
 //调用method2
 p2(2,3);
 return 0;
}
void method1()
{
 printf("1111111\n");
}
void method2(int num1,int num2)
{
 printf("2222222\n");
}

小技巧

将声明Ctrl+c复制到定义的地方,然后将声明的函数名修改为(*指针名),后面再写=函数名;
即	
	void method1();
	void (*p1)()=method1;
	void method2(int num1,int num2);
	void (*p2)(int,int)=method2;

返回值为指针的函数

本质

是一个返回值为指针的函数

语法

返回值类型* 函数名(数据类型 变量1,数据类型 变量2)
{
	函数体
}

使用函数指针记录当前函数

返回值数据类型* (*变量名)(形参列表) = 函数名;

函数的形参有指针

本质

是一个形参列表中有指针变量的函数

语法

返回值数据类型 函数名(...,void*,...)
{
	函数体
}

使用函数指针记录当前函数

返回值类型 (*变量名)(....,void*,...) = 函数名;

作用

将函数作为参数进行传递

#include<stdio.h>
//加减乘除函数声明
extern int add(int num1,int num2);
extern int sub(int num1,int num2);
extern int mul(int num1,int num2);
extern int div(int num1,int num2);

//mymath函数声明
//传入num1,num2 以及带参函数的指针
//返回值为int型的指针
extern int* mymath(int num1,int num2,int(*p)(int,int));

int main(int argc, char const *argv[])
{
 //用p1指向add的地址
 // int (*p1)(int,int)=add;
 // //用p3指向add的地址
 // int (*p2)(int,int)=sub;
 // //用p3指向add的地址
 // int (*p3)(int,int)=mul;
 // //用p4指向add的地址
 // int (*p4)(int,int)=div;
 // int sum1=p1(10,2);
 // printf("%d\n",sum1);


 int* p5=mymath(10,2,add);
 printf("加:%d\n",*p5);
 
 int* p6=mymath(10,2,sub);
 printf("减:%d\n",*p6);//解引用地址
 
 int* p7=mymath(10,2,mul);
 printf("乘:%d\n",*p7);
 
 int* p8=mymath(10,2,div);
 printf("除:%d\n",*p8);
 return 0;
}

int add(int num1,int num2)
{
 return num1+num2;
}

int sub(int num1,int num2)
{
 return num1-num2;
}

int mul(int num1,int num2)
{
 return num1*num2;
}

int div(int num1,int num2)
{
 return num1/num2;
}

int* mymath(int num1,int num2,int(*p)(int,int))
{
 // static int x = p(10,2);
 /*在 C 语言中,静态变量的初始化需要在程序启动时完成,
 而且其初始化表达式不能依赖于函数调用的返回值(除非这个函数已经是一个常量表达式)。
 具体来说,static int x = p(10, 2); 中,p 是一个函数指针,它的值在程序运行过程中是动态的。
 由于静态变量的初始化是在程序加载时进行的,
 而 p 的值直到运行时才会确定,
 因此你不能在静态变量的初始化表达式中直接使用函数指针。*/

 //如果不加static 则x(局部变量)在函数调用结束后销毁
 static int x;
 x= p(num1,num2);
 //返回x的地址
 return &x;
}

总结

指针

地址编号的数据类型

指针变量

记录地址编号的变量

万能指针

可以接收任何类型地址变量的指针类型
语法:
	void *变量名;
注意:
	不能取值

二级指针

存储一级指针地址的指针变量
语法:
	数据类型** 变量名;

常量指针

指向常量的指针,本质是个指针
语法:
	const 数据类型 * 变量名;
	数据类型 const * 变量名;
特点:
	不能修改其指向的值
	但是可以修改其存储的地址

指针常量

指针中存储的地址不能修改,顾本质上是一个常量

语法;
	数据类型 * const 变量名;
特点:
	可以修改其指向的值
	但是不能修改其存储的地址

常量指针常量

指针中存储的地址与指向的值都不能修改

语法:
	const 数据类型 * const 变量名;
	数据类型 const * const 变量名;
特点:
	不能修改其指向的值
	也不能修改其存储的地址

数组名的本质

数组中第一个元素的地址
数组地址不能修改,顾是一个常量指针

数组指针

数组中第一个元素的地址,本质是个指针
如:
	int nums[] = {1,2,3}
	//数组指针
	int *p = nums;

	int x = 10;
	int* p2 = &x;

指针数组

存储指针的数组,本质是个数组

函数指针

指向函数的指针,本质是个指针

返回值类型为指针的函数

本质是个函数,返回值类型为指针类型

const 数据类型 * 变量名;
数据类型 const * 变量名;
特点:
不能修改其指向的值
但是可以修改其存储的地址


指针常量

指针中存储的地址不能修改,顾本质上是一个常量

语法;
数据类型 * const 变量名;
特点:
可以修改其指向的值
但是不能修改其存储的地址


常量指针常量

指针中存储的地址与指向的值都不能修改

语法:
const 数据类型 * const 变量名;
数据类型 const * const 变量名;
特点:
不能修改其指向的值
也不能修改其存储的地址


数组名的本质

数组中第一个元素的地址
数组地址不能修改,顾是一个常量指针


数组指针

数组中第一个元素的地址,本质是个指针
如:
int nums[] = {1,2,3}
//数组指针
int *p = nums;

int x = 10;
int* p2 = &x;


指针数组

存储指针的数组,本质是个数组


函数指针

指向函数的指针,本质是个指针


返回值类型为指针的函数

本质是个函数,返回值类型为指针类型

标签:p2,const,int,数据类型,C++,地址,指针
From: https://blog.csdn.net/2301_81457674/article/details/143816459

相关文章

  • cmake系列-怎么处理C++仅标头库
    这篇文章讲一下cmake怎么处理C++仅标头库,什么叫仅标头库呢,顾名思义,就是只有头文件的程序库。来看这么一个demo这个demo里面有demoA和demoB两个项目,其中demoA是一个仅标头库,demoB使用demoA提供的库。我们知道仅标头库是不能编译成程序目标的,当然用cmake处理也不可能违背......
  • c++的基础认识
    大家好!我是machenss,一个新兴CSDN作者,希望大家多多支持!从今天开始,我将给大家介绍一些简单的c++知识!首先,c++是一种编程语言,是c语言的升级版。学过其他编程语言的话(c.python.java等等),学习c++是很简单的。学习各种编程语言的第一步,当然是打印出“Helloworld!"啦!给大家看一下c++......
  • 自制C++游戏头文件:C++自己的游戏头文件!!!(后续会更新)
    引言在这个数字时代,计算机游戏已经成为人们生活中不可或缺的一部分。它们不仅为我们带来了无尽的乐趣,还激发了我们的创造力和解决问题的能力。今天,我们将深入探讨一个特别的头文件——CPPgame.h,它包含了多个结构体和函数,用于实现多种精彩的游戏体验。无论你是游戏开发者还是游......
  • C++:基于红黑树封装map和set
    红黑树的修改想要用红黑树封装map和set,需要对之前实现的key-value红黑树进行修改,因为map是key-value结构而set是key结构,之前实现的红黑树不能满足需求。我们需要将key和key-value抽象统一成成一个类型T,需要修改红黑树节点类和红黑树类进行。红黑树节点enumColor{ RED, ......
  • 第23课-C++-红黑树的插入与旋转
    ......
  • 【落羽的落羽 C语言篇】指针·之其二
    文章目录一、const使用指南1.const修饰变量2.const修饰指针变量二、野指针1.野指针的概念2.野指针的成因3.如何规避野指针三、assert(断言)使用指南四、传值调用和传址调用1.传值调用2.传址调用一、const使用指南1.const修饰变量众所周知,变量是可以修......
  • 什么是C语言中的指针?
    1.基本概念在C语言中,指针是一种变量,它存储的是另一个变量的内存地址。可以把内存想象成一个巨大的公寓楼,每个变量就像住在公寓里的居民,而指针就是写着居民房间号(内存地址)的纸条。例如,假设有一个整型变量a,它存储在内存中的某个位置,指针变量p就可以用来保存变量a的内存地......
  • (分享源码)计算机毕业设计必看必学 上万套实战教程手把手教学JAVA、PHP,node.js,C++、pyth
    摘要随着计算机科学技术日渐成熟,人们已经深刻认识到了计算机功能的强大,计算机已经进入到了人类社会发展的各个领域,并且发挥着十分重要的作用。通过管理系统在电脑上的应用,人们能更好的管理信息,储存数据。为了能够提供游戏商城的方便性,开发了基于vue的游戏网站。此游戏网站......
  • (分享源码)计算机毕业设计必看必学 上万套实战教程手把手教学JAVA、PHP,node.js,C++、pyth
    摘要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,招聘网站当然也不能排除在外。招聘网站是以实际运用为开发背景,运用软件工程开发方法,采用互联网技术构建的一个管理系统。整个开发过程首先对软件系统进行需......
  • 计算机毕业设计项目推荐,SSM山西能源学院教室管理系统81671(开题答辩+程序定制+全套文案
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,山西能源学院教室管理系统当然也不能排除在外。山西能源学院教室管理系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用 SSM技术构建的一个管理系......