【重新学习C Day7 for 嵌入式Linux】

Day 7
1.
指针在一个平台下所占的内存是确定的大小 这和它的数据类型无关
但是不同类型的指针在做运算的时候所代表的意义是不相同的
指针一旦定义出来就要给一个明确的指向
2.
将指针指向空 是为了避免野指针的出现 NULL也是一个确定的指向 当我们还不知道指针需要指向哪里的时候指针可以指向这里
3.
再次强调一下 int p 并非是 一个int 类型的内容 而是一个 int 类型的内容 至于为什么非要把p写在一块 我觉得吧 确实是挺好看的 反正C语言这个东西本身就是认为规定的 不是嘛
4.
再次强调一下 a[i]=
(a+i)
圆括号这里的i是i个元素大小 其实这里就和 今天 的 第1 条中的内容相关联了
数据类型决定了这个元素的大小 作为一个“单位” 不管是 整形/浮点型/结构体 等等等等 就是作为一个元素的单位那么大
所以这里就是指针与数组关系的机理的体现

a[i]=*a(a+i)=*(p+i)=p[i]
&a[i]=a+i=p+i=&p[i]

但是这里就存在上述前提

int a[3]={1,2,3};
int *p= a;

显而易见 指针p指向了数组的首地址 而他们的数据类型是一样的 这样的思想应当与前几天的内容关联起来 这些内容的通用性是不受数组维数影响的

好的 那么到这里就会产生疑问 一个指向数组头地址的指针和这个数组有什么区别呢?貌似是一种的东西啊?
这样的疑问使得我们回忆起这两者的本质 数组a 是常量 而p是变量
比如
在C语言中 可以 进行p++的操作 这被视作指针的地址偏移 而如果你进行a++的操作 那么你的编译器就会向你报错了 它会说:左值必须是一个可以操作的量 显而易见 我们的a是一个常量

指针与N维数组
以二维数组为例 二维数组a[N][M]
当 a+1时 根据我们之前所学到的知识 地址可以看作是在“行”间跳跃 也就是说 a+1后指向的地址是跳转了一个行那么多元素大小的
而指向a首地址的指针p 它进行p++时,是严格遵守数据类型来跳转的 也就是说 当int类型的数据 进行p++时,p偏移的地址大小是一个int那么大
而二维数组 偏移的有一行那么大 如果一行中有8个int的量,那么a+1偏移的就是8个int的量
这是需要注意的一点
所以 当我们写下代码
p=a;
时,这两者在机理上是存在不同的
这个时候会有警告甚至是报错的风险 为了规避这种风险 我们应该使用更加合法的写法

首先区别这两者
a 是在行间跳跃 我们视作行指针
而p显而易见是一个长长的 列 指针
当对a进行 *(a+i) 操作的时候 显而易见 我们把行指针转化成了一个列指针

对于 * 这个操作 实际上是对指针的一个降级 前边数条提到的内容都在阐述这一个观点
比如双级指针
在目前这个例子中 我们可以这样理解
*(a+i) 这个操作实际上是把操作对象固定在了某一行上 从计算机的储存来说 这就是我们寻找的“列” 一个二维的数组固定在了一维上 这是二维数组中的一行 也是 在a这个层面上进行操作的那个元素 我们现在进入了它的内部
(对于N维的数组显然也满足这个说法)

所以 现在 *(a+i) 是和p相同机理的内容了

当前

*(a+0)+j 与 p+j 

是相同的操作
不过前者是在第0行上进行位移 而后者是在一个相当长的“列”上进行位移 但这并不影响什么 因为前者在满一行位移的时候是会自动换行的 而这个换行 就是计算机储存形式在数组中的具体体现

所以更加合法的写法是

p = *(a);

实际上它就是

p=*(a+0);

当然 也可以写成

 p=a[0][0];

以上所述是整形指针 也就是说 指针的地址跳转是严格遵循最基本的数据类型的
但是如果我们希望指针的跳转也是“按行跳转”呢?
所以我们就要用到“数组指针”
必须要声明的是 数组指针 仍然是一个指针

#include <stdio.h>
#include <stdlib.h>

int main()
{
int a[2][3]= {1,2,3,4,5,6};
	int (*q)[3] = a;
	
	exit(0);
}

这样 我们定义出来的q 就是一个可以按照a的行的大小跳转地址的指针 也就是一个数组指针

int (*q)[3] = a; 
//这句话其实是
int[3] *q = a;

其实 指针的概念完全没有改变 int[3] * 是在定义一个指针 而这个数据类型的最小的单位 是一个三个int大小的数组

反观我们定义的二维数组a[2][3] 它是一个两行 每行有3个int的数组

这样我们对数组指针的概念理解的就非常清晰了

那么这个思想延伸到N维都是可以的 就如同前几天我们强调的N维数组+1的含义
定义一个跳跃 行 甚至是N-1维空间大小的地址的 指针变量 都将会是符合逻辑的

但是要注意的一点是 跳转的大小应该和数组的跳转的大小一致 就如同

int (*q)[3]
和
int a[2][3]

中的3
我想这一点已经说的足够清楚了

字符指针和字符数组也会出现变量和常量的区别 这些和上述提到的内容并无差异
而且会影响到 <string.h> 中内容的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值