首页 > 其他分享 >03-指针进阶

03-指针进阶

时间:2023-06-23 22:00:30浏览次数:31  
标签:03 arr 进阶 int void char 数组 指针

目录

一. 字符指针

1.1 使用方式一

  • 操作字符
int main()
{
 char ch = 'w';
 char *pc = &ch;
 *pc = 'p';
 return 0;
}

1.2 使用方式二

  • 标识字符串: 这里值得注意的是, "hello bit"是把h的地址给到pstr, 并且"hello bit."是一个字符串常量保存在静态区中其值是不能修改的, 使用const可以将运行时错误变成编译时错误. 使错误能更好的被发现
#include <stdio.h>

int main()
{
 const char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗?
 printf("%s\n", pstr);
 return 0;
}

1.3 面试考点

  • 数组的创建是在栈区, str1和str2是两个不同的变量. 而str3和str4保存的地址都是相同的, 即"hello bit."的首字符的地址.
#include <stdio.h>
int main()
{
 char str1[] = "hello bit.";
 char str2[] = "hello bit.";
 const char *str3 = "hello bit.";
 const char *str4 = "hello bit.";
 if(str1 ==str2)
 printf("str1 and str2 are same\n");
 else
 printf("str1 and str2 are not same\n");
 
 if(str3 ==str4)
 printf("str3 and str4 are same\n");
 else
 printf("str3 and str4 are not same\n");
 
 return 0;
}

/*
运行结果: 
str1 and str2 are not same
str3 and str4 are same
*/

二. 数组指针

2.1 数组指针的表示形式

  • 需要和指针数组的概念做区分, 数组指针是一个指针指向数组的指针, 二指针数组是数组用于保存指针的数组.
int* p[10];    //这里p先和[]结合, 表示数组. 然后数组元素的类型时int*
int (*p)[10];  //这里p先和*结合为*p表示指针, 指针指向一个数组[]该数组大小10个元素, 且元素类型为int

2.2 数组指针的使用

  • 通常应用在操作二维数组的情景中, 需要注意的是二级指针是无法操作二维数组的, 以a[i][j]为例. 32位机上指针+1永远跳过4个字节, 而二维数组中a[i + 1]会跳过j*4个字节大小的空间. 二级指针无法满足二维数组特性.
//用法一:
#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,0};
 int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
 //但是我们一般很少这样写代码
 return 0;
}

//用法二:
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{
 int i = 0;
 for(i=0; i<row; i++)
 {
 for(j=0; j<col; j++)
 {
 printf("%d ", arr[i][j]);
 }
 printf("\n");
 }
}
void print_arr2(int (*arr)[5], int row, int col)
{
 int i = 0;
 for(i=0; i<row; i++)
 {
 for(j=0; j<col; j++)
 {
 printf("%d ", arr[i][j]);
 }
 printf("\n");
 }
}
int main()
{
 int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
 print_arr1(arr, 3, 5);
 //数组名arr,表示首元素的地址
 //但是二维数组的首元素是二维数组的第一行
 //所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
 //可以数组指针来接收
 print_arr2(arr, 3, 5);
 return 0;
}

2.3 内容拓展

  • 试着解释int (*p[10])[5];的含义
    int(*p[10])[5];                  //大小为10的数组其数组元素为数组指针,指向大小为5的整形数组.
               
	int arr[5] = { 1, 2, 3, 4, 5 };  

	p[0] = &arr;                     //p[0]是数组指针, 将数组arr的地址给p[0];

	printf("%d", *(*p[0]));          //这里*(p[0])也就相当于*(&arr), 得到arr首元素地址, 然后*(*p[0])相当于*arr得到arr[0];

三. 函数指针

3.1 区分函数指针和指针函数

  • 首先看变量先与哪个部分结合, 本质就是什么.
void* func1();    //这里func1与()结合表示一个函数, 该函数类型为void*, 表示返回值为void* 的函数
void (*func2)();  //这里func2与*结合为*func2表示一个指针, 指针指向一个返回值为void的函数void ();

3.2 看两个有趣的代码

  • 及时两段代码的含义
//代码一
(*(void (*)())0)();  //首先是将0强制类型转换为(一个指向void类型的函数的指针类型), 此时0就是一个函数地址, 然后*()0, 就是找到地址为0的这个函数去调用.
//代码二
void (*signal(int , void(*)(int)))(int);

3.2 函数指针数组

  • 要将函数地址放进一个数组中, 该数组如何定义
int (*p[10])();  // 首先p是一个数组, 数组元素都是指针, 指向返回值类型为int的函数.

四. 回调函数

4.1 什么是回调函数

  • 将函数A作为参数传递给函数B当B被调用时去回调函数A, 此时A就被称为回调函数, 该机制称为回调机制.
void testA(){};

void testB(void (*pf)()){};

int main()
{
  testB(&testA); //将函数A的地址作为参数传递给函数B

return 0;
}

4.2 应用案例, 实现qsort可满足任意类似的数组进行冒泡排序

#include<stdio.h>

void myQSort(void* arrAdd, int arrSize, int arrWidth, void (*cmp)(void* e1, void* e2));
int cmpFunctionInt(void* e1, void* e2);
void changeAdd(char* e1, char* e2, int width);

int main()
{
	int arr[] = { 1, 3, 5, 2, 4, 8, 9, 11, 6, 14, 7, 12, 13, 10 };
	int sz = sizeof(arr) / sizeof(int);

	myQSort(arr, sz, sizeof(int), cmpFunctionInt);

	for (int i = 0; i < sz; i++)
	{
		printf("%d, ", arr[i]);
	}

	return 0;
}

void changeAdd(char* e1, char*e2, int width)
{
	char e;
	for (int i = 0; i < width; i++)
	{
		e = *e1;
		*e1 = *e2;
		*e2 = e;
		e1 ++;
		e2 ++;
	}
}

int cmpFunctionInt(void* e1, void* e2)
{
	return (int*)e1 - (int*)e2;
}

void myQSort(void* arrAdd, int arrSize, int arrWidth, void (*cmp)(void* e1, void* e2))
{

	for (int i = 0; i < arrSize; i++)
	{
		for (int j = i; j < arrSize - 1; j++)
		{
			if (*((char*)arrAdd + j * arrWidth) > *((char*)arrAdd + (j + 1) * arrWidth))
			{
				changeAdd((char*)arrAdd + j * arrWidth, (char*)arrAdd + (j + 1) * arrWidth, arrWidth);
			}
		}
	}
}

标签:03,arr,进阶,int,void,char,数组,指针
From: https://www.cnblogs.com/Deng-S/p/17500266.html

相关文章

  • Codeforces 1603D. Artistic Partition
    题目链接:D-ArtisticPartition题目大意:要求将\([1,n]\)分成\(k\)段,使得每段对应的\(c(l,r)\)之和最小,其中\(c(l,r)=\sum_{i=l}^r\sum_{j=i}^r[\gcd(i,j)\gel]\)。首先注意到当\(r<2l\)时,\(c(l,r)=r-l+1\)。所以当\(2^k-1\gen\)时答案即为\(n\)。考虑\(\texttt......
  • linux-c-tina-'伪'裸机开发--寄存器操作篇
    之所以叫伪裸机,是因为还是基于操作系统的,并不能真正的裸机开发。/dev/mem文件:首先得了解一下什么是/dev/mem文件,有什么作用:/dev/mem简单来说是作为一个linux内核几乎通用的硬件地址映射文件,可以通过这个向硬件寻址,从而操作寄存器。由图可见,此文件大概占1bytes的大小。并且这......
  • 机器学习从入门到进阶所需学习资料-包括书、视频、源码
    本文整理了一些入门到进阶机器学习所需要的一些免费的精品视频课程,一些优质的书籍和经典的代码实战项目。视频1.1吴恩达老师机器学习课程:•Coursera•网易云课堂•英文笔记•中文笔记、字幕1.2吴恩达深度学习课程•Coursera•网易云课堂•笔记1.3斯坦福CS231n:Co......
  • 02-指针入门
    目录一.什么是指针1.1指针的两种含义1.2指针表示含义二.指针类型的意义2.0问题引出2.1不同类型指针步长不同2.2不同类型指针解引用的权限不同三.野指针3.1指针未初始化造成野指针3.2指针越界访问造成野指针3.3指针指向的空间释放(动态内存)3.4如何规避野指针四.指针......
  • 指针详解
    一、指针运算给一个指针变量+1,通常情况下不是给指针本身+1,而是”迈一步“,步长根据指针的类型来确定。intmain(){ chara=1; intb=1; intarr[10]={0}; char*pa=&a; int*pb=&b; int(*parr)[10]=&arr; printf("%p\n",pa); printf("%p\n",pa+1);//......
  • 【九】解决粘包的进阶方法
    【九】解决粘包的进阶方法为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据struct模块该模块可以把一个类型,如数字,转成固定长度的bytesstruct.pack(‘i’,1111111111111)。。。。。。。。。......
  • Vue进阶(贰零零):window.onresize事件在vue项目中的应用
    属性window.onresize属性可以用来获取或设置当前窗口的resize事件的事件处理函数。在窗口大小改变之后,就会触发resize事件.//vue页面<template><divid='echart'>报表</div></template><script>exportdefault{data(){return{};......
  • 强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛
    强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛策略、时序差分等以及Qlearning项目实战1.核心词汇概率函数和奖励函数:概率函数定量地表达状态转移的概率,其可以表现环境的随机性。但是实际上,我们经常处于一个未知的环境中,即概率函数和奖励......
  • 强化学习从基础到进阶-案例与实践[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛策略、时序差
    强化学习从基础到进阶-案例与实践[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛策略、时序差分等以及Qlearning项目实战策略最简单的表示是查找表(look-uptable),即表格型策略(tabularpolicy)。使用查找表的强化学习方法称为表格型方法(tabularmethod),如蒙特卡洛、Q学习和Sarsa。本章通过最......
  • 强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛
    强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛策略、时序差分等以及Qlearning项目实战1.核心词汇概率函数和奖励函数:概率函数定量地表达状态转移的概率,其可以表现环境的随机性。但是实际上,我们经常处于一个未知的环境中,即概率函数和奖励......