C语言指针简单理解
先放一个程序
指针是什么?网上主要有这么几种说法
1.指针就是一个存放地址的变量
2.指针是无符号整数a
3.指针是整型变量a
4.指针是地址
5.指针是一种类型
1.首先 指针肯定不是 整型变量 用sizeof看 是4个字节 而且可以用%d输出。
与其说是整型变量,还不如说是无符号整数呢,但是说指针是无符号整数也存在明显的问题 下面用程序先推翻这两种说法。
#include"stdlib.h"
#include "stdafx.h"
int main()
{
int *p1 = NULL;
int a = 20;
unsigned int b = 30;
p1 = a;//error
p1 = b;//error
p1 *= 5;//error
return 0;
}复制代码
把无符号整数和整数变量分别复制给指针变量, 编译器提示报错,就说明,指针不是整型变量和无符号整数。(好理解)。
而且 整数变量可以做乘法 指针变量不可以。
2.指针就是一个存放地址的变量
或者说 指针就是地址 用下面的程序测试一下
int a = 10;
int b;
b =&a;//报错:不能从 int* 转化为 int 这个证明了:普通变量不能存放地址 而指针变量可以存放地址(但是这个只是说明了 指针变量可以存放地址)
但是 指针不仅仅是一个存放地址的变量 而且 指针并不是地址
指针是不是只是一个地址呢?
地址一般理解为内存单位的编号,是数字。
那么 我们用这个数字是否可以操作内存单位(用地址完成指针的工作)
1 int main()
2 {
3 int a = 10;
4 int b;
5 b =(int)&a;
6 *(b) += 20;//error
7 return 0;
8 }复制代码
第5行,将a的内存地址强制转化为数字 存入b 然后用b操作a 结果呢 当然不可行
提示非法的间接寻址 看来用地址是不能完成指针的任务、
重点来了:
把这个地址变成指针如何?
1 int main()
2 {
3 int a = 10;
4 int b;
5 b =(int)&a;
6 *((int*)b) += 20;
7 printf("%d", a);
8 return 0;
9 }复制代码
运行后发现,结果正常,成功通过地址操作了变量a
上文出现的错误 大多提示的是类型转换的错误 (不能将 int *转换为int类型) 看来编译器是认为指针是一种类型
而上面的一个程序 *(b) 不正确 *((int *)b)正确 而多出来的(int *)正是指针的类型
或者说 指针由两部分组成: 数据类型和地址。。
3.事实上 指针确实不仅仅包含地址 数据类型也是非常重要的
因为 数据类型决定了指针移动的步长 比如 char类型指针++ 地址每次+1 int类型指针 地址每次+4
更复杂的还有数组 指针在二维数组中非常重要 是行+1还是列+1 操作的指针是不一样的
int main()
{
int arr[100];
printf("%d %d\n", arr, &arr);
printf("%d %d\n", arr+1, &arr+1);
return 0;
}
运行结果为:
9607420 9607420
9607424 9607820
请按任意键继续. . .
第一行 两个arr和&arr 都是首地址。
第二行 可以看出 arr+1 内存+4 &arr+1 内存+400
取地址的arr数据类型是整个数组 因此+1相当于+100*4
指针如果没有类型,在读取和写入也会出问题。
因为是首地址,如果没有类型,怎么知道是读取,写入几个字节呢。