Linux C学习笔记(三)

1.1 指向数组首元素的指针

在这里插入图片描述
程序结构图:

在这里插入图片描述
p[i] 等价于 *(p+i),操作都是指针所指向的内存。

1.2 指针的加减运算

加法:

在这里插入图片描述
减法:

在这里插入图片描述

1.3 指针数组

在这里插入图片描述
关于计算指针数组元素个数的解释:

在这里插入图片描述
程序结构图:

在这里插入图片描述

1.4 形参中的数组

结论:

在这里插入图片描述
举例:

在这里插入图片描述
此处的a = NULL不会报错,因为传进来的a是一个指针变量,可以被赋值。

对于如下使用情况:

在这里插入图片描述

  • a = NULL会报错,因为a是一个常量,它是数组首元素的地址
  • 这种传递参数的形式也不能达到效果

所以我们需要把数组元素个数也传递进去:

在这里插入图片描述
至于为什么形参中的数组不是数组,因为可能我们定义的数组很大,元素个数不确定,拷贝到形参里的话是很麻烦的,同时指针效率比较高也体现在这,所以这里形参只存首元素的地址就行。

结构图如下:

在这里插入图片描述

1.5 返回局部变量的地址

在这里插入图片描述
结构图如下:

在这里插入图片描述
运行到第27行的时候程序会报错,因为调用函数结束后,操作系统分配的内存会释放掉,调用函数里的变量是局部变量也会被释放掉,此时p存储的是一个野指针,对野指针操作会报错。

甚至在Linux 64位gcc环境下,不允许返回局部变量的地址,,如下图:

在这里插入图片描述

1.6 返回全局变量的地址

  • 在{ }外面定义的变量,就是全局变量,全局变量任何地方都能使用
  • 全局变量只有在程序运行结束后,才释放

在这里插入图片描述
在这里插入图片描述

1.7 字符串打印说明

为什么%s会直接打出字符串:

在这里插入图片描述
字符串很特别,它没有操作 *号,但是它已经操作了这个指针指向的内存,因为%s的内部含有如下处理:

在这里插入图片描述
但是如果想用指针操作字符串名时:

在这里插入图片描述
也可以进行如下操作:

在这里插入图片描述

1.8 字符指针

在这里插入图片描述
结构图1:

在这里插入图片描述
结构图2:

在这里插入图片描述

1.9 字符串拷贝问题

错误的拷贝示例:

在这里插入图片描述
正确的拷贝:

在这里插入图片描述
结构图如下:

在这里插入图片描述


补充记忆知识点:熟记

在这里插入图片描述
在这里插入图片描述


1.10 字符串常量

在这里插入图片描述

  • 每定义一个字符串都有一个地址,这个地址就是字符串首元素的地址,只要字符串的内容一样,它们的地址就是一样的,如上图fun()函数的输出结果和第二个printf()对应的输出地址结果相同:
    在这里插入图片描述
printf("s3 = %s\n","hello mike"+1) 
表示字符串首元素地址加一,指到下一个地址了。
输出结果:s3 = ello mike
验证了字符串就是首元素的地址

所以如下程程序就是合理的,因为一个字符串本身就是一个地址,将它赋给指针变量是正确的:

在这里插入图片描述
输出结果三个地址是一样的:

在这里插入图片描述
结构图如下:

在这里插入图片描述
需要注意的情况,文字常量区不允许修改
举例1:

在这里插入图片描述
结构图如下:

在这里插入图片描述
举例2:

在这里插入图片描述
结构图:

在这里插入图片描述
上图程序最后的函数调用结果依旧是错误的。

1.11 字符串常量初始化问题

在这里插入图片描述
结构图:

在这里插入图片描述

1.12 main形参使用说明

以下两种初始化方式结果相同,形式不同:

在这里插入图片描述
表示这个数组有三个元素,每个元素都是char * 类型,char * 类型保存了它的地址。

因为p[i]就是每个字符串的首元素地址,直接打印即可,打印每个元素的方式:

在这里插入图片描述
输出结果如下:

在这里插入图片描述
首先明确以下三种定义结果是一样的:

在这里插入图片描述
此时对应如下情况就是成立的,它的形参形式就和main里的一样,也就能理解main里的形参含义了:

在这里插入图片描述
所以对应于main函数里的参数,解释如下:

在这里插入图片描述

1.13 查找匹配字符串出现的次数

在这里插入图片描述

1.14 两头堵模型

在这里插入图片描述
还可以继续操作拷贝这个字符串:

在这里插入图片描述

发布了22 篇原创文章 · 获赞 5 · 访问量 475

猜你喜欢

转载自blog.csdn.net/RedValkyrie/article/details/105154787