零基础详解C语言指针进阶

目录
  • 前言
  • 1.字符指针
    • 例题 1
  • 2.指针数组
    • 例题 2
  • 3.数组指针
    • 3.1数组指针的定义
    • 3.2 &数组名与数组名
    • 3.3 数组指针的使用
  • 4.数组与指针在函数里的传参
    • 4.1 一维数组的传参
    • 4.2 二维数组的传参
    • 4.3 一级指针的传参
    • 4.4 二级指针的传参
  • 5.函数指针
  • 6. 函数指针数组
    • 用函数指针数组实现一个计算器
  • 7.回调函数

前言

这是指针的进阶,如果想入门指针的朋友可以关注我的另外一篇文章—c语言 指针零基础讲解

坚持看完,一定会有很大的收获~~

那接下来—起航

1.字符指针

我们目前知道整形指针,浮点型指针,字符指针跟他俩类型

字符指针—顾名思义就是指针,一个char*类型的指针

在讲解字符指针前,我先提一下怎么连续创建多个指针

连续创建多个指针的方法:

你可能会想到用:

int a ,b;

int* a,b;

或者

#define PINT int*

int main(){

int a ,b;

p a,b;

}

但是实际上这样创建的结果是:

创建一个整形指针int*a与整形变量int b.

创建指针的正确打开方式:

//方案一,直接定义两次
int a,b;
int*a; int*b;
//方案二,采用typedef重定义
typedef int* pint
{
	int a,b;
pint pa, pb;//此时就是定义int *pa与int *pb都是指针变量
return 0;
}

下面给出一个简单的代码:

char ch='w';
char* p=ch;
char* p="abcde";

定义一个char类型的变量ch,将ch地址放在指针变量p中

此时p存放的就是字符w的地址

这个很容易理解,那么char* p="abcde"是什么意思呢

实际上这次的p存放的是字符串abcde的首元素的地址,也就是a的地址

有了首地址,就很容易找到后续元素的地址

例题 1

    判断下面代码是否相等
    char arr1[] = "abcdef";
    char arr2[] = "abcdef";

    const char* str1 = "abcdef";
    const char* str2 = "abcdef";
#include<stdio.h>//证明相等关系
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	const char* str1 = "abcdef";
	const char* str2 = "abcdef";
	if (arr1 == arr2)
		printf("arr1==arr2\n");
	else
		printf("arr1!=arr2\n");
	if (str1 == str2)
		printf("str1==str2\n");
	else
		printf("str1!=str2\n");

	return 0;
}

为什么arr1!=arr2; str1==str2

首先创建数组,arr1与arr2,先向系统申请两个不同的空间,然后将abcdef放入两个不同的空间里,所以这两个空间的地址当然就不相同

其次是str1与str2的abcdef只存储在只读存储区(这跟const无关,const起到强调的作用,实际上有无const的意思是相同的),就是不能更改其中的元素;

这时候两字符串的内容相同,系统就不会在浪费多余的空间去储存两个不同的内容~

所以就形成str1==str2,实际上这两个变量储存的都是a的地址

2.指针数组

在这之前我们知道整形数组,浮点型数组等

意思就是储存整形与浮点型数子的数组

指针数组就是存放指针的数组,实际上还是数组,里面存放着不同类型的指针

int*arr[5];//整形指针数组
char*arr[5];//一级字符指针数组
char**arr[5];//二级字符指针数组

知道定义,那如何使用呢

例题 2

多组打印字符串

#include<stdio.h>
int main()//指针数组
{
	char* arr[] = { "abcdef","ghi" ,"jklmn" };
	//打印
	int i = 0;
	int sz = sizeof (arr) / sizeof (arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%s\n",arr[i]);
	}
	return 0;
}

其中的    char* arr[] = { "abcdef","ghi" ,"jklmn" }就是指针数组,存放的就是char类型的指针,

他的作用就相当于:

char arr1[] = "abcdef";
char arr2[] = "ghi";
char arr3[] = "jklmn";

打印的结果就是:

打印整形的数组

#include<stdio.h>
int main()
{
	//打印整形数
	int arr1[] = { 1, 2, 3, 4, 5};
	int arr2[] = { 2, 3, 4, 5, 6};
	int arr3[] = { 3, 4, 5, 6, 7};
	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("\n");
	}
	return 0;
}

3.数组指针

3.1数组指针的定义

有了指针数组的概念,相信很多人就知道数组指针的概念

跟你们想的一样

数组指针—就是指针,什么指针呢,存放数组的指针

int *pint;//能够指向整形数据的指针
char *p;//能够指向字符数据的指针
char (*p)[10];能够指向数组的指针

它的类型包括int(*)[],  char(*)[]

解读一下,其中的(*)就代表是一个指针[]就代表是一个数组的指针,char或者int就代表数组中的数据是啥类型的元素

(0)

相关推荐

  • c语言 指针零基础讲解

    1.指针是什么(可能有点难理解) 指针的是啥? 指针实际上就是地址,地址就是系统给定的编号,编号就是一个个内存单元. 在某种情况来说指针=地址=编号=内存单元. 指针就是地址,顾名思义,就是可以用来寻找目标的. 所以指针变量就是存放地址的变量. 当然我们口头上常说的指针就是指针变量~ 那指针是怎么产生的呢,也就是说内存是怎样产生的呢? 我们知道我们的计算机就是32位或64位系统组成,这32与64在物理上就是32根物理电线或64根物理电线组成.这物理电线通电时,就会产生高电频,从而产生电信号,再由

  • C语言数组和指针,内存之间的关系

    首先论证一维数组和一级指针之前的关系,我们常常使用一级指针指针的方式访问一维数组,只有对内存的理解到位才能理解它们直接的关系. 1.数组名是数组的首地址 2.对数组名取地址得到的还是数组的首地址 3.数组的访问方式其实就是首地址+偏移的寻址访问 我们在程序中会定义很多变量,有基本类型和自定义类型在进行开发的时候我对内存的访问访问就是通过变量名赋值的方式读写内存但是如果你看到的直接变量的符号名你将不可能理解内存.每一种类型都有字节宽度,char 1字节 short 2字节 int 字节float

  • C语言中指针常量和常量指针的区别

    在面试中我们经常会被面试官问到什么是常量指针,什么又是指针常量. 指针常量就是指针本身是常量,指针里面所存储的内容(内存地址)是常量,不能改变.但是,对应内存地址里存的内容是可以通过指针改变的. 常量指针就是指向常量的指针,指针中所存地址中对应的值是常量,不能通过指针来修改它的值.但是,指针自身不是常量,它自身的值可以改变,从而指向另一个地址. 指针常量与常量指针的声明 指针常量的声明:数据类型 * const 变量名. 常量指针的声明:数据类型 const * 变量名 或者 const 数据类

  • C语言中const,指针和引用的关系

    目录 const 与指针 const 与引用 const 与指针.引用 总结 const 与指针 我们写一段代码来探究以下 int a = 10, b = 20; int* p1 = &a; *p1 = 100; p1 = &b; const int* p2 = &a; int const* p3 = &a; int* const p4 = &a; const int* const p5 = &a; 在上面 const int* p2;与int const*

  • C语言指针的图文详解

    目录 指针是什么? 指针和指针变量 1. 指针类型决定了指针进行解引用操作的时候,能访问空间的大小 2. 指针加减整数 野指针 野指针的成因 指针和数组 二级指针 指针数组.数组指针 总结 指针是什么? 指针(Pointer)是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 换句话说就是可以通过指针找到以它为地址的内存单元. 理解:内存图解. 指针是个变量,存放内存单元的地址(编号). int main(){ int a = 10;//在内存中开辟空间存储 int* p = &a;

  • C语言 指针数组进阶详解

    目录 指针与数组中的sizeof与strlen sizeof strlen 数组名 1.一维数组 整型数组 字符数组 指针数组 2.二维数组 指针笔试题 笔试题1 笔试题2 笔试题3 笔试题4 笔试题5 前言:指针与数组的知识往往让我们无法给自己定位,似乎是懂了,但真的碰上了又一言难尽.接下来有一些关于指针与数组的知识和例题讲解,来看看你对指针和数组到底有多了解吧! 指针与数组中的sizeof与strlen sizeof sizeof值关注占用空间的大小,单位是字节,不关注元素的类型,是一个操作

  • 从头学习C语言之指针和数组

    目录 指针和数组: 示例: 总结 指针和数组: 数组名其实是数组第一个元素的地址. %p用来打印地址,为十六进制 &:取址操作符 如果用一个指针指向数组,应该怎么做呢? char *p; p=a;//语句1 p=&a[0];//语句2 指针的运算: 当指针指向数组元素的时候,我们可以对指针变量进行加减运算,这样做的意义相当于只想距离指针所在位置向前或向后第n个元素. 对比标准的下标法访问数组元素,这种使用指针进行间接访问的方法叫做指针法. 需要郑重强调的是:p+1并不是简单的将地址加1,二

  • 深入理解C语言的指针

    目录 起源 进程内存布局 栈 设置 分配方式 特点 堆 分配方式 特点 堆与栈区别 扩展 总结 起源 之前在知乎上看了一句话,指针是C的精髓,也是初学者的一个坎.换句话说,内存管理是C的精髓,C/C++可以直接跟OS打交道,从性能角度出发,开发者可以根据自己的实际使用场景灵活进行内存分配和释放.虽然在C++中自C++11引入了smart pointer,虽然很大程度上能够避免使用裸指针,但仍然不能完全避免,最重要的一个原因是你不能保证组内其他人不适用指针,更不能保证合作部门不使用指针. 那么为什

  • 让我们一起来对C语言指针再分析

    目录 初次认识指针,我们大概了解到一下知识. 第一站 字符指针----存放字符地址的指针 1.使用方法 2. 指针数组----存放指针的数组 3. 数组指针 3.1 数组指针的定义 3.2 &数组名VS数组名 3.3 数组指针的使用 总结 初次认识指针,我们大概了解到一下知识. 1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间. 2. 指针的大小是固定的 4/8 个字节( 32 位平台 /64 位平台). 3. 指针是有类型,指针的类型决定了指针的 +- 整数的步长,指针解引用操作的

  • 零基础详解C语言指针进阶

    目录 前言 1.字符指针 例题 1 2.指针数组 例题 2 3.数组指针 3.1数组指针的定义 3.2 &数组名与数组名 3.3 数组指针的使用 4.数组与指针在函数里的传参 4.1 一维数组的传参 4.2 二维数组的传参 4.3 一级指针的传参 4.4 二级指针的传参 5.函数指针 6. 函数指针数组 用函数指针数组实现一个计算器 7.回调函数 前言 这是指针的进阶,如果想入门指针的朋友可以关注我的另外一篇文章—c语言 指针零基础讲解 坚持看完,一定会有很大的收获~~ 那接下来—起航 1.字符

  • c++ 智能指针基础详解

    简介 在现代 C++ 编程中,标准库包含了智能指针(Smart pointers). 智能指针用来确保程序不会出现内存和资源的泄漏,并且是"异常安全"(exception-safe)的. 智能指针的使用 智能指针定义在头文件 memory 里的命名空间 std 中.它对于资源获取即初始化(RAII, Resource Acquisition Is Initialization) 编程理念至关重要.该理念的目的是保证对象初始化的时候也是资源获取的时候,从而使对象的所有资源在单行代码中创建

  • C语言编程数据结构基础详解小白篇

    目录 数据结构的基本信息 数据结构 逻辑结构 1,集合结构 2,线性结构 3,树结构 4,图结构或网结构 存储结构 顺序储存结构 链式储存结构 抽象数据类型 介绍 数据结构的基本信息 数据:是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称.如:字符串,实数整数.... 数据元素:是数据的基本单位,在计算机中通常被作为一个整体进行考虑与处理.如组成通讯录的每一个人的信息,数据元素可以完整的描述一个对象. 数据项:是组成数据元素的,具有独立意义的,不可分割的最小单位(也就是

  • C 语言基础----详解C中的运算符

    C语言中又有哪些运算符呢? 如下所示: ※ 算术运算符 ※ 赋值运算符 ※ 关系运算符 ※ 逻辑运算符 ※ 三目运算符 C语言基本算术运算符如下表: 除法运算中注意: 如果相除的两个数都是整数的话,则结果也为整数,小数部分省略,如果两数中有一个为小数,结果则为小数. 取余运算中注意: 该运算只适合用两个整数进行取余运算 运算后的符号取决于被模数的符号,如(-10)%3 = -1;而10%(-3) = 1. 注:C语言中没有乘方这个运算符,也不能用×,÷等算术符号. 赋值运算符 下表列出了 C 语

  • 详解C语言-二级指针三种内存模型

    二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {"abc", "def", "ghi"}; 这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char * []),数组的每个元素都是一个地址. 在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为 char *tm

  • C语言详解函数与指针的使用

    目录 一.函数类型 二.函数指针 三.回调函数 四.小结 一.函数类型 C 语言中的函数有自己特定的类型 函数的类型由返回值,参数类型和参数个数共同决定,如 int add(int i, int j)的类型为 int(int, int) C 语言中通过 typedef 为函数类型重命名 typedef type name(parameter list) 如 typedef int f(int, int); typedef void p(int); 二.函数指针 函数指针用于指向一个函数 函数名是

  • 详解C语言中二级指针与链表的应用

    目录 前言 二级指针讲解 链表的应用 定义双链表的结构体 创建双链表 前言 这篇文章即将解决你看不懂或者不会写链表的基本操作的问题,对于初学者而言,有很多地方肯定是费解的.比如函数的参数列表的多样化,动态分配内存空间函数malloc等,其实这些知识和指针联系紧密,尤其是二级指针.那么开始好好的学习这篇文章吧! 二级指针讲解 简述:其实就是一个指针指向另一个指针的地址. 我们都知道指针指向地址,但是指针自身也是一个变量,当然也可以被二级指针所指向. 语法:形如 int x = 10; int *q

  • 详解C语言进程同步机制

    本文是对进程同步机制的一个大总结(9000+字吐血总结),涵盖面非常的全,包括了进程同步的一些概念.软件同步机制.硬件同步机制.信号量机制和管程机制,对每种机制结合代码做了详细的介绍,并且对琐碎的知识点和概念解释的非常清晰. ​ 在前面的博客中讲述了进程的状态及其状态的转换,每种状态的含义和转换的原因.同样我们也知道,在OS引入了进程后,可以使系统中的多道程序可以并发的执行,进程的并发执行一方面极大的提高了系统的资源利用率和吞吐量,但是另一方面却使系统变得更加复杂,如果不能采取有效的措施,对多个

  • 详解go语言单链表及其常用方法的实现

    目的 在刷算法题中经常遇到关于链表的操作,在使用go语言去操作链表时不熟悉其实现原理,目的是为了重温链表这一基础且关键的数据结构. 1.链表的特点和初始化 1.1.链表的特点 用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的) 1.2.结点 结点(node) 数据域 => 存储元素信息 指针域 => 存储结点的直接后继,也称作指针或链 首元结点 是指链表中存储的第一个数据元素的结点 头结点 是在首元结点之前附设的一个结点,其指针域指向首元结点(非必须) 头指

  • 详解go语言json的使用技巧

    本文整理了一部分我们平时在项目中经常遇到的关于go语言JSON数据与结构体之间相互转换的问题及解决办法. 基本的序列化 首先我们来看一下Go语言中json.Marshal()(系列化)与json.Unmarshal(反序列化)的基本用法. type Person struct { Name string Age int64 Weight float64 } func main() { p1 := Person{ Name: "小明", Age: 18, Weight: 71.5, }

随机推荐