【带你玩转C语言】指针详解

141 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

指针(初阶)


一 、指针开辟内存空间

#include<stdio.h>
int main(){
    int a=10;//a为整型变量占用四个字节的空间
    int* pa = &a;//pa为指针变量,用来存放地址
    return 0;
}

&a 取的是第一个字节的地址,

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

char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

在32位平台下指针变量大小pc pi ps ...均为4个字节,64位平台下均为8个字节

既然在同一平台下指针的大小一致,那么指针类型存在的意义是什么?

二、指针类型的意义

#include<stdio.h>
int main(){
     int a = 0x11223344
     int * pa = &a;
     *pa = 0;
     return 0;
}

观察内存结果

可知四个字节均发生改变,int* 整型指针解引用时访问四个字节

char* pc =(char*)&a;// char* 类型的pc 仍可以存下a的地址
*pc  = 0;
return  0;

仅改变一个字节, char* 类型解引用仅访问一个字节

✔指针类型决定了指针在解引用时访问几个字节

#include <stdio.h>
int main()
{
  int n = 0x11223344;
  int* pi = &n;
  char* pc = (char*)&n; 
  printf("pc = %p\n", pc);
  printf("pc +1 = %p\n", pc+1);
  printf("pi = %p\n", pi);
  printf("pi+1 = %p\n", pi+1); 
  
  return  0;
 }

✔指针的类型决定了指针向前或者向后走一步有多大(距离)

总结:

✔指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节/访问能力)。

比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

int* p 能够访问四个字节 char* p 能够访问一个字节 double* p 能够访问八个字节

但是 float* 和 int*的解引用均访问4个字节空间大小,但是在内存中的存储方式完全不同,不能混用

三、野指针

  1. 指针未初始化
#include <stdio.h>
int main()
{ 
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}

2.指针越界访问

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=10; i++)
   {
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
   }
    return 0; }
  1. 指针指向的空间释放

四、指针运算

指针加减整数

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
    int arr[10] = { 0 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int* p = arr;
    for (int i = 0; i < sz; i++) {
        *p = 1;
         p++;
    //*(p+i)= 1
    }
    return 0;
}

指针++,向前移动

指针-指针

#include<stdio.h>
int main(){
  int arr[10] = {0};
  printf("%d\n",&arr[9] - &arr[0]);
  return 0;
}

✔前提:指向同一块空间的两个指针才能相减

✔结果:|指针-指针|的绝对值得到得到指针和指针之间的元素个数

五、指针与数组

六、二级指针

✔二级指针主要存放的是一级指针变量的地址

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

七、指针数组

✔存放指针的数组

for(int i = 0;i < 2;i++){
  printf("%d",*(parr[i]));
}

即可输出各元素的值

八、二级指针与二维数组

#include<stdio.h>
int main() {
	int arr1[4] = { 1,2,3,4 };
	int arr2[4] = { 2,3,4,5 };
	int arr3[4] = { 3,4,5,6 };
	int* parr[3] = { arr1,arr2,arr3 };
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 4; j++) {
			printf("%d ", parr[i][j]);
		}
		printf(" \n");
	}
	return 0;
}