C语言 指针入门 看这一篇就够了


C语言 指针入门 看这一篇就够了

指针的运算 详解 [C语言必知必会]

指针的运算

指针加减 常量

请看下面的程序,猜测一下结果:

<code>int main() {

int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* a = &arr;

printf("a = %p\\n", a);
printf("a + 1 = %p\\n", a + 1);
printf("a - 1 = %p\\n", a - 1);

}
/<code>

运行结果:

<code>a     = 00AFF82C
a + 1 = 00AFF830
a - 1 = 00AFF828
/<code>

可以看到, a 与 a + 1 和 a - 1 都差了四个字节

指针加减常量 加减的大小为 sizeof(类型) * 常量

再试试 char 类型?

<code>int main() { 


char arr[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10',};
char* a = &arr;

printf("a = %p\\n", a);
printf("a + 1 = %p\\n", a + 1);
printf("a - 1 = %p\\n", a - 1);

}
/<code>

结果如我们所料:

<code>a     = 0095F9E0
a + 1 = 0095F9E1
a - 1 = 0095F9DF
/<code>

相差大小 为 1

指针 - 指针

先来看一段程序吧:

<code>int main() {

char arr1[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10', };
int arr2[5] = { 1, 2, 3, 4, 5 };

char* ch1 = &arr1[4];
char* ch2 = &arr1;
int* i1 = &arr2[4];
int* i2 = &arr2;

printf("ch1 - ch2 = %d\\n", ch1 - ch2);
printf("ch2 - ch1 = %d\\n", ch2 - ch1);
printf("\\ni1 - i2 = %d\\n", i1 - i2);
printf("i2 - i1 = %d\\n", i2 - i1);

}
/<code>

指针相减 结果会是 指针相差的大小吗?看结果:

<code>ch1 - ch2 = 4
ch2 - ch1 = -4


i1 - i2 = 4
i2 - i1 = -4
/<code>

指针 减 指针 意义是 两个地址之间相隔的单元格数也可以理解为:指针相差的大小 / sizeof(类型)

如果想输出两个指针 相差的距离(大小)只需要将变量类型 更改成普通类型,如下:

<code>int main() {

char arr1[10] = { ' 1', '2', '3', '4', '5', '6', '7', '8', '9', '10', };
int arr2[5] = { 1, 2, 3, 4, 5 };

//变量不再是指针变量
char ch1 = &arr1[4];
char ch2 = &arr1;
int i1 = &arr2[4];
int i2 = &arr2;

printf("ch1 - ch2 = %d\\n", ch1 - ch2);
printf("ch2 - ch1 = %d\\n", ch2 - ch1);
printf("\\n");
printf("i1 - i2 = %d\\n", i1 - i2);
printf("i2 - i1 = %d\\n", i2 - i1);

}
/<code>

输出结果:

<code>ch1 - ch2 = 4
ch2 - ch1 = -4

i1 - i2 = 16
i2 - i1 = -16
/<code>

普通类型是无法进行解引用操作的

总结一下

指针 可以 加减常数,指针之间可以相减,可以比较(如:> == < >=等)但是指针不能乘除,相加 这是没有意义的举个很简单的例子,时间可以相减,但是时间乘除或者相加有什么意义呢?

NULL

通过前面的学习,我们知道:内存中的地址有很多编号。如果你的机器是 32 位,那么内存范围是:0 ~ 2^32 -1(32位2进制数全1) 最大值大约为 4GBNULL其实就表示 0地址补充个小知识点:1kB=1024B =2^10(次方是二进制形式)1MB=1024kB =2^201GB=1024MB =2^301TB=1024GB =2^40

NULL有什么用?

0地址规定为我们不能写入的地址,你的指针不指向 0地址,如果你的指针指向了 0地址 那么程序运行时会崩溃。基于这个特点,0地址 也就是NULL有了很重要的功能:

  • 函数返回 NULL指示错误
  • 防止野指针。用NULL初始化指针,如果指针使用时没有指向任何实际地址,程序崩溃。

NULL类型时 void * 可以设置任何类型为NULL下面的程序是官网上讲NULL时给出的例子:

<code>#include <stdlib.h>
#include <stdio.h>
int main(void)
{
// 能设置任何类型指针为 NULL
int* p = NULL;
struct S* s = NULL;
void(*f)(int, double) = NULL;

// 多数返回指针的函数用空指针指示错误
char* ptr = malloc(10);
if (ptr == NULL) printf("Out of memory");
free(ptr);
}
/<stdio.h>/<stdlib.h>/<code>

void*

void* 表示 不知道指向什么类型的 指针比如:

<code>int i = 1;
int* p = &i;
void* q = (void*)p;
/<code>

这么写并没有改变 p 所指向的变量的类型, 而是可以让程序用不同的眼光通过 p看它所指的变量。

指针类型的作用

1. 指针的类型决定了指针向前或者向后走一步有多大

2. 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)




分享到:


相關文章: