- 一、什么是指针?
- ✨内存
- ✨指针和指针变量
- ✨总结
- 二、指针的使用
- 2.1 指针类型
- ✨定义
- ✨意义
- ✨二级指针(用来存放指针的指针)
- 2.2 访问指针
- ✨一般变量
- ✨数组
- 2.3 指针运算
- 三、注意事项
- 野指针(指针指向的位置是不可知的)
在了解指针之前,我们需要对内存有一个了解。
✨内存概念:电脑上的存储设备,程序运行的时候会加载到内存中,并使用
如何使用:
正如生活中,我们会把高楼大厦分成一层层、一个个小房间,以便实现查找。而计算机也将内存分为了一个个小房间,并给每一个房间分配了地址编号,我们可以通过这个编号去找到每一个内存单元,而这意义其实就等同于地址
之前在【内存】模块,以及介绍了指针的概念,即编号=地址=指针
那么如何产生地址/编号?
计算机有32/64根地址线,下面我们以32位计算机为例,64位同理
32位计算机,假设有32位地址线,每根地址线在寻址的时候会产生高电平和低电平,就是1或者0。
那么32根地址线产生的地址就是从00000000000000000000000000000000~11111111111111111111111111111111一共2^32次方个地址,这些地址就是一个个编号/指针
每一个指针对应的内存单元多大------一个字节,记住就好
每一个地址标识一个字节,那我们就可以给2^32(Byte)/1024(KB)/1024(MB)/1024(GB)---->4GB的空间进行编址
指针变量是什么
我们可以通过&,取出变量的内存起始地址(取出的是第一个字节的地址),把地址存放到一个变量中,这个变量就是指针变量
在寻址的时候会产生地址,在32位的机器上,地址是32个0或者1组成2进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节;在64位机器上,如果有64根地址线,那一个指针变量的大小是8个字节,才能存放一个地址
int main()
{int a = 10; //在内存开辟一块空间,a占用4个字节空间
int* pa = &a; //把a的第一个字节的地址取出来,放到pa中,pa就是指针变量
return 0;
}
✨总结- 指针是内存中一个最小单元的编号,也就是地址。它的产生依托与地址线的寻址
- 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
- 指针变量是用来存放地址的,地址是唯一标示一个内存单元的
- 指针的大小在32位平台是4个字节,在64位平台是8个字节
int a = 0;
int* pa = &a; int*类型的指针,是为了存放int类型变量的地址
*是指,pa是一个指针变量,用来存放a的地址
int是值,pa所存放地址的对象是int类型的
😊指针数组
int* arr[5];
✨意义指针类型有许多种,如int*、char*……。那么不同的指针类型究竟有什么意义呢?---------------提供了不同的视角去观看和访问内存
✨二级指针(用来存放指针的指针)char* 一次访问(解引用)1个字节,+1跳过1个字节
int* 一次访问(解引用)4个字节,+1跳过4个字节
int a = 10;
int* pa = &a; //取出a的地址,放到pa上
int** ppa = &pa; //取出pa的地址,放到ppa上
int b = 20;
*ppa = &b; //等价于pa = &b;
**ppa = 30:
//等价于*pa = 30
//等价于a = 30
【int** ppa】:
第一个*是int *的一部分,表明ppa所存的地址的对象是int *类型的
第二个 *表明ppa是一个指针
我们存的是一个地址,而要通过一个地址去寻找(访问)对应的那个变量,就需要*(解引用)
#includeint main()
{int a = 10;
int* pa = &a;
printf("%p\n", &a);
printf("%p\n", pa);
*pa = 20;
printf("%d\n", *pa);
printf("%d\n", a);
return 0;
}
联系之前的【意义】
✨数组char* 一次访问(解引用)1个字节,+1跳过1个字节
int* 一次访问(解引用)4个字节,+1跳过4个字节
- 数组名本身就是一个地址(除了sizeof(数组名)和&数组名)
- *(arr+i) = arr[i]; arr+i = &arr[i];
指针±整数
根据指针的类型,看跳几个字节指针-指针
前提:两个指针要指向同一块空间,而且类型也要相同结果:指针-指针的绝对值,得到的是两个指针之间的元素个数
int main()
{int arr[8] = {1,2,3,4,5,6,7,8 };
printf("%d", &arr[8] - &arr[0]);
return 0;
}
- 指针的关系运算
注意:标准规定,允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
野指针,即那些危险的指针,下面几种错误操作会产生野指针,需要注意
- 未初始化就访问
int main()
{int* pa;
*pa = 20; //局部变量指针未初始化,默认为随机值
return 0;
}
- 指针越界
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10 };
int* pa = arr;
int i = 0;
for (i = 0; i<= 11; i++)
{*(pa++) = i;
}
return 0;
}
- 访问空指针
int main()
{int* pa = NULL; //没有有效的地址,就暂时先放一个空指针,相当于把狗栓了起来
*(pa++); //虽然还是有潜在危险,但是只要你不去主动招惹他就问题不大
//总体还是比野指针要安全
return 0;
}
- 指针指向的空间释放
int* test(void)
{int a = 10;
return &a;
}
int main()
{int* pa = test();
printf("%d", *pa); //这个时候,这个地址已经还给操作系统了
return 0;
}
如何规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放,及时置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
当前标题:初识C语言(指针)-创新互联
网页链接:http://scgulin.cn/article/doogdc.html