首页 > 其他分享 >指针

指针

时间:2022-11-20 19:03:13浏览次数:44  
标签:arr return int 地址 printf 指针

指针是什么

在计算机科学中,指针(pointer)是编程语言的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中的另一个地方的值.由于通过地址能够找所需的的变量单元。可以说,地址指向该变量单元。因此,降低至形象化的称为“指针”,意思就是通过它能找到以它为地址的内存单元

指针

指针就是个变量,存放内查询单元的地址(编号)

//对应到代码
int main() {
int a = 10;
int* p = &a;//指针变量 - 存放地址的变量
return 0;
}

1.一个小的的单元到底是多大(1个字节) 2.如何编址

32位的机器上产生32根地址线 - 2的32次方个地址 64位的机器上产生64跟地址线 - 2的64次方个地址

这里我们就明白

在32位的机器上,地址是32个0或1组成的二进制序列,那地址就用4个字节的空间来存储,所以一个指针变量的大小应该是4个字节 如果在64位的机器上,如果有64根地址线,拿一个指针变量的大小是8个字节,才能存放一个地址

总结 指针是用来存放地址的,地址是唯一标识一块地址空间的 指针的大小在32位平台是4个字节,在64位平台是8个字节

指针和指针类型

这里我们讨论下:指针的类型 我们都知道

指针类型的意义

1.解引用操作

指针类型决定了指针进行解引用操作的时候,能访问的空间的大小

int* p;p能够访问4个字节

char p;p能够访问1个字节

double p;*p能够访问8个字节

2.指针+-整数

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

intp;p+1 --> 4

charp;p+1 --> 1

double*p;p+1 --> 8

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

printf("%p\n", pc);
printf("%p\n", pc+1);

return 0;
}
//00000002E60FF7E4
//跳过4个字节
//00000002E60FF7E8

//00000002E60FF7E4
//跳过1个字节
//00000002E60FF7E5

指针_数组名

总结:指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。比如:char*的指针解引用就只能访问一个字节,而int*的指针解引用就能访问四个字节

野指针

概念:野指针就是指针指向的位置是不可预知的(随机的,不正确的,没有明确限制的)

野指针的成因

1.指针未初始化

int main() {
int a;//局部变量不初始化,默认是随机值
int* p;//局部的指针变量,就被初始化随机值

return 0;
}

2.指针越界访问

int main() {
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 12; i++) {
//当指针指向的范围超出数组arr的范围时,p就是野指针
p++;
}
return 0;
}

3.指针指向的空间释放

int* test() {
int a = 10;
return &a;
}
int main() {
int* p = test();
*p = 20;
return 0;
}
如何规避野指针的产生

1.指针初始化 2.小心指针越界 3.指针指向空间释放即使置NULL 4.指针使用之前检查有效性


int main(){
//指针释放空间使其为NULL
int* p=NULL;
int a = 10;
p = &a;
if(p !=NULL){//判断是否为NULL
*p = 20;
}
return 0;
}

指针运算

指针 +- 整数

指针 - 指针

指针的关系运算

指针 +- 整数
//指针+指针
#define N_VALUES 5
float valies[N_VALUES];
float *vp;
//指针 +- 整数:指针的关系运算
for(vp=&values[0];vp < &values[N_VALUES];){
*vp++ = 0;
}
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int i=0;
int sz=sizeof(arr)/sizeof(arr[0]);
int* p = arr;
for(i=0;i<sz;i++){
printf("%d\n",*p);
p++;//p=p+1
}
return 0;
}
指针 - 指针
int main(){
char ch[5] = {0};
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr[9]-arr[0]);//指针 - 指针 = 中间元素个数 -- 9
//printf("%d\n",arr[0]-arr[9]); -- -9
printf("%d\n",&arr[9] - &ch[0]);//结果不可预知,错误的写法 - int型和char型不能做加减
return 0;
}
int my_strlen(char* str) {
char* start = str;
char* end = str;
while (*end != '\0') {
end++;
}
return end - start;
}
int main() {
//strlen - 求字符串长度
//递归 - 模拟实现了strlen - 计数器的方式1,递归的方式2

//第三种方法
char arr[] = "bit";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
指针的关系运算
#define N_VALUES 5
float valies[N_VALUES];
float *vp;
//指针 +- 整数:指针的关系运算
for(vp=&values[0];vp < &values[N_VALUES];){
*vp++ = 0;
}

for(vp = &values[N_VALUES-1];vp >= &values[0]; vp--){//不允许的
*vp = 0;
}

实际在绝大多部分的编译器上市可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证可行。

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

指针和数组

int main() {
int arr[10] = { 0 };
printf("%p\n", arr);//地址 - 首元素的地址
printf("%p\n", arr+1);//+4
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0]+1);//+4
printf("%p\n", &arr);//&arr - 取出的是整个数组的地址
printf("%p\n", &arr+1);//+40
//1.&arr - 数组名 - 数组名不是首元素的地址 - 数组名表示整个数组 - &数组名 取出的是在整个数组的地址
//2.sizeof(arr) - sizeof(数组名) - 数组名表示的整个数组 - sizeof(数组名)计算的是整个数组的大小
return 0;
}

指针_数组_02

二级指针

int main() {
int a = 10;
int* pa = &a;
int** ppa = &pa;//ppa就是一个二级指针
printf("%d\n", *pa);//通过pa直接访问a的地址
printf("%d\n", **ppa);//通过ppa访问pa的地址,pa中保存的又是a的地址.ppa ->pa ->a

//printf("%d\n", **ppa);

//int*** pppa = &ppa;//pppa三级指针
return 0;
}

指针数组

//指针数组 -- 数组
//数组指针 -- 指针
int main() {
//多个指针变量时
int a = 10;
int b = 20;
int c = 30;
/*
int* pa = &a;
int* pb = &b;
int* pc = &c;*/
//这种方法比较笨
//整型数组 - 存放整形
//字符数组 - 存放字符
//指针数组 - 存放指针
//int arr[10];
int* arr2[3]={&a,&b,&c};//指针数组
int i = 0;
for (i = 0; i < 3; i++) {
printf("%d\n",*(arr2[i]));
}
return 0;
}

这里大致说一下指针,了解一下什么是指针,是干什么用的,什么储存原理,了解其中的一些名词。

标签:arr,return,int,地址,printf,指针
From: https://blog.51cto.com/u_15812262/5871608

相关文章

  • 指针的基础知识(上)
    大家晚上好呀,今天要给大家带来的是关于指针的基础知识点。首先,我们都知道如何一个整型的变量,并赋值给它。如:inti=5;但它在电脑中具体的运行是怎么样的呢?其实啊,首先在电脑内......
  • 【c&c++】二级指针的使用
    有时候,我们需要在函数体的内部申请内存空间并初始化,然后将内部申请的存储空间交付给外部指针来引用,这时候,我们可以使用二级指针作为申请空间的函数的参数来实现。main.c......
  • c指针
    intp;//这是一个普通的整型变量int*p;//首先从P处开始,先与*结合,所以说明P是一个指针,然后再与int结合,说明指针所指向的内容的类型为int型.所以P是一个返回整型......
  • 函数指针
     1#include<cstdio>2#include<iostream>3usingnamespacestd;4intmax(intx,inty)5{6returnx>y?x:y;7}8intmain()9{10int......
  • 重载为什么一定要指针才行呢?请专家解答下
    请教专家,为什么下面的代码都是输出A类的方法,而采用指针才能达到重载的目的。1#include<endian.h>2#include<iostream>3usingnamespacestd;45classA......
  • C语言的灵魂——指针
    相关视频——强烈推荐【强烈推荐】4小时彻底掌握C指针-顶尖程序员图文讲解-UP主亲自翻译校对(已完结)_哔哩哔哩(゜-゜)つロ干杯~-bilibili我的小站——半生瓜のblog......
  • 数组指针和指针数组?
    首先,理解一下数组指针和指针数组这两个名词:“数组指针”和“指针数组”,只要在名词中间加上“的”字,就知道中心了——数组的指针:是一个指针,什么样的指针呢?指向数组的指针......
  • 代码随想录day1补充之LeetCode27移除元素相向双指针法&补充题目---LeetCode35搜索插入
    1.LeetCode27移除元素题是晚上刷的,今天看发现第一天的题目只写了快慢指针法(见链接Day1),现补充练习实现相向双指针法。分析:相向双指针法是指使用左右指针,左指针寻找需要移......
  • C++:将char*指针强制转换成一个指向结构体的指针
    在使用Socket与雷达进行通信采集数据时,会遇到“打包与解包”的问题,在打包和解包过程中,会涉及到结构体指针与字符指针间的强制转换。如下:打包就是将包头与信息封装成一定大......
  • 数组指针强制转换为结构体指针
    前两天在看TI官方提供的BasicRF的源码时,发现一个看不懂的地方,就是将一个数组名强制转换为结构体指针,如下所示。   在上面的图片中,basicRfPktHdr_t是一个结构体,rxM......