[C语言] 指针详解(1)

一. 指针

利用指针,可以找到相对应内存地址(唯一的一段编号),从而定位数据.

(通俗来说,指针就是变量,用来存放内存单元的地址)

保存一段 16进制的 地址编号

二、指针类型/变量:

  1. 类型: 基础类型+* 如: int* char*
  2. 指针变量: int* pa pa就为指针变量.
  3. 解引用符号: * 放在变量前面 表示这一个变量数据 , 简单的 指针变量仅仅表示一段地址.
  4. 取地址符号: & 取出所对应的内存单元的地址

一般存储地址方法:

	int a = 123;
	int* pa=&a;  //将a的地址 赋值 给指针变量pa
	*pa = 20;    //将pa解引用 重新赋值

1. 一个内存单元多大?

一字节

2. 一个指针变量大小:

32位平台 为 4字节 , 64位平台 为8字节

3. 为什么指针变量一样大,为什么不同的指针类型呢?(指针类型意义)

2个16进制位 = 8个2进制位 = 1字节

意义1 : (指针类型决定了指针进行解引用操作时,能访问的空间大小)

比如:

当同时分别往2个不同类型的 指针变量存入 一个 0x11223344,然后再解引用.

解引用修改变量数据时, int *是修改4字节, 但是char*修改1字节, double* 修改8字节

(所以当赋值时,应该赋值合适的指针类型)

#include<stdio.h>
main()
{
	int a = 0x11223344;
	int* pa=&a;  //将a 的地址取出,放入 pa指针中
	char* pc=&a;

	printf("%p\n", *pa);  //取出指针变量 pa中的值
	printf("%p", *pc);

}

输出结果:
0000000011223344
0000000000000044

意义2 : 指针类型决定了:指针一步走多远(指针的步长)

#include<stdio.h>
main()
{
	int a = 0x11223344;
	int* pa=&a;  //将a 的地址取出,放入 pa指针中
	char* pc=&a;

	printf("%p\n", *pa);  //取出指针变量 pa中的值
	printf("%p", *pc);

}

计算结果:
000000B515CFF898
000000B515CFF895

计算 地址+1:

  • *p= 11223344; (16进制)
  • int*p+1 是在原先地址上+4 :127
  • char*p+1 是在原先地址上+1 :124
  • double*p+1 是在原先地址上+8 :12b

三、野指针:

1.含义:

指针指向的位置是不可知的(可能是随机的,不正确的,不明确的)

2. 造成野指针的原因:

1).指针未初始化(局部变量不置初值,默认是随机值)

2).指针越界

比如 一个数组大小为12,但是循环时指到了地址 13, 就会报错.

3).指针指向空间释放

当指针垮函数使用时, 由于子函数可能创建的是一个 临时变量,当子函数返回指针时,临 时变量也将取消,当主函数再次使用值时,发现是一个释放掉的空区域.

3.避免野指针:

1).指针未初始化

2).指针越界

3).指针合适赋值为 nill, 空指针无法被访问

4).使用前检查有效性

四、指针运算

1.指针+-整数

p+1 表示 地址位置根据 数据类型 往后面移位置

*p+1 表示 p中存储的数据+1

#include<stdio.h>
main()
{
	int arr[] = { 1,2,3,4,5 };
	int i;
	int* p = arr;   //将数组首地址赋值  指针变量p
	for (i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ",*p);   //输出 指针变量 p中的值
		p++;    //p 的位置 一字节一字节的 往后移. 1 到 2 到 3.....
	}

}

输出结果:
1 2 3 4 5

sizeof(arr) / sizeof(arr[0])  // 表示数组长度

2.指针-指针

指针-指针, 表示 两指针中间的元素个数.(必须保证是同一空间,同一类型)

#include<stdio.h>
main()
{
	int arr[] = { 1,2,3,4,5 };
	int i;
	int* p1 = &arr;   	//将数组首地址赋值  指针变量p
	int* p2 = &arr[2];

	printf("%d ", p2-p1);

}

结果为 2

3.指针关系运算

注: 标准规定,允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针作比较,但不允许和第一个元素之前的内存位置的指针作比较

允许p2 和p3

不允许p2 和p1

虽然在绝大部分情况下可以运行成功

#include<stdio.h>
main()
{
	int arr[5] = { 1,2,3,4,5 };
	int i;
   int *p2;

	for (p2=&arr[5]; p2>&arr[0];)  //将最末端小于或等于最前段时 ,停止
	{
		*--p2 = 0;   //赋值为0
		printf("%d ", *p2);
	}
}
结果:0 0 0 0 0

五、指针与数组

1.首地址代表 :

数组名

&数组名[0]

2.不代表首地址情况:

&数组名 表示整个数组,取出整个数组地址

sizeof(数组名) 表示整个数组,计算整个数组的大小

六、二级指针

int main()
{
    int a=10;
    int* aa=&a;      //一级指针  类型  int*   ,存的变量的地址
    int** aaa=&aa;   //二级指针  类型  int**  ,存的指针的地址
    **aaa=20;        //修改了a的值为20
}

七、指针数组/数组指针

**指针数组:**存放指针的数组

数组指针:指针

int main()
{
    int a=1;
    int b=2;
    int c=3;

    int* arr[3]={&a,&b,&c};  //存储3个地址,称为指针数组

    int i=0;
    for(i=0;i<3;i++)
    {
    printf("%d",*(arr[i]));  //循环打印出 abc中的值
    }

}
相关推荐
DARLING Zero two♡24 分钟前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
7年老菜鸡25 分钟前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Gu Gu Study27 分钟前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
Ni-Guvara34 分钟前
函数对象笔记
c++·算法
似霰38 分钟前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
芊寻(嵌入式)1 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
獨枭1 小时前
C++ 项目中使用 .dll 和 .def 文件的操作指南
c++
霁月风1 小时前
设计模式——观察者模式
c++·观察者模式·设计模式
橘色的喵1 小时前
C++编程:避免因编译优化引发的多线程死锁问题
c++·多线程·memory·死锁·内存屏障·内存栅栏·memory barrier
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript