C语言指针详解(1)------指针类型(简单例子+详细讲解)

news2025/1/18 7:42:16

C语言指针类型详解及举例

此文介绍了C语言中常见的6种指针,对每种指针进行了介绍,并举出相应的例子供大家理解学习.

文章目录

  • C语言指针类型详解及举例
  • 1.字符指针
  • 2.数组指针
  • 3.指针数组
  • 4.函数指针
  • 5函数指针数组
  • 6指向函数指针数组的指针


1.字符指针

字符指针是指向字符数组或字符串的指针。在C语言中,字符串实际上是以null字符(‘\0’)结尾的字符数组。字符指针指向这个字符数组的首地址。

例如,有一个字符串 “Hello”,可以用字符数组来表示:char str[] =“Hello”。而字符指针则指向这个字符数组的首地址,可以这样声明:char *ptr = str;。

通过字符指针,我们可以访问和操作字符串中的字符,也可以通过指针算术运算来遍历字符串。常见的字符串操作函数如strlen、strcpy、strcat等也都是通过字符指针进行操作的。

需要注意的是,字符指针指向的字符数组应该是以null字符(‘\0’)结尾的,以便正确识别字符串的结束。否则,可能会导致访问越界或其他错误。

使用举例

//一,最简单的使用
char ch = 'w';
char *pc = &ch;
*pc = 'w';

//二,字符串使用
const char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);//pstr中存放的是字符串首字符‘h’的地址
//代码 const char* pstr = "hello bit.";

2.数组指针

数组指针是指向数组的指针。在C语言中,数组名本身就是一个指向数组首元素的指针,即数组的地址就是数组名的值。因此,可以使用指针来操作数组的元素。

例如,有一个整型数组 int arr[5] = {1, 2, 3, 4, 5},可以用数组名 arr
来表示该数组,同时arr也是指向数组首元素的指针,即 int *ptr = arr;。

通过数组指针,我们可以访问和操作数组的元素,也可以通过指针算术运算来遍历数组。

需要注意的是,数组指针的类型应该与数组的类型一致,即指向何种类型的数组就应该声明指针类型为该类型的指针。同时,数组指针也可以指向多维数组,只需要指针类型与数组维度相对应即可。

总结来说,数组指针是指向数组的指针,可以通过指针来访问和操作数组的元素。

使用举例

int arr[10]={1,2,3};
&arr;//拿到的是数组的地址

int (*p)[10]=&arr;//p是一个数组指针变量
int (*)[10]//是一个数组指针类型
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);

printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);

在这里插入图片描述

根据上面第二段代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。
实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下)
本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型
数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.

3.指针数组

指针数组是指一个数组,其中的元素都是指针类型。换句话说,指针数组是由指针组成的数组。

在C语言中,可以声明一个指针数组来存储多个指针。每个数组元素都是一个指针,可以指向不同的数据类型或对象。这使得我们能够在数组中存储不同类型的数据或对象的地址。

使用举例

char *arr[5];//存放字符指针的数组
int *arr2[6];//存放整形指针的数组

例如,假设我们有三个整型变量 int a, int b 和 int c,并希望将它们的地址存储在一个数组中,我们可以这样声明一个指针数组:
具体如下:

int *ptrArr[3];  // 声明一个指针数组,包含三个指针元素
//然后,我们可以将这三个整型变量的地址分别存储到指针数组中:
ptrArr[0] = &a;
ptrArr[1] = &b;
ptrArr[2] = &c;


4.函数指针

函数指针是指向函数的指针变量,它可以用来存储和调用函数的地址。在C语言中,函数指针允许将函数作为参数传递给其他函数,或者将函数作为返回值返回。

使用举例

int Add(int x, int y)
{
	return x + y;
}
//&函数名 - 拿到的就是函数的地址
//函数名 - 也是函数的地址
int main()
{
	printf("%p\n", &Add);
	printf("%p\n", Add);
	int (* pf)(int, int) = &Add;//pf就是一个函数指针变量
	int (* pf)(int, int) = Add;
	int ret = pf(3, 5);
	int ret2 = Add(3, 5);
	printf("%d\n", ret);
	printf("%d\n", ret2);
	return 0;
}

运行结果如下:
在这里插入图片描述

5函数指针数组

函数指针数组是一个数组,其中的元素都是函数指针。换句话说,函数指针数组是由函数指针组成的数组。

在C语言中,可以声明一个函数指针数组来存储多个函数指针。每个数组元素都是一个函数指针,可以指向不同的函数。

函数指针数组的用途:转移表

使用举例(计算器)

#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
do
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
switch (input)
{
case 1:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = add(x, y);
printf( "ret = %d\n", ret);
break;
case 2:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = sub(x, y);
printf( "ret = %d\n", ret);
break;
case 3:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = mul(x, y);
printf( "ret = %d\n", ret);
break;
case 4:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = div(x, y);
printf( "ret = %d\n", ret);
break;
case 0:
printf("退出程序\n");
breark;
default:
printf( "选择错误\n" );
break;
}
} while (input);
return 0;
}

我们可以看到如果不使用函数指针数组,我们写一个计算器需要的代码非常繁琐,如果还要再增加功能,那么代码也会更加复杂.

下面使用函数指针数组:

#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输入有误\n" );
printf( "ret = %d\n", ret);
}
return 0;
}

我们可以看到此时代码得到了简化,不需要再去一个个调用每个功能,只需要用到转移表,这就是函数指针数组的强大功能.

6指向函数指针数组的指针

它在我们写代码时很少用到,作为一个扩展,我用一个简单的例子让大家了解一下

int a=10;
int b=20;
int c=30;
int *arr[]={&a,&b,&c};//整形指针数组
int *(*p)[3]=&arr;//p是指针,是指向整形指针数组的指针

//函数指针数组 - 数组 - 存放的是函数的地址
int (*pfArr[5])(int,int)={NULL,Add,Sub,Mul,Div};//pfArr是函数指针数组
p=&pfArr;
int (*(*p)[5])(int,int)=&pfArr;//指向函数指针数组的指针

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

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

相关文章

vue学习之事件绑定

事件绑定 创建 demo5.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…

手写Mybatis框架

Mybatis核心配置文件就是为了配置Configration 因此要首先会解析Mybatis核心配置文件 首先使用dom4J解析Mybatis核心配置文件 新建模块演示dom4j解析.xml 目录放错了 无所谓 引入依赖 从原来项目可以拷贝过来 就些简单配置就好 解析核心配置文件和解析xxxMapper.xml映射文件…

《React vs. Vue vs. Angular:2023年的全面比较》

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

如何快速下载UE源码

前置技能要求掌握Git和Github的基础操作和知识 1.获取源码仓库授权并下载源代码 (1).获取授权 UE是开源的&#xff0c;但是它的代码仓库在Github不开源&#xff0c;我们没法直接搜索到&#xff0c; 登录->个人信息->应用与账户->连接Github 请按照官网指引成功进…

想要精通算法和SQL的成长之路 - 课程表III

想要精通算法和SQL的成长之路 - 课程表III 前言一. 课程表III&#xff08;贪心优先队列&#xff09;1.1 优先选择截止时间更小的课程1.2 如果当前课程无法学习怎么办&#xff1f;1.3 优化 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 课程表III&#xff08;贪心优先队列&…

【ArcGIS pro】-使用arcpy一次保存多个布局

在arcgis Pro中常常会创建多个地图和多个布局&#xff0c;本文介绍如何使用代码&#xff0c;一次保存多个布局文件 在arcgis pro中打开python视图 找到工程位置 在python视图中输入如下代码 保存为pdf import arcpy# 设置当前项目&#xff0c;这通常是一个.aprx文件 projec…

11.Xaml DatePicker控件 时间控件

1.运行效果 2.运行源码 a.Xaml源码 <Grid Name="Grid1"><!--DisplayDate="2020-5-1" 显示的日期--><!--DisplayDateStart="2020

Linux CentOS7 添加中文输入法

在安装CentOS7时&#xff0c;现在默认安装了桌面中文系统。可以切换为英文&#xff0c;中英文可以按要求随时更换。而在CentOS7桌面环境下&#xff0c;显示中文非常方便、正确&#xff0c;并不能录入中文。 在远程登录系统的情况下&#xff0c;不论是系统语言&#xff08;LANG…

Vue2电商前台项目——完成Home首页模块业务

Vue2电商前台项目——完成Home首页模块业务 Vue基础知识点击此处——Vue.js 文章目录 Vue2电商前台项目——完成Home首页模块业务一、项目开发的步骤二、Home首页拆分静态组件1、完成TypeNav三级联动组件&#xff1a;全局组件2、完成其余静态组件&#xff1a;局部组件 三、请求…

黑马JVM总结(四)

&#xff08;1&#xff09;本地方法栈 Java虚拟机调用本地方法时&#xff0c;给本地方法提供的一个内存空间&#xff0c;本地方法它是指哪些不是由java代码编写的方法 java代码有一定限制&#xff0c;它有时候不能直接跟操作系统底层打交道&#xff0c;需要用c和c语言编写的本…

《C和指针》笔记23: 指针的指针

int a 12; int *b &a;现在有了第三个变量c c &b;c的类型是什么&#xff1f;显然它是一个指针&#xff0c;但它所指向的是什么&#xff1f;变量b是一个“指向整型的指针”&#xff0c;所以任何指向b的类型必须是指向“指向整型的指针”的指针&#xff0c;更通俗地说…

D. Paths on the Tree

Problem - 1746D - Codeforces 思路&#xff1a;先分析一下题意&#xff0c;根据第一条性质&#xff0c;每次只能够从1开始&#xff0c;而第二条性质则表明对于每个节点来说&#xff0c;经过这个节点的子节点的路径条数应该尽量均衡&#xff0c;最大值与最小值相差不能超过1&am…

水浒传之“领导力的定义:梁山集团三代领导人的特点”

周末快乐&#xff0c;我是老原。 周末修整&#xff0c;也不要忘记给自己的大脑充个电。 最近空闲时间看《水浒传》&#xff0c;有了一些关于领导力的感悟。 一提到领导力&#xff0c;有人可能会认为&#xff0c;这是企业领导才需要掌握的能力。 其实并不是。 领导力可以体…

liunx系统无sudo或管理员权限安装rar解压安装包

liunx无sudo权限安装rar解压安装包 &#xff08;1&#xff09;正常liunx安装rar&#xff08;2&#xff09;无sudo\root(管理员身份)时如何安装rar &#xff08;1&#xff09;正常liunx安装rar 1、下载安装包 WinRAR archiver, a powerful tool to process RAR and ZIP files (r…

C#类与类库调用注意事项

类 创建一个类文件&#xff0c;myfunction.cs //静态类&#xff1a;直接引用、无需实例化 static public int jiafa(int V) //普通类&#xff1a;引用时需要实例化 public int jiafa(int V)using System; using System.Collections.Generic; using System.Diagnostics; using …

VS Code 配置 JAVA(总)

VS Code 配置 JAVA&#xff08;总&#xff09; 主要参考&#xff1a; 处理单独 java 源文件的vscode配置VScode关于 java 配置的总体说明安装多版本 jdk 后&#xff0c;如何指定使用某个版本&#xff1f;某些与java相关的有用扩展VS code 如何配置不同编程语言及其工作流程 …

运维必备 | 使用 ansible 自动化批量执行工具,提升企业运维工作效率

各位亲爱的读者&#xff0c;现在公众号更改了推送规则&#xff0c;如果您需要第一时间看到我们推送的好内容。 一定要记得给公众号星标&#xff0c;经常点赞、在看、转发、分享和留下您的评论 &#xff01; 关注回复【学习交流群】加入【安全开发运维】答疑交流群 请朋友们【多…

买卖股票的最佳时机含冷冻期

题目链接 买卖股票的最佳时机含冷冻期 题目描述 注意点 卖出股票后&#xff0c;无法在第二天买入股票 (即冷冻期为 1 天)不能同时参与多笔交易&#xff08;必须在再次购买前出售掉之前的股票&#xff09;可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09…

l8-d11 TCP连接管理与UDP协议

一、三次握手 TCP 建立连接的过程叫做握手。 采用三报文握手&#xff1a;在客户和服务器之间交换三个 TCP 报文段&#xff0c;以防止已失效的连接请求报文段突然又传送到了&#xff0c;因而产生 TCP 连接建立错误。 二、四次挥手 TCP 连接释放过程比较复杂。 数据传输结束后…

2、k-means聚类算法sklearn与手动实现

本文将对k-means聚类算法原理和实现过程进行简述 算法原理 k-means算法原理较简单&#xff0c;基本步骤如下&#xff1a; 1、假定我们要对N个样本观测做聚类&#xff0c;要求聚为K类&#xff0c;首先选择K个点作为初始中心点&#xff1b; 2、接下来&#xff0c;按照距离初始中…