zoukankan      html  css  js  c++  java
  • c指针

    内存的编号:
    一个字节(8个位)一个字节编号(即 8个1 或者 8个0)
    一个字节一个编号:编号即地址。
    地址(内存单元的编号)

    指针:
    指针的重要性
    1、 表示一些复杂的数据结构
    2、快速的传输数据
    3、使函数返回一个以上的值
    4、能够直接访问硬件
    5、能够方便的处理字符串
    6、是理解面向对象语言中引用的基础。

    总结:指针是c语言的灵魂
    #include <stdio.h>

    int main(void)
    {
    int * p;
    //p是指针变量(地址变量)的名字,int * 表示p编量存放的int类型变量的地址;
    // int * p 不应该定义了一个名字叫做 *p的变量;
    // int * p 应该这样理解: p是变量名,p变量的数据类型的 int * 类型;
    // 所谓int * 类型 实际就是存放 int变量地址的类型。


    int i;

    p = &i;

    /*

    1、p保存了i的地址,因此p指向i,
    2、p不是i,i也不是p,更准确的说:修改p的值不影响i;
    修改i也不影响p;
    3、如果一个指针变量指向了某个普通变量,则*指针变量
    就完全等同于 普通变量
    例子:
    如果p是个指针变量,并且p存放了普通变量i的地址
    则p指向了普通变量i。

    *p 就完全等同于 i;
    即 在使用出现 *p的地方都可以替换成 i;
    在所有出现 i 的地方都可以替换成 *p;

    */


    return 0;
    }

    1、指针就是地址,地址就是指针;
    2、地址就是内存单元的编号;
    3、指针变量是存放地址的变量;
    4、指针和指针变量的两个不同的概念;
    5、但是要注意:通常我们叙述时会把指针变量简称为指针;
    实际它们含义并不一样;

    6、指针的本质就是一个操作受限的非负整数(只能进行减运算)。

    指针的基本类型:
    1、

    *号的用法:
    1、乘法;
    2、定义指针变量
    int * p;
    //定义了一个名字叫p的变量,int * 表示只能存放int变量的地址;

    3、指针运算符
    该运算符放在已经定义好的指针变量的前面;
    如果p是一个已经定义好的指针变量;
    则*p表示 以p的内容为地址的变量;


    指针和数组:
    指针和一维数组
    一维数组名是个 指针 常量
    它存放的是一维数组的地址;

    下标和指针的关系
    如果p是个指针变量,则
    p[i]永远等价于*(p+i)

    确定一个一维数组需要几个参数
    如果一个函数要处理一个一维数组,则需要接收该数组的那些信息。
    需要两个参数:
    数组第一个元素的地址,
    数组的长度;

    指针变量的运算
    指针变量不能相加,也不能相乘,相除;
    (如果两个指针变量指向的是同一块连续空间的不同的存储单元,
    这两个指针变量才能相减。)
    一个指针变量到底占几个字节;
    知识:
    sizeof(数据类型)
    功能:返回值就是该数据类型所占的字节数;
    例子:sizeof (int) = 4; sizeof(char)= 1;
    sizeof(double) = 8;
    sizeof(变量名)
    功能:返回值是该变量所占的字节数;

    假设p指向char类型变量(1个字节)
    假设q指向int类型变量(4个字节)
    假设r指向double类型变量(8个字节)
    p q r 本身所占的字节数是否一样
    一样,本身所占字节数为4;(32个状态,即32跟线)
    总结:一个指针变量,无论它指向的变量占几个字节;
    该指针变量 本身 只占四个字节
    一个变量的地址使用该变量 首字节的地址 来表示;

    内存中一个字节(8bit)对应一个编号

    指针和二维数组

    printf("%#x ",&a[0]); //a[0]地址的输出;


    如何通过被调函数改变主调函数的值:
    1、实参必须为该普通变量的值。
    2、形参必须为指针变量。
    3、在被调函数中通过
    *形参名 = ....
    的方式就可以修改主调函数相关变量的值。

    专题: (非常重要)
    动态内存控制:
    传统数组的缺点:
    1、数组长度必须事先制定,并且只能是常整数;不能说变量;
    例子:
    int a[5]; //ok
    int len = 5; int a[len]; //error
    2、传统形式定义的数组,该数组的内存程序员无法手动释放。
    数组一旦定义,系统就会为该数字分配存储空间就会一直存在。
    除非数组所在地函数运行结束。
    在一个函数运行期间,系统为该函数中数组分配的
    内存空间会一直存在,直到该函数运行完毕时,
    数组的空间才会被系统释放。

    3、数组的长度一旦定义,其长度就不能在更改。
    数组的长度不能在函数运行的工程中动态的扩充或缩小。

    4、传统方式定义的数组不能跨函数使用。
    A函数定义的数组,在A函数运行期间可以被其他函数使用,
    但A函数运行完毕之后,A函数中的数组将无法被其他函数使用。
    原因是: 调用函数运行完毕,数组空间被释放了。。。

    为什么需要动态分配内存:
    动态数组很好的解决了传统数组的这4个缺陷。
    传统数组也叫静态数组。

    动态内存分配举例___动态数组的构造(难点)

    静态内存和动态内存的比较
    1、静态内存是由系统自动分配,由系统自动释放;
    2、静态内存是在栈分配的,

    3、动态内存是有程序员手动分配, 手动释放的;
    4、动态内存是在堆分配的,


    跨函数使用内存的问题:

    地址:内存单元的编号;

  • 相关阅读:
    http 笔记2 url与资源
    计算机网络一些知识点
    Codeforces Round #652 (Div. 2) B. AccurateLee(思维)
    Codeforces Round #652 (Div. 2) C. RationalLee 贪心
    Codeforces Round #652 (Div. 2)D. TediousLee 推导
    Codeforces Round #652 (Div. 2) E. DeadLee 贪心
    Codeforces Round #651 (Div. 2) A Maximum GCD、B GCD Compression、C Number Game、D Odd-Even Subsequence
    js实现一棵树的生长
    安装python的selenium库和驱动
    Alice's mooncake shop HDU
  • 原文地址:https://www.cnblogs.com/chris-cp/p/3676564.html
Copyright © 2011-2022 走看看