C语言笔记(适用于大一新生查漏补缺) 您所在的位置:网站首页 大一c语言笔记重点 C语言笔记(适用于大一新生查漏补缺)

C语言笔记(适用于大一新生查漏补缺)

2024-07-12 07:24| 来源: 网络整理| 查看: 265

大家好,我是一名刚学C语言两个月不到的菜狗子,以下是我两周以来学习指针的详细笔记,笔记内容可以说是结合了鹏哥C语言,翁恺C语言,以及CSDN上的一些大佬的分享,也加入了我很多的见解(每一个我自己的想法都有对应的代码验证)。

这是一篇给新手用来查漏补缺或者学习指针中较高级(对我来说比较高级)知识的笔记,主旨并不是讲明白最基础的概念,不建议完全没学过的新手用来入门C语言,但是较为复杂,难懂的内容我都会尽力做到讲明白,至于其中我也不会的两个题就丢出来给大家思考和讨论了(我记得好像就两个题,文章中会进行说明,下次博客更新的时候会提供答案,提前说明我会挖几个坑下次填哈哈)

以下为文章的目录,每一块标题都用黄色标注出来了,读者可以按需翻找

1.指针的定义    2.野指针    3.指针的基础运算 

4.字符指针      5.指针数组  6.数组指针

7.二级指针      8.指针与数组指针的步长       9.一级指针传参和二级指针的传参

10.void*空指针     11.函数指针       12.函数指针数组

13.回调函数      14.指针相关作业含sizeof()、strlen()与指针的结合

废话一下,标题不让写萌新或者新手,我只能被迫写了一个大一新生,哭死,这水平根本不配代表大一新生

指针:

定义及基础知识

1.在内存中取一个字节为一个内存单元,每个字节里面存放一个指针

比如int a = 10;这个代码,其中a占四个字节,我们取a的地址的时候其实拿到的是四个字节中的第一个字节的地址

2.指针在32位系统中占4个字节,在64位系统中占8个字节

3.不同类型的指针都占同样的字节,那么指针类型的意义是什么?

(1)指针类型决定了指针解引用的权限有多大,即能操作几个字节

(2)指针类型决定了,指针走一步能走多远(详见例一)

例一

 

整型指针加一与char类型指针加一的结果不同

Int类型加一相当于跳过一个整型,char类型加一相当于跳过一个char类型

所以两个结果一个是+4一个是+1

具体的作用就是比如一个数组p指针,每次给p加一,那么每次跳过多少个字节取决于这个指针的类型,那么设置指针的类型就有意义了

野指针:

指向的位置是不可知的就是野指针

原因: 1.指针未初始化

2.指针越界访问

3.指针指向的空间释放了

例一:指针未初始化

 

 

没有初始化指针的时候里面存的是一个随机值,指向的是内存中某一个位置,这个值指向的是不是这个程序都不一定,所以再将20赋给这个值,然后再访问的时候就会出现非法访问内存了

例二:指针越界

 

例三:

相当于订的房间住完退订后,再想去住就会有问题了

 

综上,解决方法就是

1.使用指针的时候要记得初始化(但不知道要初始化为什么地址的时候,给一个NULL即可)

2.C语言本身是不会检查数据的越界行为的,自己要注意

3.为了防止野指针的出现,可以在开始的时候设置为NULL,使用前判断一下是不是NULL,使用完设置为NULL

指针的运算:

例一:指针相减

 

输出的结果是9,为什么?

指针-指针得到的是两个指针之间的元素个数

原因是什么?王八屁股——龟腚

指针和指针相减的前提是:两个指针指向的是同一块空间

为什么不用学习指针加指针?

有些运算是有意义的,有些是没有意义的,比如日期减日期得到的是相差的天数,但是日期加上日期没有什么实际的意义,指针的加减同理

例二:用指针求字符串的长度

 

这个代码可以指针-指针的方式进行运算

代码如下:

 

注意:

王八的屁股——龟腚

允许使用数组的最后一个的下一位进行比较,但是不允许第一位的前一位,总之就是访问数组的时候要++不要—,就是可以往后越界但是不能往前越界

字符指针:

常量字符串的概念:

Char arr[] = “abcdef”; 就是把这串字符放进arr[]数组中去,输入和输出函数都可以用

Char* arr = “abcdef”; 就是定义了一个常量字符串,里面的值是不能修改的只能用于输出函数,不能用于输入函数,被当作常量并且存储在内存静态区

Char*不仅能存储单个字符,也能存储字符串

存储字符串的时候是把首字符的地址存储起来了

例一:字符串不同方式定义时产生的区别

 

输出的结果是:

 

因为前两个是分别开辟了两块不同的空间

但是三和四是将同一块空间存储的内容的地址给了不同的指针,实际上三和四还是指向的是同一个地址,相当于把一个常量赋值给了a和b两个变量

指针数组:

定义:存放指针的数组,本质上是一个数组,存放的指针

格式如:int* arr[]

这样就是存放整型指针的数组了

例一:指针数组的初始化

菜狗写法

 

以下是较高级写法

 

这样就能遍历这个数组了

 

输出的时候也可以写成arr[i][j]

为什么输出的时候是用*(arr[i]+j)在后面讲解步长的时候有具体说明

数组指针:

本质上是一种指针,指向数组的指针

格式如:int (*parr)[10] = &arr;

先对parr解引用表示这是一个指针,指向的是有10个元素的数组,如果没有括号就成了一个数组了([]的优先级比*要高),所以可以把arr的地址放在*parr里面

 

Parr就是一个数组指针,存放的是数组的地址,*parr就相当于一个数组名

例一:数组指针与指针的加一跨过的字节大小不同

 

看似两个输出的结果是一致的,但是实际上类型是完全不一样的

第一个输出arr的是数组类型

第二个输出&arr的是指针类型,这个指针指向arr[10]这个数组

因为类型不一样,所以加一跨过的字节也是不一样的

 

这样输出的结果:

第一个跨过一个整型,就是4个字节,第二个跨过一个数组,就是10个字节

结论:

综上其实&arr和arr虽然值是一样的,但是意义是不一样的

&arr取得是数组的地址,而不是数组首元素的地址,当其地址+1的时候跳过的是整个数组的大小

补充:数组名是数组首元素的地址,但是有例外

1.sizeof数组名表示整个数组,计算的是整个数组大小

2.&数组名表示整个数组,取出的是整个数组的地址

例二:用指针的方式来访问数组元素

 

(*pa)+i就是让首元素的地址加i,其中*pa就相当于数组名,输出的结果是一个地址

所以要在进行一次解引用,*((*pa)+i)这样才是这个地址对应的值

输出的结果就是遍历这个数组

一般情况下一维数组不用数组指针,写起来很麻烦关键

例三:数组指针在二维数组的应用

 

二维数组的数组名表示首元素的地址,二维数组的首元素是第一行的地址

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有