• C Basic


    // java数据类型 和长度int  4个字节 double  8个字节  float 4个字节 long 8个字节 
    // short 2个字节 boolean  1个字节 char 2个字节 byte   1个字节 
    // char, int, float, double, signed, unsigned, long, short and void
    // c语言中 数据类型比java少一些 在c语言中没有 boolean类型的数据  int 1 代表真 0 代表假
    // c 语言中没有String类型的数据   java中表示一个字符串 String  , c语言中表示字符串 通过char类型的数组来表示字符串
    // c 语言没有byte类型   所有用char的类型表示byte类型 
    
    #include <stdio.h>    
    #include <stdlib.h>
    // sizeof(); c语言的一个函数 可以把 某种数据类型的长度获取出来 int 
     main() 
    {          // %d 类似sql语句的? 占位符  
                printf("char的长度为%d
    ", sizeof(char));
                printf("int的长度为%d
    ", sizeof(int));
                printf("float的长度为%d
    ", sizeof(float));
                printf("double的长度为%d
    ", sizeof(double));
                printf("long的长度为%d
    ", sizeof(long));
                printf("short的长度为%d
    ", sizeof(short));
                
                //signed, unsigned, 数据类型的修饰符
               // signed int ; 代表的是有符号的int的数据 
               // unsigned int ;  无符号的int数据 
                  printf("signed int的长度为%d
    ", sizeof( signed int));
                  printf("unsigned int的长度为%d
    ", sizeof( unsigned int));
            
               // 符号的修饰符 只能修饰 整数类型的数据 long int 
               // 不能修饰 浮点型的数据 float double  
               // printf("signed float的长度为%d
    ", sizeof( signed float));
            
                  system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
    }
    
     
    /*%d  -  int
    %ld – long int
    %c  - char
    %f -  float
    %lf – double
    %x – 十六进制输出 int 或者long int 或者short int
    %o -  八进制输出
    %s – 字符串
    
    Int len;
    Scanf(“%d”,&len);*/
    #include <stdio.h>    // java  import xxx.xx.pack    引用函数的声明  
    #include <stdlib.h>
     main() // 程序的入口函数  
    {    int i = 3;
         float f = 3.1415;
         double d = 6.2815;
         char c = 'A';   //通过单引号定义字符 
         short s = 2;   
           
         printf("int i=%d
    ",i);
         printf("float f=%f
    ",f);
         printf("char c=%c
    ",c);
         printf("double d=%lf
    ",d);
         printf("short s=%d
    ",s);
         
         /*char arr[20] ; //定义一个长度为20的数组
         scanf("%s",arr);  // 从键盘接受一个字符串,放在c数组里面 
         
         printf("s =%s
    ",arr); 
           */
           
         int j ;
         scanf("%d", &j);//&代表的是取地址  
         printf("j=%d
    ",j); 
            
         system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {       
            // 所有的变量都会分配一块内存空间
            
            // 指针就是用来表示一块内存空间的地址的  
            
            // 地址可以用过 &这个符号获取到某个变量的在内存中的地址 
            
            // 这个地址如果想把他存放起来 就需要有一个变量 去存放这个地址
            
            //  存放内存地址的变量 就是指针变量  
            
            
            // 指针和指针变量 
            // 指针是用来表示一块内存地址的,
            // 指针变量是用来存放一个内存地址的 .
            
            //  
            printf("ready go! 剩余时间60秒
    ");
             
             int time = 60;
             printf("time变量对应的内存地址为%#X
    ", &time); 
             
              for(;time>0;time--){
                            
                      
                          
                     printf("剩余时间%d
    ",time); 
                    
                    
                     sleep(4000);     
          }                 
           printf("游戏结束");
         
            system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {    
          //指针是什么?   指针就是一个地址
          //地址代表的就是一块内存空间  
         
          int i =5;// 定义一个int 类型的变量i 值 =5 
            printf("i的地址 %#X
    ",&i); 
          
          //获取i的地址
          // &i; 
          //定义一个指针变量
          int* p ; // 指针变量 定义一个int* 类型的变量p  
          //int *p, int * p;
          
          
          p = &i;  // 就是把i的指针赋给指针变量p  ,现在指针变量p里面存放的内容(数据)  就是i的地址  
         
         
          printf("p里面的内容为(i的地址) %#X
    ",p); 
         
          //*号 操作符
          // *号的几种含义  
          //1 . *号放在某种数据类型的后面,代表就是这种数据类型的指针  int*   float* 
          //2 . *号 代表一个乘法符号  3*5  = 15;
          //3 .  *号放在一个指针变量的前面 -> 代表取这个指针变量所存放的地址里面对应的数据  
           printf("i=%d
    ",i);
           printf("*p的值%d
    ",*p); 
         
           // 改变p的值 会不会影响i的值? 
            //p = NULL;
           // printf("i=%d
    ",i);
           
           // 改变i的值 会不会影响p的值? 
           // i = 100;
           //  printf("p里面的内容为(i的地址) %#X
    ",p); 
           // 通过上述实验 p和 i 是两个不同的变量 ,改变i的值 不会影响 p的值,同理,更改p的值 也不会影响i的值  
           
           // 更改*p的值 会不会影响i的值  
          // *p  = 88;
           // printf("i=%d
    ",i);
           
           // 更改i的值 会不会影响 *p的值呢?
          // i = 99;
          // printf("*p的值%d
    ",*p);  
            
            //*p 和i 其实代表的是同一个变量,代表是同一块内存空间  
            
           
           system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {   
          /*    int* p; //定义一个指针变量   垃圾值 -> 野指针  
              
               //printf("*p=%d
    ",*p); 
              *p = 1231; 
              // 立刻蓝品 
              // 
              指针变量如果没有赋值就不能使用  
              */ 
             /* int d = 324233;
             char* c; ;  // 编译错误  不符合的指针类型  
             
             c = &d;
             printf("*p = %c
    ",*c); 
             类型不相同的指针不可以互相转换 
             */
              system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
    f(int** q){
        int i = 3; 
        printf("子函数 i的地址 %#X
    ",&i); 
        // *q   代表的就是p变量  
        *q = &i; 
    } 
    /**
       使用指针的时候 不可以访问已经被系统回收掉的数据  
       子函数执行完毕后 子函数里面所有的局部变量都会别系统回收  
    */
    
     main() 
    {  
            
            
            
            // 希望在主函数里面去使用子函数里面的变量 i 
            
            // f(); 
            
            // 希望在主函数里面得到子函数 里面int i变量的地址 
            
            int* p ; //存放子函数f中 int i的地址的一个变量
            
             
            f(&p); 
             
           // printf("主函数 i的地址 %#X
    ",p); 
            
           // printf("i的值为 %d
    ",*p); 
            
           system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
     // public List<Person> getPersons() {}; 
     // public byte[] getbytes(){};
     
     /*
     如果让子函数 更改主函数里面的数据  
     如何让子函数 返回一个以上的值 
     1.子函数的形参 为 主函数中要修改的变量的地址 
     2. 调用子函数的时候 把要修改的变量的地址 传递给子函数 
     3. 在子函数里面 修改这个地址里面存放的变量的内容 
     4. 主函数使用这个变量的时候 里面的值就发生了变化  
      
     */
     
     int f(int* p, int* q){
        *p =  33;
        *q = 55;
         
     }
    
    
     main() 
    {   
        
        int i = 3;
        int j = 5;
        f(&i,&j);
        printf("i=%d
    ",i);
        printf("j=%d
    ",j);
        
        
        
        
                  system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {  
        char arr[20] ={'h','e','l','l','o',''};    
        
        // 利用char类型指针 方便的表示一个字符串  
        char* arr1= "hello world";
            
        printf("%s",arr1);    
            
        system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
    // 数组是一块连续的内存空间  数组名 就是内存空间的首地址 
    // 数组名[i]  ==  *(数组名+i); 
     main() 
    {  
                /* char[] arr = new char[20]; 
                 char arr[] ; 
                 */
                 // 创建一个长度为5的int类型的数组  
                int arr[5] ={1,2,3,4,5};
                
                printf("a[0]=%d
    ",arr[0]);
                 
            
                printf("a[4]=%d
    ",arr[4]);
            
                 // 逻辑上是错误的代码  数组下标越界  
                // printf("a[5]=%d
    ",arr[5]);
                // windows xp   缓冲区越界补丁  
                
                
                // arr是一个什么东西呢?
                printf("arr = %#X
    ",arr); 
                
                // 打印 数组的第一个元素的地址 
                printf("arr[0]地址 = %#X
    ",&arr[0]); 
                
                // 打印数组中的第二个元素 
                printf("arr[1]=%d
    ",arr[1]); 
                printf("arr[1]=%d
    ", *(arr+1));
                //问题: arr[i]  *(arr+i)  代表的是同一个变量么? 
                // 代表的是同一块内存空间 指向的是同一个变量  
                
                
                //通过实验 : 数组名表示的 就是这个数组第一个元素 的首地址 
            
                   system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
    #define pi 3.1415 
    // 写一个子函数 打印数组里面的每一个元素 
    
    void printArr(int* arr, int len){ // arr是数组的首地址  len数组的长度  
         int i=0;
         for(;i<len;i++){ // 在c99 的语法格式下  for循环的初始化条件 不能写在 for 循环的括号里面  
            // printf("arr[%d]=%d
    ",i,arr[i]);  // arr[i] 和  *(arr+i) 代表的含义相同 
            printf("arr[%d]=%d
    ",i, *(arr+i));
         }
    } 
    
     
    main() 
    {  
           // int arr[10]={1,2,3,4,5};
            
           // printArr(&arr[0],10);
            //1 .定义一个数组  缺陷 数组的长度 必须事先申请好 
            //int arr[1000];   //  这一句代码一旦执行 ,就立刻会在内存里面申请 5个内存空间 每个内存空间的大小可以存放一个int类型的数据  
            // 没有办法动态的增加这一块空间的大小, 也没办法减小这一块内存空间  
            //2. 循环赋值
            //3. 打印数组里面的内容 
            int* arr = (int* )malloc(sizeof(int)*10); 
            
            arr =  realloc(arr,sizeof(int)*8); //空间的长度为12了 
            int i =0;
            for(;i<5;i++){
               printf("请输入arr[%d]=的值
    ",i);
               scanf("%d",arr+i);                            
            }
            
            printArr(arr,5);
            
            system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
         
         
             // 作业: 从键盘接受一个数组 数组的大小 
           
             // 动态的更改 数组的大小增加2 
                
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {  
            int i =3;  //天津的某个路上 盖了一个房子 3 
            int j =5;  // 北京的某个路上 盖了一个方法 5 
            int* p = &i; // p 天津的门牌号 
            int* q = &j; // q 北京的门牌号 
            
           
            // 指针的运算和数组都是紧密关联的 
            char arr[5]={'a','b','c','d','e'};  //一块连续的内存空间 
            
            char* p1 = &arr[2];
            printf("char = %c
    ", *(p1-1));
            
            // char 内存中占用 1个字节 
            // int 内存 中占用 4个字节  
            
             int intarr[5]={1,2,3,4,5};  //一块连续的内存空间 
            
            int* q1 = &intarr[2];
            printf("char = %d
    ", *(q1-1));
            
            
            
            // 指针的运算 按照 约定好的数据类型   偏移相对应的内存空间的大小  
            
            system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
        
    }
    #include <stdio.h>    
    #include <stdlib.h>
     main() 
    {  
            int i =3;
            double d = 3.141692;
            float f = 3.1423;
            char c ='B';
            
            int*  ip = &i;
            double* dp = &d;
            float* fp = &f;
            char* cp = &c;
             
            
            printf("int 类型指针变量的长度为 %d
    ",sizeof(ip)); 
            printf("double 类型指针变量的长度为 %d
    ",sizeof(dp)); 
            printf("float 类型指针变量的长度为 %d
    ",sizeof(fp));        
            printf("char 类型指针变量的长度为 %d
    ",sizeof(cp));        
            
            
            
            // 在32位的操作系统上 因为程序 最大能使用的内存空间的地址 就是2的32次方
            // 指针只需要4位 就可以表示出来所有的内存空间 
            
            // 64 并且编译支持64位 8位 
            
             system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
        
    }

    动态内存和静态内存的比较

    静态内存是系统是程序编译执行后系统自动分配,由系统自动释放,静态内存是栈分配的.动态内存是堆分配的.

    (1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

    (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

    (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多.

      堆和栈的区别:

    1.申请方式

    栈:   

    由系统自动分配.例如,声明一个局部变量int  b; 系统自动在栈中为b开辟空间.例如当在调用涵数时,需要保存的变量,最明显的是在递归调用时,要系统自动分配一个栈的空间,后进先出的,而后又由系统释放这个空间. 

    堆:   

    需要程序员自己申请,并指明大小,在c中用malloc函数   

    如char*  p1  =  (char  *)malloc(10);   

    但是注意p1本身是在栈中的.

      2  申请后系统的响应   

     栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。   

    堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,    会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。   

    3.申请大小的限制   

    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(vc编译选项中可以设置,其实就是一个STACK参数,缺省2M),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。   

    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。   

     4.申请效率的比较:   

    栈:由系统自动分配,速度较快。但程序员是无法控制的。   

    堆:由malloc/new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.   

     5.堆和栈中的存储内容   

    栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。   

    当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。   

    堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。   

    6.内存的回收

    栈上分配的内存,编译器会自动收回;堆上分配的内存,要通过free来显式地收回,否则会造成内存泄漏。

      堆和栈的区别可以用如下的比喻来看出:   

    使用栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。   

    使用堆就像是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

    /*1.定义int (*pf)(int x, int y);
    2.赋值 pf = add;
    3.引用 pf(3,5);
    */
    #include <stdio.h>    
    #include <stdlib.h>
    
    int add(int x , int y){
        
        return x+y;
        
    }
    
     main() 
    { 
          
           int (*pf) (int x, int y); //定义一个函数的指针的声明 名字叫pf  返回值 int 接受参数两个int  
           pf = add; 
           
           printf("result=%d
    ", pf(3,6)); 
          
           system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h>    
    #include <stdlib.h>
    
    struct Student
    {
        int age; //4
        float score; // 4/
        long id;  //4
        char sex ; //2   vc 6.0 14
    };
     main() 
    { 
        struct Student st={80,55.6f,100010 ,'F'};   
        
        struct Student* pst;
        pst = &st;
          
        printf("age = %d
    ",st.age);    
        printf("score = %f
    ",st.score);     
        printf("id = %ld
    ",st.id);    
         printf("sex = %c
    ",st.sex);    
        // 结构体的长度 
        printf("长度 = %d
    ",sizeof(st)); 
        
        //printf("age = %d
    ", (*pst).age);   
        printf("age = %d
    ", pst->age); 
        
        system("pause");    // 调用windows下系统的命令 让程序暂停执行  方便观察程序的执行结果  
              
              
    }
    #include <stdio.h> 
    
    
    
    main( )
     { 
    
    struct date { int year, month, day; } today; 
     
     // 联合体 是定义一块相同的内存空间 存放里面的数据  
    union { long i; int k; char ii; } mix; 
    
    // 联合体的作用就是用来表示一组数据类型 数据的数据类型为这一组中的某一种数据类型 
    //注意 :   联合体里面的数据内容会相互覆盖 
    
    printf("date:%d
    ",sizeof(struct date));  //12 
    
    printf("mix:%d
    ",sizeof(mix));  
    mix.ii = 'A';
    printf("k=%d
    ",mix.k);
    system("pause");
    } 
    #include <stdio.h>
    typedef int haha;
    enum WeekDay
    {
    Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
    };
    
    // c  
    //  
    int main(void)
    {
        
      haha i = 3; 
      printf("%d
    ",i);
      //int day;
      enum WeekDay day = Sunday;
      printf("%d
    ",day);
      system("pause");
      return 0;
    }
  • 相关阅读:
    像Google Play一样让DrawerLayout拉出的抽屉在透明系统状态栏和工具栏(ToolBar)之间。
    WebView中实现延迟加载,图片点击时才加载。
    MediaPlayer配合SurfaceView或TextureView做视频播放器时的截图方法。
    解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
    使用SAE的Storage来为Android应用提供版本更新的检查和下载功能
    使用SAE的服务来实现android端的用户反馈功能。
    使用IntentService给自己的Android应用写一个文件下载器。
    禁止进入Activity时NumberPicker自动弹出输入法。
    使用Android系统提供的DownloadManager来下载文件。
    Android异步下载图片的类和缓存图片到SD卡的类。
  • 原文地址:https://www.cnblogs.com/exmyth/p/4944271.html
Copyright © 2020-2023  润新知