广而告知: 博客写得好,Emoji要选好!!🎵 🎶 🔈 🔇 🔉 🔊 🔔 🔕 📣 📢
写博客是知识是巩固和温习,所以在这个信息爆炸的时代,每个人每天都要接收很多讯息,你的记忆是有限的,知识也是有限的,时间也是有限的,既然如此,那是时候磨亮我的五十米大刀了。 你很强,上天揽月你不行,你很强,下海捞鱼总行吧!
💀☠💩🤡👹👺👻👽👾🤖 -->渴望知识!!!
目录
1.指针变量类型的意义
2.Const修饰指针变量
3 指针运算
4.指针的关系运算
1.指针变量类型的意义
指针变量的大小与类型无关,只要是指针变量,只跟使用的平台有关系。
1.1指针的解引用
在内存中查看指针是如何进行修改字节内的内容
初始值放置的是0x44332211
#include <stdio.h>
int main()
{
int n = 0x44332211;
int* ptr = &n;
*ptr = 0;
return 0;
}
当执行完*ptr=0;之后,a的值被修改成了00 00 00 00
可见当ptr在操作整型的时候可以同时操作4个字节,并进行修改。
1.2 指针的运算
&n的地址008FFD3C
ptr指针变量指向变量a的地址也就是&a地址,008FFD3C
但是ptr使用char*类型进行强制类型转换,ptr+1,则是跳过1个字节008FFD3D
p指针变量指向变量a的地址也就是&a地址,008FFD3C
但是p使用int* 类型进行强制类型转换,p+1,则是跳过4个字节008FFD40,
#include <stdio.h>
int main()
{
int n = 10;
char* ptr = (char*)&n;
int* p = &n;
printf("%p\n",&n);
printf("%p\n",ptr);
printf("%p\n",ptr+1);
printf("%p\n",p);
printf("%p\n",p+1);
return 0;
}
总结:指针的类型决定了指针位移的字节数。
2.Const修饰指针变量
2.1 定义的变量本身是可以被修改的,而被指针指向的变量,是可以指针变量来修改这个变量的值。
那么如果,你不想这个变量被修改,那么可以在这个变量前面加上const,就无法修改这个变量的值了。
#include<stdio.h>
int main()
{
int a = 20;
const int b = 10;
b = 20;
return 0;
}
当我们将b使用const进行修饰之后,在编译的时候会出现无法编译通过,这就是const的作用。
2.1.1可以通过指针修改变量的值
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int* ptr = &a;
*ptr = 20;
ptr = &b;
}
一开始a的值在十进制表示是10,而在内存中是以十六进制存储,因为看到的是0a
当进行*ptr=20修改变量a的数值之后,会看到内存中的&a的数值变成14(十六进制显示)
2.2 那些情况下指针变量无法修改const修饰的变量
2.2.1 使用const来修饰之后,会发现无法编译
2.2.2 将const放在int *的右侧,也是无法编译成功的
2.2.3 在ptr左侧和*左侧分别加上const,这样子也是无法编译的
通过以上几个示例,我们可以总结如下:
1)const如果放在*的左边,修饰的是指针指向的内容,确保指针指向的内容不能通过指针来修改。
2)const如果放在*的右边,修饰的指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针修改。
3 指针运算
指针运算有三种:指针+-整数,指针-指针,指针的关系运算
3.1 指针+-整数
分析数组在内存中的存储:数组在内存中的存储是连续的,只要知道数组内第一个元素的地址,就可以找到其他地址对应的元素。
我们用一张图来体现,数组在内存中是联系存放的。
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
return 0;
}
3.1.1 指针+整数
那么如果是用指针来进行+-整数的时候会是什么样子呢?
ptr+i //这里就算指针的+整数
ptr+i=&arr[i],ptr+i是一个地址,*(ptr+i)对地址进行解引用
同时还等等价于*(ptr+i)=*(arr+i)
3.1.1.1指针操作整型
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int n = 0;
int* ptr = &arr;
n = sizeof(arr)/sizeof(arr[0]);
for (int i = 0; i < n; i++)
{
printf("%d\n",*(ptr+i)); //*解引用,跳过四个字节,往后访问 ptr+i=&arr[i],ptr+i是一个地址,*(ptr+i)对地址进行解引用
printf("%d\n", *(arr + i));
//printf("%d\n",*p);
//p=p+1; //p+1 跳过一个整型
}
return 0;
}
3.1.1.2指针操作字符型
#include <stdio.h>
int main()
{
char str[] = "abcde";
char* ptr = &str;
while (*ptr != '\0')
{
printf("%c",*ptr);
ptr++;
}
return 0;
}
给大家打印一下
3.1.2 指针-指针
3.1.2.1使用的前提:两个指针是指向同一块空间的
指针-指针其实就是等于地址-地址
指针-指针得到的是指针和指针之间元素的个数。
//指针-指针
//前提:两个指针是指向同一块空间的
//指针-指针得到的绝对值等于两个指针之间元素的个数
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int a = &arr[9] - &arr[0]; //指针-指针就等于地址-地址
//arr[0]+9 = arr[9]
printf("%d\n",a);
return 0;
}
3.1.2.2如何实现你自己的strlen()函数,用来计算字符的个数
我们可以使用指针的方式,来实现,下面是实现的代码。
int my_strlen(char * ptr)
{
int count = 0;
while (*ptr != '\0')
{
ptr++;
count++;
}
return count;
}
#include <stdio.h>
int main()
{
int a=my_strlen("abcdef");
printf("%d\n",a);
return 0;
}
下面我们使用第二种方法
#include <stdio.h>
intmy_strlen(char* str)
{
int* start = str; //用指针变量start 来存储str的首地址
while(*str !='\0') //对str解引用之后的字符与‘\0’做比较,进行条件判断
{
str++;
}
return str - start; //相当于指针-指针,而定义已知指针减去指针得到的绝对值就是指针之间的元素个数
}
int main()
{
int a=my_strlen("abcdef");
printf("%d\n",a);
}
4.指针的关系运算
从数组的起始地址开始往后遍历,当ptr访问到最后一个元素的时候,认为循环结束,跳出while循环。
起始地址加上10,跳过10个元素就指向最后一个地址
进行指针的大小比较 。 比较两个地址的大小关系
//指针的关系运算,比较指针地址大小,然后进行数据输出
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* ptr = arr;
while (ptr < arr + 10) //arr+10 是为了指向最后一个元素10的后面,如果ptr的指针跳出10个元素之后,则跳出while循环
{
printf("%d ",*ptr);
ptr++; //ptr++ 跳过一个元素
}
return 0;
}
最后,请各位发财的金手指,帮忙点点赞和关注!
💁♂️💁♀️🙋🙋♂️🙋♀️🧏🧏♂️一赞三连🧏♀️🙇🙇♂️🙇♀️🤦🤦♂️🤦♀️🤷🤷♂️🤷♀️
💁♂️💁♀️🙋🙋♂️🙋♀️🧏🧏♂️一赞三连🧏♀️🙇🙇♂️🙇♀️🤦🤦♂️🤦♀️🤷🤷♂️🤷♀️
💁♂️💁♀️🙋🙋♂️🙋♀️🧏🧏♂️一赞三连🧏♀️🙇🙇♂️🙇♀️🤦🤦♂️🤦♀️🤷🤷♂️🤷♀️