C语言指针4

news2024/12/23 0:40:35

1.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int a = 10;
	int* p = &a;//一级指针
	int** pp = &p;//二级指针
	return 0;
}

上述代码中p的类型是int*

pp的类型是int**

2.int* arr[5];

数组arr的每个元素是整形指针

3.定义一个变量时,去掉变量名,剩下的就是变量的类型

4.用二级指针模拟二维数组:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int arr1[5] = { 1,2,3,4,5 };//5列
	int arr2[5] = { 2,3,4,5,6 };//5列
	int arr3[5] = { 3,4,5,6,7 };//5列
	int* arr[] = { arr1,arr2,arr3 };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", *(arr[i] + j));
			printf("%d ", arr[i][j]);
			//上述两行代码等效
			//因为arr[i][j] == *(arr + i)[j] == *(*(arr + i) + j)
		}
		printf("\n");
	}

	return 0;
}

5.char* p = "abcdef";

p存放的是首字符a的地址

6.可以把字符串想象为一个字符数组,但是这个数组是不能被修改的.

当常量字符串出现在表达式中的时候,他的值是第一个字符的地址.

例:

printf("%c", "abcdef"[3]);

char* p = "abcdef";

打印的是d,而且p[3] == "abcdef"[3];

7."abcdef" + 3拿到的是'd'的地址

8.数组指针和指针数组的区别示例:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int(*pa)[10] = &arr;//pa的类型是int(*)[10],p是一个指针,指向的是具有10个元素且每个元素的类型是int的数组
	int a = 10;
	int b = 20;
	int c = 10;
	int* p[3] = { &a,&b,&c };//pa的类型是int* [10],p是具有10个元素且每个元素的类型是int*的数组

	return 0;
}

9.

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//&arr 的类型是int (*)[10]  

10.*p == arr;

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int(*p)[10] = &arr;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d", arr[i]);
		printf("%d", (*p)[i]);
		//上述两行代码等效
		//因为p == &arr
		//所以*p == *&arr == arr
	}
	return 0;
}

11.数组名都是首元素的地址,二维数组也不例外

12.二维数组传参传过去的也是首元素的地址,那么就可以用数组指针来接受那个一维数组,这也就是二维数组传参的本质

13.二维数组解引用一次的的话是找到了一维数组,而此时一维数组是该一维数组的数组名,即该数组首元素的地址,再对它进行解引用就拿到了某个数据

14.可以这样再函数内部查看主函数内部的数组

arr,长度

例:

15.int (*)[10] == int [10]*

16.若parr是数组指针,则parr里面存的是这个数组的地址,解引用拿到的是首元素的地址

17.函数名同时也是函数名的地址,&函数名也一样

18.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void print(int arr[3][5], int r, int c)
{
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	} 
}

int main()
{
	void(*p)(int[3][5], int, int) = &print;
	return 0;
}

上述的p是函数指针变量

而int*p(int[3][5], int, int);是函数的声明

pf == print

*pf == print

上述的p也可以这样初始化:

void(*p)(int[3][5], int, int) = print;

19.使用函数指针的例子:转移表的创建:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

void menu()
{
	printf("***********************\n");
	printf("*****1.Add   2.Sub*****\n");
	printf("*****3.Mul   4.Div*****\n");
	printf("*****0.exit       *****\n");
	printf("***********************\n");
}

int Add(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{
	return x - y;
}

int Mul(int x, int y)
{
	return x * y;
}

int Div(int x, int y)
{
	//x = (float)x;
	return x / y;
}

int cal(int x, int y, int(*p)(int, int))
{
	return p(x, y);
}


int main()
{
	//函数指针数组
	int(*p[5])(int, int) = { 0,Add,Sub,Mul,Div };//重点!!!
	int input = 1;
	menu();
	scanf("%d", &input);
	while (input != 0)
	{
		if (input <= 4)
		{
			int a = 0;
			int b = 0;
			printf("请输入两个数:\n");
			scanf("%d %d", &a, &b);
			printf("%d\n", cal(a, b, p[input]));
		}
		else
		{
			printf("输入错误!请重新输入\n");
		}
		menu();
		scanf("%d", &input);
	}



	return 0;
}

20.(*(void (*)())0)();是调用地址为0的函数

21.void  (* signal(int, void(*)(int) ) )(int);

这是一个函数的声明,函数名是signal,参数类型是(int, void(*)(int) ),返回类型是void  (*)(int)

22.typedef可以将复杂的类型名字简单化

原名字还是可以用的

但是对于数组指针类型和函数指针类型就有点不一样

例:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

typedef int m;

typedef int(*parr)[10] ;

typedef int(*ppp)(int, int);

int Add(int x, int y)
{
	return x + y;
}
int main()
{
	m a = 10;
	//上述代码等价于
	//int a = 10;

	int arr[10] = { 0 };
	parr a = &arr;
	//上述代码等价于
	//int(*a)[10] = &arr;

	ppp aaa = &Add;
	//上述代码等价于
	//int(*aaa)(int, int) = &Add;

	return 0;
}

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

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

相关文章

报数游戏C语言

分析:掌握数字移动的规律&#xff0c;以及判断&#xff0c;我们可以用一个二维数组来记录每一个人说的数字&#xff0c;就像第一张图片一样&#xff0c;西安向右边移动&#xff0c;再向左下移动&#xff0c;再向左边移动&#xff0c;在向右边移动&#xff0c;在可以用一个数组来…

3 - Electron BrowserWindow对象 关于窗口

优雅的打开应用~ 当加载缓慢&#xff0c;打开应用的一瞬间会出现白屏&#xff0c;以下方法可以解决 const mainWindow new BrowserWindow({ show: false }) mainWindow.once(ready-to-show, () > {mainWindow.show() }) 设置背景颜色 const win new BrowserWindow({ b…

比特币即自由

号外&#xff1a;教链内参12.15《疯狂的铭文》 文 | Ross Ulbricht. 原文标题&#xff1a;Bitcoin Equals Freedom. 2019.9.25 在中本聪发明比特币后的头一年左右&#xff0c;发生了一些特别的事情&#xff0c;不仅没有人预料到&#xff0c;甚至很多人认为不可能。试着想象一下…

【Python从入门到进阶】44、Scrapy的基本介绍和安装

接上篇《43.验证码识别工具结合requests的使用》 上一篇我们学习了如何使用验证码识别工具进行登录验证的自动识别。本篇我们开启一个新的章节&#xff0c;来学习一下快速、高层次的屏幕抓取和web抓取框架Scrapy。 一、Scrapy框架的背景和特点 Scrapy框架是一个为了爬取网站数…

Python:Jupyter

Jupyter是一个开源的交互式计算环境&#xff0c;由Fernando Perez和Brian Granger于2014年创立。它提供了一种方便的方式来展示、共享和探索数据&#xff0c;并且可以与多种编程语言和数据格式进行交互。Jupyter的历史可以追溯到2001年&#xff0c;当时Fernando Perez正在使用P…

开源免费图床Lychee本地部署搭建个人云图床并公网访问【内网穿透】

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

LeetCode(64)分隔链表【链表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 分隔链表 1.题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示…

加油站“变身”快充站,探讨充电新模式——安科瑞 顾烊宇

摘要&#xff1a;新能源汽车规模化发展的同时&#xff0c;充电不便利的痛点愈发明显。在未来的新能源汽车行业发展当中&#xff0c;充电的矛盾要远远大于造车的矛盾&#xff0c;解决好充电的问题成为电动汽车行业发展的一个突出问题。解决充电补能问题&#xff0c;重要的方式之…

Python实现员工管理系统(Django页面版 ) 六

本篇博客主要实现用户账号管理&#xff0c;这与之前的账号管理不同&#xff0c;之前的账号管理你可以理解为公司在外面买的一些手机号然后需要发放给员工做内部使用&#xff0c;而本篇博客的用户账号管理主要是为了后续的登录网页实现&#xff0c;那么我们开始今天的项目实现吧…

栈和队列的实现(Java篇)

文章目录 一、栈的概念二、栈的实现2.1压栈(push)2.2出栈(pop)2.3获取栈顶元素(peek)2.4判断栈是否为空(isEmpty)栈的实现测试 三、队列的概念四、队列的实现4.1入队(offer)4.2出队(poll)4.3判断队列是否为空4.4获取对头元素队列的实现测试 五、循环队列5.1入队5.2出队5.3获取队…

手把手教你Linux查找Java的安装目录并设置环境变量以及Linux下执行javac未找到命令的保姆级教学

查找Java的安装目录 输入 java -version&#xff0c;查看是否成功安装Java 输入 which java&#xff0c;查看Java的执行路径 输入 ls -lrt /usr/bin/java 输入 ls -lrt /etc/alternatives/java&#xff0c;/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 就是J…

系列七、函数

一、函数 1.1、概述 函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码MySQL中已经为我们提供好了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成相应的业务需求即可。 1.2、分类 按照业务分类&#xff0c;MySQL中…

centOS安装bochsXshell连接centos启动可视化界面

centOS安装bochs 参考&#xff1a;https://blog.csdn.net/muzi_since/article/details/102559187 首先安装依赖环境&#xff1a; yum install gtk2 gtk2-devel yum install libXt libXt-devel yum install libXpm libXpm-devel yum install SDL SDL-devel yum install libXr…

【LeetCode刷题-哈希表】--187.重复的DNA序列

187.重复的DNA序列 本题就是找到长度为10的字符出现次数大于2的 子串序列 方法&#xff1a;使用哈希表 class Solution {public List<String> findRepeatedDnaSequences(String s) {List<String> ans new ArrayList<String>();HashMap<String,Integer&g…

【LeetCode刷题-字符串】-- 186.反转字符串中的单词II

186.反转字符串中的单词II 方法&#xff1a;先反转整个字符串再反转单词中的字母 class Solution {public void reverseWords(char[] s) {reverseCharacters(s,0,s.length-1);reverseEachWord(s);}//反转单词中的字母public void reverseEachWord(char[] s){int length s.len…

【CASS精品教程】cass11提示“请不要在虚拟机中运行此程序”的解决办法

文章目录 一、问题提示二、解决办法一、问题提示 按照正常安装教程安装好南方测绘cass 11之后,打开的时候可能会有以下提示:请不要在虚拟机中运行此程序,如下图所示: 遇到问题,咱们就想办法解决问题,下面将自己尝试的方法及最终解决情况跟大家说一下,供参考。 二、解决…

注册与回调

C 再谈谈注册(本质是建立映射)与回调 在之前的博文中&#xff0c; 我们探讨过映射的重要作用&#xff0c; 请直接看&#xff1a;http://blog.csdn.net/stpeace/article/details/39452203, 在那篇文章中&#xff0c; 我们是用STL中的map来做的&#xff0c; map建立的是key-value…

代码随想录算法训练营Day1 | 704.二分查找、27.移除元素

LeetCode 704 二分查找 题目链接&#xff1a;704.二分查找 本题思路&#xff1a;本题题目写的是二分查找&#xff0c;所以我们用到的算法肯定也是二分查找&#xff0c;需要定义 3个变量。 l: 从数组的下标0开始 r: 数组长度 - 1 mid&#xff1a;&#xff08;l r&#xff09;…

AUTOSAR组织引入了Rust语言的原因是什么?有哪些好处?与C++相比它有什么优点?并推荐一些入门学习Rust语言链接等

AUTOSAR(汽车开放系统架构)是一个由汽车制造商、供应商和其他来自电子、半导体和软件行业的公司组成的全球发展伙伴关系,自2003年以来一直致力于为汽车行业开发和引入开放、标准化的软件平台。 AUTOSAR 最近宣布成立一个新的工作组,用于探索在汽车软件中使用 Rust 编程语言…

【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火

​ &#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《网络安全之道 | 数字征程》⏰墨香寄清辞&#xff1a;千里传信如电光&#xff0c;密码奥妙似仙方。 挑战黑暗剑拔弩张&#xff0c;网络战场誓守长。 ​ 目录 &#x1f608;1. 初识…