C语言

#include <stdio.h>
#include <math.h>
#include<malloc.h>  
/*机器语言 01010100
汇编语言  ADD AX,BX  高级编程语言 a+b 
面向对象语言  java C++ */

/*c优点:代码量小 速度快 功能强大
缺点:危险性高 开发周期比较长  可移植性不强*/
/*c语言的应用领域:
  系统软件开发,驱动程序,数据库
  应用软件开发:wps,ps,
  嵌入式软件开发:智能手机,掌上电脑
  游戏开发:cs*/ 
/*有史以来最重要语言,一名合格黑客必须要掌握的语言
C语言最重要的是指针,学好C语言的指针就能很好理解java的引用*/


/*
1.一个字节占8位
一个汉字占2个字节 

2.基本数据类型:
整形:int 4个字节 
短整型:short int  2个字节 
长整形:long int 8个字节 
浮点型:
    单精度浮点数  float    4个字节 
    双精度浮点数  double   8个字节 
字符:char  1个字节 

3.复合基本类型
    结构体
    枚举 
*/

/*
4.变量:本质就是内存中一段存储空间 
int i;
操作系统会在内存条中找到一个空闲的存储单元与i相关联 
i=3; 把3放到存储单元里面 
3放在内存中,程序终止之后所占的空间被释放 


5.变量为什么要初始化?初始化就是赋值的意思
 内存条是硬件设备,高电平是1,低电平是0。里面存的是1/0   
 如果变量没有被初始化,会被默认添加一个数值
 当软件运行完毕,操作系统会回收该内存空间,操作系统不清空该内容空间中遗留下的数据
 
 6.如何定义变量
     数据类型 变量名=变量值
         等价于 数据类型 变量名;变量名=变量值; 
         int i=2; int i; i=2;
        int i,j;int i=3,j=5;
        
7.什么是进制
    十进制:逢10进1
    0 1 2 3 4 5 6 7 8 9
    二进制:逢2进1
    
8.
%d表示以10进制输出
%x或者%X表示以16进制输出
%o表示以8进制输出

9.十六进制:前面加0x
8进制:前面加0
科学计数法:1.235*e3=1235
123.12e-2=1.2312 

10.什么是字节
字节就是存储数据的单位,并且是硬件访问的最小单位 
1K=1024字节
1M=1024K
1G=1024M

11
ASCII码:不是一个值,规定了不同的字符用哪个整数值表示 
A 65  a 97 
B 66  b 98
C 67  c 99

12
printf("输出控制符",输出参数);
printf("%d%d",i,j) ;

13
scanf:通过键盘将数据输入到变量中
将从键盘输入的数据转化为按照输入控制符所规定格式的数据 ,然后存到以输入参数 
的值为地址的变量中。 
scanf("输入控制符",输入参数);
scanf("%d",&i);
scanf中尽量不要输入非控制输入符例如\n

14
四则运算
16/5==3被除数除数都是整数商也是整数
16/5.0==3.20000 除数是小数商也是小数

逻辑运算符 
&&左边的表达式为假右边的表达式就不执行
||左边是真右边不执行 


if默认智能控制一个语句的执行,如果要控制多个语句的执行,必须要括起来
素数 1 5 7 11 13 

15 循环:某些代码会被重复执行
for while do...while

16 强制类型转换
int i=100;
float sum=(float)i; 

17 浮点数存储带来的问题
 float 和 Double都不能保证精确的存储小数
 举例:有一个浮点型的变量x,怎样判断x的值是0
 |x-0.0000001|<=0.0000001
 
18 多层for之间的嵌套使用


19 什么叫n进制
   把2进制转化成10进制
   把10进制转化为2进制
   不同进制所代表的数值之间的关系
   
   10进制转2进制 把余数倒过来

20
++i 先+1,再参与运算
i++  先参与运算,再加一
 
21 break continue
break不能用于if
break终止最近的循环 

22 
一维数组:
为N个变量连续存储空间
所有变量的数据类型相同 
所有变量所占的字节大小相等

有关一维数组的操作:
初始化
    完全初始化
        int a[5]={1,11,12,2,3} ;
    不完全初始化,没有初始化的值为0 
        int a[5]={1,12,3};
    不初始化,所有值为垃圾直 
        int a[5]; 
    错误写法:
        int  int a[5]; 
         a[5]={1,12,3};
    把a数组中的值全部复制给b数组
    错误的写法:b=a;
    正确的写法 ;
            for(int i=0;i<5;i++){
            b[i]=a[i];
    } 
    
    scanf("%d",&a[0]); 

排序
求最大最小值
倒置 
插入
删除

二维数组
int a[3][4]可以当做3行4列看待 

23
函数

为什么需要函数

如何定义函数

函数的分类

注意的问题

24 指针
内存是8个0或者8个1 一个编号 

 
 
*/ 

            //int * p; p是变量的名字 ,(int *)表示p变量存放的是int类型变量的地址
            //int * p,不表示定义了一个名字自叫做*p的变量 。而是p是变量名,p变量的数据类型是int *类型、
            //所谓int *类型,就是存放int变量地址的类型 

            //int i=3; p=i;error p只能存放int类型变量的地址 
    
    /* p=&i;
    p保存了i的地址,因此p指向i.
    p不是i,i也不是p:修改p的值不会影响i的值,修改i的值不会影响p的值
    如果一个指针变量指向了一个普通变量,则 *指针变量就完全等同于 普通变量
        例子:
            如果p是一个指针变量。并且p存放普通变量的地i的地址
            *p 就完全等同于 i 
            *p以p的内容为地址的变量 
            或者说:在所有出现*p的地方都可以替换成i
                    在所有出现i的地方都可以替换成*p
                    
    1.指针就是地址,地址就是指针 
    2.地址就是内存单元的编号
    3.指针变量是存放地址的变量,指针变量存放指针,指针只是一个值
    4.指针变量和指针是两个不同的概念
    5.但是要注意:通常我们叙述时会把指针变量简称为指针,实际他们含义不一样 
    
    指针:
        表示一些复杂的数据结构 
        快速的传递数据
        它使函数返回一个以上的值
        能直接访问硬件
        能够方便的处理字符串
        它也是理解面向对象语言中应用的基础
        
        总结:它是c语言的灵魂 
        
        指针的定义
            地址:内存单元的编号 ,是一个从零开始的非负整数。
            
            指针:
                指针就是地址,地址就是指针
                指针变量是存放地址的变量,指针变量存放指针,指针只是一个值
                指针变量和指针是两个不同的概念
                指针的本质是操作受限的非负整数 
                但是要注意:通常我们叙述时会把指针变量简称为指针,实际他们含义不一样 
        
        指针的分类
            1.基本类型指针
            2.指针和数组
            3.指针和函数
            4.指针和结构体
            5.多级指针
            
            CPU直接处理内存条数据 
            CPU-内存:控制线、数据线、地址线 
        
        指针常见错误:
            1    int i=5;
                int *p;
                *p=i; 
            2     int i=5;
                int *p;
                int *q;
                *q=p;//不能把int *类型转换为int 类型
            3      int i=5;
                int *p; 
                int *q;
                p=&i; 
                p=q; q是垃圾值,q赋给p,p也是垃圾直 
                printf("%d",*q);
                    q空间属于本程序,本程序可以读q的内容
                    但是q内部是垃圾直,本程序不能读*q的内容
                    
        经典指针程序: 互换数字
            1 
            void huhuan(int a,int b){
                int t;
                t=a;
                a=b;
                b=t;
            }
             main(){
                int a=3;
                int b=5;
                huhuan(a,b);//只是改变形参的值,不会改变实参的值 
                }
             
            2
             void huhuan(int *p,int *q){
             p指向a的地址,*p就是a
             q指向b的地址,*q就是b 
                int t;
                t=*p;
                *p=*q;
                *q=t;
            }
             int main(void){
                int a=3;
                int b=5;
                huhuan(&a,&b);//只是改变形参的值,不会改变实参的值 
                printf("%d %d",a,b);
                return 0;
            }
            
        
        
        附注:
            *的含义
                1:乘法
                2:定义指针变量
        
        指针使函数返回一个以上的值:
             void huhuan(int *p,int *q){
                *p=1;
                *q=2;
            }
             int main(void){
                int a=3;
                int b=5;
                huhuan(&a,&b);//只是改变形参的值,不会改变实参的值 
                printf("%d %d",a,b);
                return 0;
            }    
        如何通过被调函数修改主调函普通变量的值
            1:实参必须为普通变量的地址
            2:形参必须为指针变量
            3:在被调函数中通过*形参名=。。。就可以修改主调函数相关变量的值    
            
        指针和数组:
                指针和一维数组的关系
                    数组名:第一个元素的地址
                    int a[5] a是数组名,5是数组元素个数,元素就是变量  a[0] a[1]
                    一位数组名是个指针(常量),他存放的是一维数组第一个元素的地址
                    int a[5];
                    int b[5];
                    a=b;//error a是常量
                    一位数组第一个元素的地址:&a[0] 
                        
                    
                    下标和指针的关系 
                        如果p是个指针变量,则p[i]永远等价于*(p+i)
                        
                    如果一个 函数要处理一个一维数组,则需要接受该数组的哪些信息?
                        数组名
                        数组的长度 
                     例1:
                     void f(int *prr,int len){
                        for(int i=0;i<len;i++){
                        printf("%d",*(prr+i));
                        }    
                    }
                    
                     int main(void){
                        int a[5]={1,2,3,4,5};
                        f(a,5);
                    }
                    
                    例2:
                    void f(int *prr,int len){
                        prr[3]=88;//prr[3]等价于*(prr+3) 等价于a[3]    
                    }
                    
                     int main(void){
                        int a[5]={1,2,3,4,5};
                        f(a,6);
                        a[3]=6; 
                    
                    }
        指针变量的运算:
            不能相加、不能相乘、也不能相除
            如果两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才可以相减
        
        一个指针变量到底占几个字节:
            sizeof :该数据类型占的字节数 sizeof(int)=4 
            int i=5;
            double j=4.4;
            int * p=&i;
            double * q=&j;
            sizeof(p)=sizeof(q)=4
            
            
            动态内存分配:
                传统数组的特点
                    1:数组长度必须事先制定,必须是常整数,不能是变量
                    int a[10]; ok
                    2:传统形式定义的数组,该数组的内存程序员无法手动释放 
                    数组一旦定义,系统为该数组分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放
                    3:数组的长度不能在函数运行的过程中动态地扩充或者缩小
                    4:A函数定义的数组,在A函数运行期间可以被其他函数利用 。但是在A函数运行完毕之后,不能被其他函数使用
                                      
                
                为什么要需要动态分配内存?
                    动态数组很好的解决了传统数组的4个缺陷。
                
                    malloc 是memory内存 allocate分配
                        1.要使用malloc这个函数 ,必须添加malloc.h这个头文件 
                        2.malloc只有 一个形参,并且形参是整形
                        3.malloc(4)表示请求系统为本程序分配4个字节
                        4. malloc函数只能返回第一个字节的地址 
                        5.p本身所占的内存是静态分配的,p所指向的内存是动态分配的 
                int i=5;//分配了4个字节,静态分配 
                int *p=(int *)malloc(4) ;
                free(p);//表示把p所指向的内存给释放掉,p本身的内存是静态的
                *p=5;//*p代表的就是一个int变量     
                
                
                动态内存分配举例——动态数组的构造
                    int main(){
                    int a[5];//如果int占4个字节的话,则本数组总共占20个字节。每四个字节被当做了一个int变量来使用 
                    int len;
                    int * pArr; 
                    printf("请输入你要存放的元素的个数:\n") ;
                    scanf("%d",&len);
                    pArr=(int *)malloc(len*sizeof(int)) ;
                    //pArr存放第一个字节地址,但是因为pArr是int *类型的。 
                    //所以他指向了前4个字节。parr+1指向后4个字节地址,pArr在这里就相当于数组名 
                    
                    //对以为数组进行赋值 
                    for(int i=0;i<len;i++){
                        scanf("%d",&pArr[i]);
                    } 
                    //输出 
                    for(int i=0;i<len;i++){
                        printf("%d ",pArr[i]);
                    } 
                    free(pArr);//释放掉动态分配的数组    
                    return 0;    
                    
                } 
                                 
                静态内存和动态内存的比较
                    静态内存由系统自动分配,由系统自动释放
                    静态内存是在栈分配的 
                    动态内存是由程序员手动分配,手动分配。
                     动态内存是在堆分配的 
                
    
                跨函数使用内存问题
                例:    void f(int ** q){
                        int i=5;
                        //*q等价于p 
                        //*q=i; error 因为*q=i等价于p=i,这样写是错误的
                        *q=&i; 
                    }
                    int main(){
                        int *p;
                        f(&p);//f函数已经终止了,f函数里面的静态变量 i和q不能跨函数使用 
                        printf("%d",*p);//本句语法没有问题,但是逻辑上有问题 
                    }
                
                动态内存可以跨函数使用内存
                例:    void f(int ** q){
                        //*q等价于p 
                        //*q=i; error 因为*q=i等价于p=i,这样写是错误的
                        *q=(int *)malloc(sizeof(int));//等价于p=(int *)malloc(sizeof(int)); 
                        **q=5; //*p=5等价于i=5 
                    }
                    int main(){
                        int *p;
                        f(&p);/
                        printf("%d",*p);
                    } 
                
                
                
                多级指针(保存指针变量地址的指针变量)
                int i=10;
                int * p=&i;
                int ** q=&p;
                int *** r=&q;
                 //r=&p; error 因为r是int ***类型,所以r只能放int **类型变量的地址
                 
----------------------------------------------------------------------------------------
            结构体:
                             
                 struct Student{
                    int age;
                    float score;
                    char sex;
            };
            int main(){
                struct Student st={80,66.6,'f'}; 
            }
            为什么需要结构体?
                为了表示一些复杂的事物,普通的基本类型无法实现
            什么叫结构体?
                把一些基本数据类型组合在一起形成的一个新的数据类型
            如何定义一个结构体?
                推荐:这只是定义了一个新的数据类型,没有定义变量 
                struct Student{
                    int age;
                    float score;
                    char sex;
                };    
            怎么使用结构体变量?
                赋值和初始化
                    struct Student st={80,66.6,'f'}; //初始化 定义的同时赋值
                    struct Student st2;
                    st2.age=10;
                    st2.score=88;
                    st2.sex='f';
                如何取出结构体变量中的每一个成员
                    结构体变量名.成员名
                    指针变量名->成员名  //在计算机内部会被转化成(*指针变量名).成员名 的方式来指向 
                        struct Student st={80,66.6,'f'};
                         struct Student *pst=&st;
                        printf("%d",pst->age) ;
                        pst->age在计算机内部会被转化成(*pst).age 也等价于st.age
                        我们之所以知道pst->age等价于st.age,是因为pst->age被转化成了(*pst).age 执行 
                    pst->age的含义:
                        pst所指向的结构体变量中age的这个成员 
                结构体变量的运算
                    结构体变量不能进行加减乘除操作,但是可以相互赋值 
                结构体变量和结构体指针作为参数传递的问题:推荐使用结构体指针变量作为参数传递 
                例:不能修改st的地址 
                    struct Student{
                            int age;//
                            !!!!!!!!!!
                            age占4个字节,一个字节8位,8位一个编号(地址),一个字节一个地址,地址只用首字节地址表示
                            (int *p 表示) 
                            float score;
                            char name[100]; 
                            };    
                     void InputStudent(struct Student * ps){//指针变量无论他指向的数据类型占几个字节,ps本身只占4个字节 
                         ps->age=10;
                         ps->score=44.4; 
                         strcpy(ps->name,"张三");//不能写成stu.name 
                     } 
                
                     int main(void){
                         struct Student st;
                         InputStudent(&st);
                         outStudent(st);//对结构体输出可以发送st的地址,也可以发送st的内容 
                        printf("%d %f %s\n",st.age,st.score,st.name) ;
                        return 0; 
                    }     
                冒泡排序:
                void sort(int *a,int len){
                    int i,j,t;//如果有i个数字,总共需要比i-1轮,然后每轮里面两个两个比 
                    for(int i=0;i<len-1;i++){//整体比较 
                        for(int j=0;j<len-1-i;j++){
                            if(a[j]>a[j+1]){
                                t=a[j];
                                a[j]=a[j+1];
                                a[j+1]=t;
                            }    
                        }    
                    } 
                }    
                    
                int main(void){
                    int array[6]={3,5,2,17,9,4};
                    sort(array,6);
                    for(int i=0;i<6;i++){
                    printf("%d ",array[i]);
                    }
                return 0;    
                }          
                
               动态构造存放学生信息的结构体数组,然后按照分数排序输出
                   struct Student{
                    char name[100];
                    int age;
                    float score;
                };
                
                int main(){
                    int len;
                    printf("请输入学生个数:\n");
                    scanf("%d",&len);
                    struct Student t;
                    // 动态给学生分配几个内存 
                    struct Student *pst;
                    pst=(struct Student *)malloc(len*sizeof(struct Student));
                    
                    //输入 
                    for(int i=0;i<len;i++){
                        printf("请输入第%d个学生信息:\n",i+1) ;
                        printf("age=");
                        scanf("%d",&pst[i].age);
                        printf("name=");
                        scanf("%s",pst[i].name);//name是数组名,本身就是数组首元素的地址,不能改成取地址
                        printf("score=");
                        scanf("%f",&pst[i].score);
                    }
                    
                    for(int i=0;i<len-1;i++){//整体比较 
                                for(int j=0;j<len-1-i;j++){
                                    if(pst[j].score>pst[j+1].score){
                                        t=pst[j];
                                        pst[j]=pst[j+1];
                                        pst[j+1]=t;
                                    }    
                                }    
                            } 
                    printf("=============学生的信息===========\n");
                    //输出 
                    for(int i=0;i<len;i++){
                        printf("第%d个学生信息是\n",i+1) ;
                        printf("age=%d\n",pst[i].age);
                        printf("name=%s\n",pst[i].name);
                        printf("score=%f\n",pst[i].score);
                    
                    }
                        
                    return 0;    
                } 
        
               枚举:
                       把一个事物所有可能的取值一一列举出来 
                       enum WeekDay{
                        Monday,Friday,Sundy
                    };    
                        
                    int main(void){
                        enum WeekDay day=Monday;
                        printf("%d",Sundy);//2
                        
                    return 0;    
                    } 
                进制转换
                (32)5=3*5+2*1=(17)10;
                 
                链表 
                    算法:
                        通俗的定义:
                            解题的方法和步骤 
                        狭义定义:
                            对存储数据的操作 
                        广义定义:
                            广义的算法也叫泛型
                            无论数据是如何存储的,对该数据的操作都是一样的
                        我们至少可以通过两个结构来存储数据
                            数组
                                优点:存取速度快
                                缺点:插入和删除速度慢 
                            链表 
                                特点:插入删除快,查询慢
                                专业术语
                                    头结点
                                        头结点的数据类型和首节点的类型是一模一样的
                                        头结点是首节前面的那个节点
                                        头结点并不存放有效数据
                                        设置头结点的目的是为了方便对链表的操作 
                                    头指针
                                        存放头结点地址的指针 
                                    首节点
                                        存放第一个有效数据的节点 
                                    尾结点
                                        存放最后一个有效数据的节点
                                        指针域为空 
                            确定一个链表需要一个参数:头指针                     
                    */ 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值