zoukankan      html  css  js  c++  java
  • <C> 指针

    引入:

    二进制中的三位 对应 八进制中的一位

    二进制中的四位 对应 十六进制中的一位

    例:001 010 011(2)→123(8)→0x53(53)

    注:在位数不够的时候 前面补零去看

    一.对一个变量我们可以进行哪些操作

    1.写操作:a = 10;

    2.读操作:用printf输出一个数的值

    3.取地址操作:&a; 

    ①内存→一个格子一个字节 例如:int a; 就是向系统申请了四个字节

    一个格子就像一个房间 每个房间都有不同的编号 这个编号 就可以叫做内存的地址

    ②表示方法:取地址符 + 变量名称

    如若想查看一个一个变量的地址 可以打为 printf("%p ",&a); 来查看a的地址 返回的是首地址

    ③在32位中 地址是由8个16进制的数组成的 (00000000~FFFFFFFF)

    注:每次在查看地址的时候 地址是变的 不是固定的

    因为程序执行结束以后地址就会被收回 如果要再次执行就要重新分配空间

    地址的名字是不再占用内存空间的

    ④地址偏移:

    int型 4个字节 输出&a 和&a+1 结果差4

    char 1个字节 输出&b 和&b+1 结果差1

    结论:看指针所能操作的内存大小 看类型 与右边无关 看左边

    间接引用 *:指的是对内存空间进行操作

    用法:* + 地址

    二.指针

    1.定义:本质是用来存储地址的变量

    用法:变量类型 + * + 名(变量类型是需要存储地址的变量类型

    例如:

    1 int* p = &a;
    2 //p中存的是a的地址

    注:p→&a 即*p = *&a = a的值 p中放的是a的地址 *p是a的值 指向空间的内容

    2.sizeof():

    sizeof不是一个函数 是一个操作符 是求变量或者类型的大小的(即占多少个字节)

    例如:

     1 #include<stdio.h>
     2 int main()
     3 {
     4     int a = 10;
     5     char b = 'a';
     6     int* p = &a;
     7     char* pp = &b;
     8     printf("%d
    ",sizeof(p));
     9     printf("%d
    ",sizeof(pp));
    10 }

    上面这段程序在32位电脑中 运行的结果是4 4 在64位电脑中 结果应该是8 8

    那么这就说明了:指针的大小与指向变量的类型是无关的

    3.如何判断一个变量的类型呢?

    去掉变量名 剩下的就是类型 

    4.如何判断一个指针所指向的类型?

    去掉变量名 去掉一个* 所剩下的就是指针所指向的类型

    5.多个指针可以指向同一空间(变量)因为他们的值是一样的

    例题:

    1 #include<stdio.h>
    2 int main()
    3 {
    4     int a;
    5     int* p1 = &a;
    6     int* p2 = &a;
    7     *p1 = 100;
    8     printf("%d
    ",*p2);
    9 }

     6.大端存储和小端存储:

    大端存储通常在网络设备中 与小端相反 小端存储一般用于个人电脑 是低地址存在低字节中

    字节序是从左到右的 从高到低

    例题:int a = 0; char* p = &a;如何能让printf("%d ",a)输出999999?

    999999的二进制为 00000000 00001111 01000010 00111111(0 15 66 63)

     1 #include<stdio.h>
     2 int main()
     3 {
     4     int a = 0;
     5     char* p = &a;
     6     *p = 63;
     7     p = p + 1;
     8     *p = 66;
     9     p = p + 1;
    10     *p = 15;
    11     printf("%d
    ",a);
    12 }

    注:指针的大小与右边是无关的 与左边的类型有关

    以下两种解决方式也都可以 在数组的地方 还可以有第四种解决方式

     1 #include<stdio.h>
     2 int main()
     3 {
     4     int a = 0;
     5     char* p = &a;
     6     *p++ = 63;
     7     *p++ = 66;
     8     *p++ = 15;
     9     printf("%d
    ",a);
    10 }
     1 #include<stdio.h>
     2 int main()
     3 {
     4     int a = 0;
     5     char* p = &a;
     6     *p = 63;
     7     *++p = 66;
     8     *++p = 15;
     9     printf("%d
    ",a);
    10 }

    三.运算符优先级

    这里放几道例题:a = 0; b = 1;

    1.a = b++; //输出结果为 a = 1; b = 2;

    2.a = ++b; //输出结果为 a = 2; b = 2;

    3.a = ++b + ++b; //输出结果为a = 6; b = 3;(两边的b都变成了3)

    4.a = b++ + b++; //输出结果为a = 2; b = 3;(这里的b是到下一行才变的)

    5.

    1 int n = 21;
    2 printf("%d %d
    ",n,n++);

    输出结果为:22 21

    这里就要提到一个叫函数栈的东西 它是符合栈的存储形式的

    n先进栈 n++后进栈 先计算n++ 但此时n已经变成22 所以n输出为22

    1 int n = 21;
    2 printf("%d %d
    ",--n,--n);

    输出结果为:19 19

    .野指针

    如果申请了一个指针 暂时不知道应该存谁的地址 那么就让它 = NULL

    注:永远都不要操作不属于你的程序的内存空间

    五.二级指针

    这里就简单粗暴的放一道例题了解一下:

    int a = 1; int b = 2; int* p = &a; int** pp = &p; 怎样才能使pp通过printf("%d ",*p)输出b的值?

    #include<stdio.h>
    int main()
    {
        int a = 1;
        int b = 2;
        int* p = &a;
        int** pp = &p;
        *pp = &b;
        printf("%d
    ",*p);
    }

    分析:*p = a

    * pp = p = &a

    ** pp = a

  • 相关阅读:
    LeetCode 242. Valid Anagram (验证变位词)
    LeetCode 205. Isomorphic Strings (同构字符串)
    LeetCode 204. Count Primes (质数的个数)
    LeetCode 202. Happy Number (快乐数字)
    LeetCode 170. Two Sum III
    LeetCode 136. Single Number (落单的数)
    LeetCode 697. Degree of an Array (数组的度)
    LeetCode 695. Max Area of Island (岛的最大区域)
    Spark中的键值对操作
    各种排序算法总结
  • 原文地址:https://www.cnblogs.com/Aaaaaalei0612/p/8684482.html
Copyright © 2011-2022 走看看