0
点赞
收藏
分享

微信扫一扫

指针(pointer)

指针是什么

指针是一个变量

带地址的传送门 (存放在指针中的值都被当成地址处理)存放在内存单元的地址(编号)

指针也是一个变量,只不过是指针类型的变量  指针的类型为所指向对象的类型

int main()
{
int i = 0;
int* j = &i;//j为指针变量,里面存的是指向对象的地址
printf("%d\n", *j);
return 0;
}

指针(pointer)_数组


指针的类型

为什么存入的类型不同,打印的地址却一样

int main()
{
int i = 0;
int* pa = &i;
char* pc = &i;
printf("%p\n", pa);
printf("%p\n", pc);

return 0;
}

指针(pointer)_指针变量_02

不同类型指针 在通过指针  改变   指向变量的区别!!

对指针进行解引用操作时 不同类型指针改变内存的大小不同

指针类型决定了指针进行解引用操作时,能够访问空间的大小(权重不同)


int main()
{
int i = 0x55667788;
int* pa = &i;
*pa = 1;
return 0;
}

int指针 类型改变了四个字节

指针(pointer)_指针变量_03

&i 

指针(pointer)_数组_04

int main()
{
int i = 0x55667788;
char* pa = &i;
*pa = 1;
return 0;
}

char指针 类型改变了一个字节

指针(pointer)_数组_05

那么double指针能够访问多少字节呐???

指针 + - 整数

对不同的 指针变量  加一 看地址位的变化

int main()
{
int i = 0x55667788;
int* pc = &i;
char* pa = &i;
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pa);
printf("%p\n", pa+1);

return 0;
}

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

int*p;p+1-->4bit

char*p;p+1-->1bit

double*p;p+1-->8bit

指针(pointer)_数组_06


指针的使用

int main()
{
int arr[10] = { 0 };
int i = 0;
int* p = arr;//数组名为首元素地址 所以不需要 &
for (i = 0; i < 10; i++)
{
*(p + i) = 1;//每次地址走动4个字节正好对应数组的存放方式
printf("%d\n", arr[i]);

}

return 0;
}


指针(pointer)_二级指针_07

指针申请的内存空间大小 8Byte   这是64位机器的结果 每次处理8个字节

指针(pointer)_指针变量_08


解引用操作

可以直接对地址进行解引用操作,arr为首元素的地址所以可以对arr进行解引用操作

但是sizeof(arr) 和&arr都是对 数组 进行的操作

&arr[ i ] 是通过下标对数组某元素进行取地址操作

指针(pointer)_数组_09


地址线

每一个地址都对应着唯一的选择(所有地址线通过与门的关系形成唯一一条路径)

8位机的内存 每次处理8bit

指针(pointer)_指针变量_10

二级指针


指针(pointer)_数组_11


指针(pointer)_指针变量_12

指针(pointer)_二级指针_13


二级指针的应用

在二级指针工作时一级的作用只有地址中转站的作用了,具体改变指向变量的空间大小由二级指针决定

二级指针为char类型 只能改变一个字节

此时一级指针为 int 类型 

指针(pointer)_指针变量_14

二级指针为int 类型 可以改变四个字节

此时一级指针为 char类型 

指针(pointer)_二级指针_15


野指针

指针指向的位置是不可知的(随机的,不准确的,没有明确限制的)

指针未初始化指针(pointer)_二级指针_16
指针(pointer)_二级指针_16

指针(pointer)_二级指针_18


int main()
{
int i;
int* p;//局部变量未初始化
*p = 10 ;//错误的 p 中的地址是非法的 随机的
return 0;
}
指针越界访问
int main()
{
int arr[10] = {0};
int* p=arr;
int i = 0;
for (i = 0; i < 12; i++)//超出数组元素的范围
{
*p++ = i; //指针越界就是野指针
}
return 0;
}
int main()
{
int arr[10] = {0};
int* p=arr;
int i = 0;
for (i = 0; i < 12; i++)
{
*p = i;
p = p + 1;//每一次加的是元素个数 是int 类型的4Byte
}
return 0;
}

指针(pointer)_二级指针_19


指针指向的内存空间被释放

(封装函数里的变量内存) 

int* test()
{
int i = 0;
return &i;//返回为地址 函数类型为指针
}
int main()
{

int* p = test();//接收为指针类型来接收
*p = 10;

return 0;
}


int* test()
{
int i = 0;
int* p = &i;
return p;//返回的类型为指针决定了函数的类型

}
int main()
{
int** pa = test();//是不是应该使用二级指针来接收??
**pa = 10;//pa指向的地址是临时的 此时已经被销毁

return 0;
}

static的使用

变量i出局部范围就注销了但是经过 static 的修饰变成静态局部变量,从外面可以使用指针进行访问,但是不可以直接引用变量i。i的地址和值被保存,但是范围还是局部范围。

int* test()
{
static int i = 0;
return &i;//返回为地址 函数类型为指针
}
int main()
{

int* p = test();//接收为指针类型来接收
*p = 10;
printf("%d\n", *p);

return 0;
}


NULL 空指针

指针(pointer)_二级指针_20

NULL 为0,强制类型转换为空指针。

int main()
{

int a = 0;
int* p = &a;
int* pa = NULL;//空指针,不知道指向哪个地址,暂时赋值为0 但是类型为指针
p = NULL;//不使用这个地址了就把指针变量 p 赋值为空指针

return 0;
}

检查指针的有效性


int main()
{

int a = 10;
int* p = &a;
int* pa = NULL;
if (pa != NULL)
{
//指针为有效地址才使用这个指针
*pa = 10;//为空指针不能进入判断
}

return 0;
}


指针的运算

为什么最后打印的数不是数组的最后一个元素


指针(pointer)_数组_21

#define N_values 5
int main()
{
float values[N_values]={1,2,3,4,5};
float* p=&values;
for (p = &values[0]; p < &values[N_values];)
{
*p++ = 0;//*p++ 先解引用 然后自增1 导致指针在最后变成野指针
printf("%f ", *p);//values[0]指向的变量没有打印
}
return 0;
}


稍微改一下就行  不要让指针越界变成野指针

指针(pointer)_数组_22


指针减指针

指针减去指针得到是两指针中间的元素个数

int main()
{

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int ret = &arr[9] - &arr[0];
printf("%d\n", ret);
return 0;
}



指针(pointer)_指针变量_23


不同类型的指针相减 得到的是随机数 没有意义

指针减指针必须满足 指针指向的是同一个数组的内存空间

指针(pointer)_数组_24


指针求字符串的长度

计数的方式    函数递归的方式    指针的方式 


int My_strlen(char* pa)//使用指针来接收首元素的地址{
{
char* star = pa;//star end是二级指针吗???

char* end = pa;//pa不需要进行解引用操作吗?? pa不是指针变量吗??

while (*end != '\0')
{
end++;
}
return end - star;
}
int main()
{
char arr[] = "ling song";
int ret = My_strlen(arr);//使用指针求字符串的长度
printf("arr[0]= %p\n", &arr[0]);
//printf("%d\n", ret);
return 0;
}
int My_strlen(char* pa)//使用指针来接收首元素的地址
{
int i = 0;
while (*pa != '\0')//字符串结束标志
{
pa++;//指针变量自增1 增加的 是元素的个数
i++;
}
return i;
}

int main()
{
char arr[] = "ling song";
int ret = My_strlen(arr);//使用指针求字符串的长度
printf("%d\n", ret);
return 0;
}

指针变量有没有自己的内存空间

指针(pointer)_二级指针_25

star end是一级指针 ,里面存放的是地址,而不是指针。 


指针变量是有自己的地址,只是变量里面存放是指向变量的地址 

int main()
{
int i = 0;
int* p = &i;
printf("%p\n", &i);
printf("%p\n", p);
printf("%p\n", &p);
return 0;
}

指针(pointer)_指针变量_26


指针数组

存放指针的数组 

指针(pointer)_数组_27








举报

相关推荐

0 条评论