zoukankan      html  css  js  c++  java
  • C语言知识点总结

    /*2018年4月24日17:36:45
    author:TangHui
    指针知识的整理
    */

    /*
    1.指针:
    (指针的重要性)
    表示一些复杂的数结构
    快速的传递数据,减少内存的耗用
    使函数返回一个以上的值 //举例
    能直接访问硬件(因为指针就是地址)
    能够方便的处理字符串
    是理解面向对象语言中引用的基础

    总结:指针是C语言的灵魂


    指针的定义:
    地址:
    内存单元的编号
    从0开始非负整数
    内存大小: (32根线)
    分析:00 01 10 11 4种情况 也就是2根线的情况
    1k = 2的10次方b
    1M = 2的10次方kb = 2的20次方b
    1G = 1024M = 2的30次方b
    2的32次方 = 2的30次方 * 2的2次方 = 4G
    32根线 也就是2的32次方的单元 但每个单元8位 就是 2的32*8 约等于 4G(内存)
    范围:4G

    指针:
    指针就是地址,地址就是指针
    指针变量就是内存单元存放单元编号的变量,或者说指针变量就是存放地址的变量。
    指针和指针变量是2个不同的概念
    但要注意的:通常我们叙述时会把指针变量简称为指针,实际上他它们的含义不一样。
    指针的本质就是一个操作受限的非负整数

    指针的分类:
    1.基本类型的指针
    int *p;//p是变量的名字,int * 表示p变量存放的是int类型变量的地址
    //int * p;不表示定义了一个名字叫做*p的变量
    //int *p;应该这样理解:p是变量名,p变量的数据类型是int *类型
    // 所谓int *;类型就是存放int 变量地址的类型
    int i = 3;
    int j;
    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
    *p 就是以p的内容为地址的变量

    j = *p;
    printf("i = %d,j=%d ",i,j);//3,3


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

    2.指针和数组
    指针和一维数组
    数组名

    下标和指针的关系

    指针变量的运算

    指针和二维数组

    3.指针和函数

    4.指针和结构体

    5.多级指针

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

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

    4.a函数定义的数组,在a函数运行的期间可以别其他函数使用,
    但a函数运行完毕后, a函数中的数组将无法被其他函数使用。
    函数使用
    传统方式定义的数组不能跨函数使用

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

    动态内存分配举例_动态数组的结构

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

    动态内存是由程序员手动分配,手动释放
    动态内存是在堆分配的(堆排序)

    跨函数使用内存的问题

    结构体
    为什么需要结构体
    为了表示一些复杂的事物,而普通的基本类型无法满足我们实际要求
    什么叫结构体
    把一些基本类型数据组合在一起形成一个新的复合数据类型,这个就叫结构体
    如何定义一个结构体
    3种方式
    //第一种
    struct Student//定义了一个数据类型
    {
    int age;
    float score;
    char sex;
    };

    //第2种
    struct Student2
    {
    int age;
    float score;
    char sex;
    } st2;


    //第3种
    struct//定义了一个数据类型
    {
    int age;
    float score;
    char sex;
    } st3;

    怎么使用结构体变量
    赋值和初始化
    定义的同时可以整体赋储值
    如果定义玩之后,则只能单个的赋初值

    如何取出结构体变量中的每一个成员
    1.结构体变量名.成员名
    2.指针变量名->成员名 (第二种更常用)
    指针变量名->成员名 在计算机内部会被转换为(*指针变量名).成员名
    的方式来执行
    所以说这两种方式 是等价的

    例子:
    struct Student//定义了一个数据类型
    {
    int age;
    float score;
    char sex;
    };

    int main(void)
    {
    struct Student st={80,66.6,'F'};//定义了一个变量

    struct Student * pst = &st;//定义一个指针变量,类型为struct Student
    //&st不能改为st
    st.age; //第一种方式
    pst->age;//第二种方式
    }

    1. pst->age 在计算机内部会被转换为(*pst).age,没有为什么
    这就是->的含义,这就是一种硬性的规定

    2. 所以pst->age 定价于(*pst).age 也等价于 st.age

    3. 我们之所以知道pst->age 等价于st.age,是因为pst->age是被转换为了
    (*pst).age来执行

    4.pst->age 的含义:
    pst所指向的那个结构体变量中的age这个成员


    结构体变量和结构体变量指针作为函数参数传递的问题
    推荐使用结构体指针变量作为函数参数来传递
    结构体变量的运算
    结构体变量不能相加,不能相减,也不能相互乘除
    但结构体变量可以相互赋值
    例子:
    struct Studnet
    {
    int age;
    char sex;
    char name[100];
    };//分号不能省略
    struct Studnet st1,st2;
    st1+st2 st1*st2 st1/st2 都是错误的
    st1 = st2 或者st2 = st1 都是正确的
    举例:
    动态构造存放学生信息的结构体数组
    动态构造一个数字,存放学生的信息
    然后按分数排序输出

    枚举
    什么是枚举
    把一个事物所有可能的取值一一列举出来
    怎么样使用枚举

    枚举的优缺点
    代码更加安全
    书写麻烦

    位运算符:
    &---按位于
    && 逻辑与 也叫并且
    &&与& 含义完全不同
    1&1 = 1
    1&0 = 0
    0&1 = 0
    0&0 = 0
    5&7 = 5
    21&7 = 5;

    |---按位或

    ||逻辑或
    | 按位或

    1 | 0 = 1
    1 | 1 = 1
    0 | 1 = 1
    0 | 0 = 0

    ~--- 按位取反
    ~i就是把i变量所以的二进制位取反

    ^按位异或
    相同为0
    不同为1
    1 ^ 0 = 1
    0 ^ 1 = 1
    1 ^ 1 = 0
    0 ^ 0 = 0

    <<--按位左移
    i<<3表示把i的所有二进制位左移3位,右边补零
    左移n位相当于乘以2的n次方
    面试题:
    A)i = i*8;
    B)i = i << 3;
    请问上面哪个语句执行速度快?
    答案:B

    >>--按位右移
    i>>3表示把i的所有二进制位右移3位,左边一般补零,当然也有可能补1
    左移n位相当于除以2的n次方 ,前提是数据不能丢失
    面试题:
    A)i = i/8;
    B)i = i >> 3;
    请问上面哪个语句执行速度快?
    答案:B

    位运算符的现实意义
    通过位运算符,我们可以对数据的操作精确到每一位


    >>--按位右移



    专题:
    原码
    也叫 符号-绝对值码
    最高位0表示正 1表示负,其余二进制是该数字的绝对值的二进制位

    原码简单易懂
    加减运算赋值
    存在加减乘除四种运算,增加了cpu的复杂度
    零的表示不唯一(1000/0000)

    反码
    反码运算不便,也没有在计算机中应用

    移码
    移码表示数值平移n位,n称为移码量
    移码主要用于浮点数的阶码的存储

    补码
    已知十进制转二进制
    求正整数转二进制
    除2取余,直至商为零,余数倒叙排序

    求负整数转二进制
    先求与该负数相对应的正整数的二进制代码 ,然后将
    所有位取反,末尾加1,不够位数时,左边补一
    (根据自己定义的容器的大小,比如int 32个字节
    eg:-3的补码
    1111....1101(一共32位)
    FFFFFFFD



    求零转二进制
    全是零

    已知二进制转十进制
    如果首位是0,则表明是正整数,按普通方法来求

    如果首位是1,则表明是负整数
    将所有位取反,末尾加1,所得数字就是该负数的绝对值
    (eg:



    如果全是零,则对应的十进制数字就是零


    学习目标:
    在vc++6.0中一个int类型的变量所能存储的数字的范围是多少?
    int类型变量所能存储的最大整数用十六进制表示 7FFFFFFF
    int类型变量所能存储的绝对值最大的负整数用十六进制表示为80000000
    具体参见补码.png图片

    最小负数的二进制代码是多少?
    最大正数的二进制代码是多少?
    已知一个整数的二进制代码求出原始的数字?
    数字超过最大正数会怎么样?
    溢出,只会截取地位的字节
    不同数据的相互转换

    进制转化

    字符串的处理


    链表:

    指针数组和数组指针
    指针数组,它是数组,每个元素都是指针
    数组指针,它是指针,指向数组的指针


    */


  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/healy/p/8933199.html
Copyright © 2011-2022 走看看