首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C语言:指针2(超详细讲解)

在一维数组中我们需要通过数组首元素地址来访问全部元素 这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且 是数组⾸元素的地址,我们来做个测试 下面这个代码我们可以看到地址是一样的说明...指向数组首元素地址 循环输入:p一直都是首元素地址不会变,+ i跳过i个字节 打印的话p的首元素地址也不会变+i跳过i个字节然后解引⽤ int main() { int arr[10] = { 0 }...; //计算数组有多少个元素 int sz = sizeof(arr) / sizeof(arr[0]); //指向数组首元素地址 int* p = &arr[0]; //输入 for (int...2个数值进行交换 最后就是打印了 指针数组 指针就是存放指针的数组 当我们需要创建很多个指针,总不能一个一个创建吧 我们就需要创建个指针数组把这些指针放进去就行了 下面这个就是把a,b,c的指针放到指针数组里...然后循环通过i访问下标把这3个值改成99,然后打印 当然指针数组里每个地址都是int*类型的,也可以说是指针 指针数组模拟二维数组 我们通过 i 来访问arr1,arr2,arr3 j是访问这些数组的每个元素

9010

第七节(指针)

首先打印ctr元素的编号,然后分别打印3个数组中该元素对应的地址。 4.3 指针算术: 假设有一个指向数组第1个元素的指针,该指针必须以该数组中储存的数据类型大小来递增。...如何通过指针表示法访问数组元素? 答案是:指针算术 指针算术非常简单。只需关注两种指针运算:递增和递减。 (1)指针递增 递增指针时,递增的是指针的值。...每次计数,第33行都在调用printf()函数时解引用两个指针,并打印它们的值。 然后通过递增运算符分别递增每个指针,以指向数组的下一个元素。随后继续迭代下一轮for循环。...在大多数情况下,还要传递数组中元素的个数。 在函数中,可以通过下标表示法或指针表示法,通过指针来访问数组元素。 警告:给函数传递一个普通变量时,传递的是该变量的副本。...数组名是指向该数组首元素的指针。通过指针的运算特性,可以很方便地使用指针来访问数组元素。实际上,数组下标表示法就是指针表示法的特殊形式。 本次还介绍了通过传递指向数组的指针来将数组作为参数传递给函数。

20140
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C语言---动态内存管理

    有时候我们需要的空间⼤⼩在程序运⾏的时候才能知道,那数组的编译时开辟空间的⽅式就不能满⾜了。 C语⾔引⼊了动态内存开辟,让程序员⾃⼰可以申请和释放空间,就⽐较灵活了。...,realloc帮我们释放 总之: realloc函数返回的地址可能是一个旧的地址,也可能是一个新的地址,也可能是一个空指针 那么我们应该拿什么东西进行指针接收呢?...i < 5; i++)// { *p = i; p++; }//5次循环之后,p就指向了第6个元素了 free(p);//这里的p就是第6个元素的地址了...NULL进行解引用操作,程序就会崩溃的 //上面函数内的malloc函数申请的空间并没有进行及时的释放内存,这样会造成内存泄漏的问题 printf(str);//printf接受了首元素地址就能进行打印了...";//局部数组 // return p;//p是这个字符串的起始元素的地址 //} //void Test(void) //{ // char* str = NULL;//str里面放的是空指针

    8810

    【数据结构】C语言实现带头双向循环链表万字详解(附完整运行代码)

    带头双向循环链表的元素位置查找. 带头双向循环链表的任意指定元素前插入. 带头双向循环链表的尾删. 带头双向循环链表的头删. 带头双向循环链表的任意指定元素删除. 带头双向循环链表打印....: 如图,我们在尾插时首先要找到原链表的尾,即head->prev,然后我们需要改变四个指针的指向关系: 使旧尾的next连接上newnode 使newnode的prev连接上旧尾 使head的prev...prev = newnode; newnode->next = phead; } 7.带头双向循环链表元素的头插 头插示意图: 如图,我们在头插时首先需要找到旧头,即head->next,然后需要改变四个指针的指向关系...因为,如果我们先更改了head的next指针的指向,后续想要找到旧头就只能再循环遍历一遍链表了,这样会非常麻烦....了解了这点后,带头双向循环链表的打印逻辑很简单,顺着头指针的后一个结点向后循环遍历打印整个链表结点的数据域即可,当遍历指针再次走到head结点时,则代表已经遍历打印完链表的所有元素,这时跳出循环即可.

    23110

    深入解析 Go 中 Slice 底层实现

    不过传指针会有一个弊端,从打印结果可以看到,第一行和第三行指针地址都是同一个,万一原数组的指针指向更改了,那么函数里面的指针指向都会跟着更改。 切片的优势也就表现出来了。...用切片传数组参数,既可以达到节约内存的目的,也可以达到合理处理好共享内存的问题。打印结果第二行就是切片,切片的指针和原来数组的指针是不同的。...它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。...空切片和 nil 切片的区别在于,空切片指向的地址不是nil,指向的是一个内存地址,但是它没有分配任何内存空间,即底层元素包含0个元素。 最后需要说明的一点是。...通过打印的结果,我们可以看到,在这种情况下,扩容以后并没有新建一个新的数组,扩容前后的数组都是同一个,这也就导致了新的切片修改了一个值,也影响到了老的切片了。

    87110

    Go切片数组深度解析

    C与Java的数组类型不一样,NewArray用于创建一个数组,从源码中可以看出最后返回的是 &Array{}的指针,并不是第一个元素的指针,在Go中数组属于值类型,在进行传递时,采取的是值传递,通过拷贝整个数组...编译器对数组函数中做两种不同的优化: 当元素数量小于或者等于 4 个时,会直接将数组中的元素放置在栈上; 当元素数量大于 4 个时,会将数组中的元素放置到静态区并在运行时取出; var arr [5]int...,不过传指针会有一个弊端,从打印结果可以看到,指针地址都是同一个,万一原数组的指针指向更改了,那么函数里面的指针指向都会跟着更改。...,通过传递切片,地址是不一样的,数组值相同。...所以每次打印 Value 的地址都不变。 由于 Value 是值拷贝的,并非引用传递,所以直接改 Value 是达不到更改原切片值的目的的,需要通过 &slice[index] 获取真实的地址。

    58430

    Go 基础面试题

    所谓的“地址传递”或“引用传递”在 Go 中是通过传递指向数据的指针来实现的,这样在函数内部可以通过指针来修改原始数据。...Semantic) 也就是通过传递参数的地址,即指针,实现的 通过指针可以在函数内部修改原始数据 只有指针的副本被创建并传递给函数,而所指向的数据没有被复制 举例说明: package main import...区别总结: 数组传递时通过完整复制,函数接收的是整个数组的一个副本。 切片传递是通过引用复制,函数接收的是指向相同底层数组的切片副本。...指针:这个指针指向数组的第一个可以通过 slice 访问到的元素。这不一定是数组的第一个元素。 长度:长度是 slice 的长度,即 slice 中元素的数量。...这是通过创建一个新的底层数组并将旧数组的元素赋值到新数组中来实现的。扩容的具体步骤是: 计算新的容量的大小。新容量的选择遵循以下规则: 如果旧容量小于 1024 个元素,通常会扩大到旧容量的两倍。

    26310

    C语言----深入理解指针(1)

    -指针 指针的关系运算 //循环打印数组的内容 //int main() //{ // int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; // int sz =...++;//打印完p++往后走一步,整型指针加一就是向后挪了一个整型 // //循环十次就能把这个数组的内容打印出来 // } // return 0; //} //获取数组第一个数字的地址赋值给...end++;//直到enf走到\0不满足条件就不进行循环了,此时的*end指向的就是\0 } return end-star;//两个指针相减得到的就是指针之间元素的个数 }//数组中最后一个元素的指针减去第一个指针的元素得到的...};//数组初始化 int i = 0; int* p = &arr[0];//将数组第一个元素的地址给p for (i = 0; i 循环11次...= NULL) // { // *P = 200; // } // return 0; // //} //当指针变量指向一块区域时,我们可以通过指针访问该区域, //

    9310

    指针+数组指针+字符指针+指针数组

    p中,此时指针变量p就是指向变量i,注意p中的是i的地址;然后我通过对指针解引用,就是在指针前面加一个*,来通过地址访问i的内存,也就是i的值;很明显打印的值就是i的值;同理,浮点型,字符型的变量都是可进行如上操作的...3.打印的第一行和打印的第3行的地址是相同的,说明数组名就是数组首元素的地址,而对数组取地址的这个地址也同样是数组首元素的地址: 结论:二者都是数组首元素的地址,不同的是,步长大小不同; 我们再回到数组指针上...; 正文 普通指针打印数组元素 上代码: 这里我先把指针指向数组的首元素,通过循环就可以实现数组的打印啦;值得一提的是p=arr;p就大致等同数组名了,所以我可以通过第二种打印方式实现打印数组各元素;...,其实我们平时打印字符串都是找到字符串的首地址,然后以%s的格式从地址向后打印;而指针正好指向的字符串,指针变量里面储存的就是字符串的首元素地址(这个跟数组是一样的);然后我们就可以完成打印啦。...2.二维数组的数组名代表的是一行的一维数组的整个地址,当我们用数组指针指向二维数组时,就直接取二维数组的数组名就好啦。

    7510

    C语言----深入理解指针(3)

    int a=10 int *p=&a 那么数组指针就是指向数组的指针 数组指针变量存放的是数组的地址 数组的地址--&数组名 指针数组 1.是数组 2.是存放指针的数组 char* arr[6]---...--char*是数组的元素类型---存放字符串指针的数组 int *arr2[5]---存放整型指针的数组 数组指针 是指针,指向数组的指针 *p--表示这是一个指针变量 这个指针指向的是数组,得有大小...在前面加上类型 int (*p)[10]--这里的p就是数组指针,P指向的数组有10个元素,每个元素的类型是int p的类型是int (*)[10] 将数组的地址取出来,存放在指针变量里面, char(..., int r, int c) { //两层循环,第一层循环打印行,第二层循环打印列 for (int i = 0; i < r; i++) { for (int.../使用数组指针存放第一行的地址,传过来的是一个一维数组,那么我们就需要一个数组指针来接收 {//这个数组指针并不是指向的二维数组,而是指向的是这个二维数组的第一行 //两层循环,第一层循环打印行

    9110

    C语言---深入指针(2)

    ,右边是数组的形式 //arr+i是地址,地址解引用,找到的就是这个地址指向的那个数 //右边的是通过数组下标来访问对应的数字 //arr[i]*(arr + i) *(i+arr...,数组名表示的是数组首元素的地址 return 0;//传过去的是地址,要用指针接收 }*/ //打印结果为 // sz1=10 //sz2 = 2 //为什么二者结果不一样 //test(arr...5]----存放字符指针的数组--放的都是指向字符类型的指针 int *arr[5]-----存放整型指针的数组 int*arr5说的就是一个包含5个元素的数组,每个元素都是指向int类型的指针....在C语言中,int*arr[5] 声明了一个包含5个元素的数组,每个元素都是一个指向int类型数据的指针。这个数组可以存储指向整数的指针,可以是指向整数变量的指针,也可以是指向整数数组的指针。...int类型的指针 在这个例子中,arr数组的前三个元素分别指向变量num1、num2和num3的地址。

    9310

    【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    数组 与 指针 区别 ( 1 ) 概念简介 ( ① 数组名就是首元素地址 不需要寻址 | ② 指针 中保存一个地址 指向首元素地址 需要寻址 | printf 打印 数组 或 指针 : 根据占位符自动判断打印地址还是打印内存中的具体内容...数组 与 指针 区别 ( 1 ) 概念简介 ( ① 数组名就是首元素地址 不需要寻址 | ② 指针 中保存一个地址 指向首元素地址 需要寻址 | printf 打印 数组 或 指针 : 根据占位符自动判断打印地址还是打印内存中的具体内容...正确使用数组 p 打印字符串的方法(模仿编译器行为手工寻址) : p 是指针, 指向 "Hello", 但是本文件中声明为类数组, 数组与指针打印时编译器会做不同处理; // ( 1 ) 首先 p 是地址...指针 - 1 指向数组的上一个元素 ; 数组运算规则 : 1.数组本质 : 数组的***元素存储空间是连续的***, 从数组首地址(数组元素首地址 | 数组名)开始 ; 2.数组空间大小 : 数组的空间通过..., &数组名 是数组的首地址 ; 3.数组首地址 : & 数组名 是数组首地址 , 数组首地址 不是 数组名( 数组首元素地址 ) ; 4.数组指针定义 : 数组指针是通过 定义 数组类型 的指针;

    3.7K30

    函数的返回值指向一个指针

    create_array() 函数接收一个整数 n,然后动态分配了一个 n 个元素的整型数组,将数组中的每个元素初始化为其下标值,最后将指向数组的指针作为函数的返回值返回。...在 main() 函数中,调用 create_array() 函数并将其返回值指向一个整型指针 arr。然后,使用一个循环遍历数组的每个元素,并打印出其值。最后,释放数组所占用的内存空间。...在函数体内,使用一个循环遍历数组中的每个元素,并调用传递进来的函数指针 cb 来处理每个元素。...在调用 apply() 函数时,将一个名为 print() 的函数指针作为参数传递给它,这个函数会将整型参数打印到标准输出中。...指针作为参数传递进函数时,实际上传递的是指针所指向的内存地址,函数可以通过指针来访问、修改指针所指向的内存中的数据。 定义了一个名为 swap() 的函数,它有两个参数,都是指向整型变量的指针。

    69420

    【C语言】qsort函数介绍

    ,回调函数就是一个通过函数指针调用的函数。...如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数 时,被调用的函数就是回调函数。...size,int(*compar)(const void*,const void*)); 我们来一个一个分析,第一个参数是指针指向的是待排序数组的第一个元素,由于不知道你会传递什么指针类型,就用void...第二个参数是base指向的待排序数组的元素个数,第三个参数是每个元素的大小(字节长度),最后一个传入的是一个函数compar的指针,指向的是两个元素的比较函数。...我们在定义比较函数时,也要注意,传过来的元素地址不管什么类型,都要将它强制转换成整型指针,这是因为因为比较函数返回值就是整型。

    7410

    【C++】整形数|组和字符数|组输出的差异解析

    在C++中,应用数组名时,系统将它解释为指向数组首元素的指针(也就是记录数组内存地址)。 cout对指针输出时,将它作为内存地址,因此输出为“0x70fde0”。...C++ 数组名的解释 在C++中,数组名不会被直接解释为数组内容。而是: 在不使用特定操作时,数组名会“藏存”为指向首元素的指针。...数值数组:它是一个指针,而没有专用操作,因此输出内存地址。 3. 内存地址和字符串的不同解释 数组名作为指针: 数组名会被解释为指向首元素的指针,并不自动输出数组内容。...如果要输出数值数组的内容,可以通过循环输出每个元素: 以原代码为核心: for (int i = 0; i < 10; i++) { cout << arr1[i] << " "; } cout...通过定义"学生"类,设置姓名、学号和成绩等属性,再为类添加一些方法,如打印信息和计算平均分,我逐渐理解了OOP的实际应用价值。

    4100

    C语言入门这一篇就够了(进阶篇)

    注意,在C语言中,数组名称本身就是指向数组第一个元素的指针。因此,我们可以直接使用数组名称来访问数组中的元素。...这些操作可以通过使用循环、条件语句和函数来实现。下面是一些常用的操作示例: 遍历数组:使用for循环遍历数组中的每个元素。例如: 查找元素:使用for循环或二分查找算法在数组中查找特定元素。...下面是一个关于C语言指针的基本示例: 在这个例子中,我们首先定义了一个整型变量a并赋值为5,然后定义了一个整型指针p。接下来,我们将指针p指向变量a的地址。...最后,我们分别打印了变量a的值和指针p所指向的值。由于p指向了变量a的地址,因此*p代表了变量a的值,输出结果应为5。...4.字符串操作:字符串本质上是字符数组,通过指针可以方便地对字符串进行操作。 5.回调函数:通过指针可以指向函数地址,实现回调函数的功能。

    27630

    【嵌入式开发】C语言 指针数组 多维数组

    地址算数运算示例 指针算数运算 : int *p, array[5]; p = array; p 指向一个 int 数组元素, p + i 的地址时数组中第 i 个元素的地址, 即 p + i 指向 第..., 当分配内存的时候, 通过计算 数组首地址 + 数组长度 - 偏移量 >= 分配大小 , 成立的话就可以分配内存, 分配内存就是将偏移量 加上 分配大小; 释放内存的时候, 就将偏移量 指向 释放内存的指针的首地址...; 指针运算 :  -- 比较运算 : 两个指针都指向同一个数组中的元素, 那么两个指针之间的比较是有意义的, 指向两个不同数组元素的指针之间比较无意义; -- 加减运算 : 指向数组元素的指针, 进行加减运算...-- 创建字符指针数组 : 当获取到的字符串个数为0, 停止获取字符串, 然后统计字符串个数, 根据字符串个数分配字符指针数组大小; -- 递归排序 :  -- 打印数组 : 遍历指针数组, 将指针指向的字符串打印出来...代表参数是一个指针, 这个指针指向一个 由 13个元素组成的一维数组; -- 错误情况 : fun(int *dat_table[13]) 传入的时一个 存放有 13个指针元素的 一维数组; -- 错误情况

    95260

    【Java】ArrayList与LinkedList详解!!!

    顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。...,如果有返回true,没有返回false while(a.hasNext()){ //a.next:返回迭代器当前所指向的元素,然后指向下一个元素未被遍历的元素并打印...,如果有返回true,没有返回false while(b.hasPrevious()){ //b.previous:返回迭代器当前所指向的元素,然后指向上一个元素未被遍历的元素并打印...在扩容时会创建一个新的容量更大的数组并复制旧元素,这会消耗较多的时间和资源; 插入和删除的效率较低(中间元素):在频繁的插入和删除中间元素的时候,需要不断地移动元素,时间复杂度为O(n)。...单链表:每个节点包含数据和下一个接节点的指针,最后一个节点的指针指向空 双链表:每个节点都有包含数据,以及指向前一个节点的指针和指向后一个节点的指针 循环链表:循环链表分为单循环链表和双循环链表,其就是最后一个节点的下一个节点的指针指向其头结点

    12410

    【编程基础】C语言指针函数和函数指针

    子函数返回的是数组某元素的地址。...但是因为*运算符高于++运算符,所以圆括号在这里是必须的,如果没有圆括号,那么++运算符将作用于二重指针fpp上。 四、指向指针数组的指针 指针的指针另一用法旧处理指针数组。...每次printf()的调用都首先传递指针nm指向的字符型指针,然后对nm进行自增运算使其指向数组的下一个元素(还是指针)。...注意完成上述认为的语法为*nm++,它首先取得指针指向的内容,然后使指针自增。 注意数组中的最后一个元素被初始化为0,while循环以次来判断是否到了数组末尾。...具有零值的指针常常被用做循环数组的终止符。程序员称零值指针为空指针(NULL)。采用空指针作为终止符,在树种增删元素时,就不必改动遍历数组的代码,因为此时数组仍然以空指针作为结束。 整理自互联网

    2.1K100
    领券