【筑基系列】 初识C指针

简介: C指针必会知识

一 、指针开辟内存空间

#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;
}

相关文章
|
4月前
|
C++
C/C++工程师面试题(指针篇)
C/C++工程师面试题(指针篇)
81 0
|
1月前
|
搜索推荐 编译器
【C初阶】进一步初识指针
【C初阶】进一步初识指针
|
存储 编译器 C语言
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它4
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它4
|
编译器 C语言
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它3
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它3
|
存储 C语言
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它1
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它1
|
4月前
|
存储 安全 编译器
【指针:掌握它,让你的程序如虎添翼】
【指针:掌握它,让你的程序如虎添翼】
|
11月前
|
存储 C++
指针与数组的 “ 爱恨情仇 ”——指针进阶(一)
指针与数组的 “ 爱恨情仇 ”——指针进阶(一)
35 0
|
C语言
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它2
【C语言】 指针篇,不会的一定要看,指针没有想象的那么难,我们一起攻克它2
指针的进阶【中篇】
指针的进阶【中篇】
60 0