精华内容
下载资源
问答
  • TURBO C语言编译调试链接三者的顺序和关系是什么,一般来说软件开发先执行哪个步骤?
  • C语言代码编写除了代码编辑、编译运行,还有什么步骤,3个步骤的顺序是什么 C语言代码编写除了代码编辑、编译运行,还有什么步骤,3个步骤的顺序是什么
  • 1.为什么两段不相干的代码会互相影响 在主程序里有一段点亮发光二极管的代码,和一段计数器计数并在...按照书上的方法先段选再位选,但是点亮的数码管本来不应该点亮的,段选和位选顺序换了之后就能正常显示了
  • 本程序在语法没有任何问题,但是根据C语言编译语句自上而下 和 内存就地分配原则。详解:本程序在开始运行时, 内存依照就地分配原则就地割划内存空间为堆栈 运行本程序,请注意:被割划出来的内存空间仍然保存...
    不知道,为什么会出现这样的结果?

    答:此问题从二个方面解答:
    1> 编译器是上古三大神器的编译器之一,不带有任何只能辅助系统。
    2>本程序在语法没有任何问题,但是根据C语言编译语句自上而下 和  内存就地分配原则。
    详解:本程序在开始运行时,  内存依照就地分配原则就地割划内存空间为堆栈 运行本程序,请注意:被割划出来的内存空间仍然保存上次程序运行所产生的数值。  定义变量a,b,sum时,这个三个变量在堆栈里是有数值滴(即内存本身存储滴的无用数值),压数值入a,b后,变量a,b所在的内存数值变化//请注意此时的变量sum所在的内存里数值没有变化,还是无用数值// 输出a,b后,变量sum的数值没有变化// 因为运行程序是自上而下,所以sum=a+b是没有被运行滴// 故输出sum的值为  割划内存空间成堆栈时内存保留的垃圾值!


    #include <stdio.h>
    int main (void)
    {
     int a,b,sum;
     printf("请输入要进行运算的数值:\n");
     scanf("%d%d",&a,&b);
     printf("a=%d b=%d",a,b);
     sum=a+b;
     printf("sum = %d\n",sum);
     return 0;
    }

    
    
    展开全文
  • 什么是对齐,以及为什么要对齐: 现代计算机中内存空间都按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况在访问特定变量的时候经常在特定的内存地址访问,这就需要各...
    什么是对齐,以及为什么要对齐:   
    现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。   
    对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。   
    对齐的实现   
    通常,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择时候目标平台的对齐策略。当然,我们也可以通知给编译器传递预编译指令而改变对指定数据的对齐方法。   
    但是,正因为我们一般不需要关心这个问题,所以因为编辑器对数据存放做了对齐,而我们不了解的话,常常会对一些问题感到迷惑。最常见的就是struct数据结构的sizeof结果,出乎意料。为此,我们需要对对齐算法所了解。


    对齐的算法:   

    由于各个平台和编译器的不同,现以本人使用的gcc   version   3.2.2编译器(32位x86平台)为例子,来讨论编译器对struct数据结构中的各成员如何进行对齐的。   
    设结构体如下定义:   
    struct     A   
    {   
    int   a;   
    char   b;   
    short   c;   
    };   
    结构体A中包含了4字节长度的int一个,1字节长度的char一个和2字节长度的short型数据一个。所以A用到的空间应该是7字节。但是因为编译器要对数据成员在空间上进行对齐。所以使用sizeof(strcut   A)值为8。   
    现在把该结构体调整成员变量的顺序。   
    struct   B   
    {   
    char   b;   
    int   a;   
    short   c;   
    };   
    这时候同样是总共7个字节的变量,但是sizeof(struct   B)的值却是12。   
    下面我们使用预编译指令#progma   pack   (value)来告诉编译器,使用我们指定的对齐值来取代缺省的。   
    #progma   pack   (2)   /*指定按2字节对齐*/   
    struct   C   
    {   
    char   b;   
    int   a;   
    short   c;   
    };   
    #progma   pack   ()   /*取消指定对齐,恢复缺省对齐*/   
    sizeof(struct   C)值是8。   


    修改对齐值为1:   
    #progma   pack   (1)   /*指定按1字节对齐*/   
    struct   D   
    {   
    char   b;   
    int   a;   
    short   c;   
    };   
    #progma   pack   ()   /*取消指定对齐,恢复缺省对齐*/   
    sizeof(struct   D)值为7。   


    对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。 
    这里面有四个概念值:   
    1.数据类型自身的对齐值:就是上面交代的基本数据类型的自身对齐值。   
    2.指定对齐值:#progma   pack   (value)时的指定对齐值value。   
    3.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。   
    4.数据成员、结构体和类的有效对齐值::自身对齐值和指定对齐值中小的那个值。   
    有了这些值,我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的 "存放起始地址%N=0 ".而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍,结合下面例子理解)。这样就不能理解上面的几个例子的值了。   
    例子分析:   
    分析例子B;   
    struct   B   
    {   
    char   b;   
    int   a;   
    short   c;   
    };   
    假设B从地址空间0x0000开始排放。该例子中没有定义指定对齐值,在笔者环境下,该值默认为4。第一个成员变量b的自身对齐值是1,比指定或者默认指定对齐值4小,所以其有效对齐值为1,所以其存放地址0x0000符合0x0000%1=0.第二个成员变量a,其自身对齐值为4,所以有效对齐值也为4,所以只能存放在起始地址为0x0004到0x0007这四个连续的字节空间中,复核0x0004%4=0,   且紧靠第一个变量。第三个变量c,自身对齐值为2,所以有效对齐值也是2,可以存放在0x0008到0x0009这两个字节空间中,符合0x0008%2=0。所以从0x0000到0x0009存放的都是B内容。再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b)所以就是4,所以结构体的有效对齐值也是4。根据结构体圆整的要求,0x0009到0x0000=10字节,(10+2)%4=0。所以0x0000A到0x000B也为结构体B所占用。故B从0x0000到0x000B共有12个字节,sizeof(struct   B)=12;   


    同理,分析上面例子C:   
    #progma   pack   (2)   /*指定按2字节对齐*/   
    struct   C   
    {   
    char   b;   
    int   a;   
    short   c;   
    };   
    #progma   pack   ()   /*取消指定对齐,恢复缺省对齐*/   
    第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1=0;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续字节中,符合0x0002%2=0。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放在0x0006、0x0007中,符合0x0006%2=0。所以从0x0000到0x00007共八字节存放的是C的变量。又C的自身对齐值为4,所以C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct   C)=8. 
    展开全文
  • 在网上查了很多关于顺序表的资料,但是都差强人意,由于本人对C语言掌握的还可以,所以一下程序全部使用C语言进行编写, 使用编译工具Dev C++,文件.c文件 有什么相关细节问题可以留言区留言,感谢你的观看. #...

    C语言 数据结构 相关 顺序表 函数
    在网上查了很多关于顺序表的资料,但是都差强人意,大部分都是由C++编写,且编写顺序和函数都不够详细
    由于本人对C语言掌握的还可以,所以一下程序全部使用C语言进行编写, 使用编译工具是Dev C++,文件是.c文件

    有什么相关细节问题可以留言区留言,感谢你的观看.

    #include "stdio.h"
    #include "stdlib.h"
    #include "malloc.h"
    
    #define NewLine printf("\n") 
    #define MAX_SIZE 50
    
    //所有返回-1都是错误 
    
    typedef struct{
        int data[MAX_SIZE];
        int length;
    }List;
    
    List *CreateList(void);  //开辟空间 
    void ListDisplay(List *L);  //显示顺序表 
    int ListInsert(List *L, int k, int e);  //在位置k 插入e 
    int ListDel(List *L, int k, int *e); //在位置k 删除数值保存到e 
    int ListFind_e(List *L, int e);  //找元素e的位置 
    int ListDel_Min_From_FinElem(List *L);  //删除最小值,将值返回,将最后一个元素替换到原来位置 
    int ListReverse(List *L);   //反置 
    void Swap(int *a, int *b); //交换两个数值 
    int ListDel_All_e(List *L, int e); //删除所有与e 
    int ListDel_FromSToT(List *L, int s, int t);  //删除给定的位置范围的所有值; 
    int ListDel_s_t(List *L, int s, int t);  //删除顺序表中顺序给定值s,t之间的数据 (s<t) 
    int ListDel_s_t_disorder(List *L, int s, int t); //删除顺序表中乱序的在st之间的所有值 
    int ListDel_Repeat(List *L);        // 删除有序 顺序表中重复数据 
    List* ListMerge(List *L1, List *L2);  //链接两个顺序表,返回链接好的顺序表 
    
    
    int main()
    {
        int i,e;
        int a[20]={1,2,3,4,4,5,5,5,5,5,6,6,7,8,9,10,11,12,15,15};    
        List *L, *L2;
    
    
        L = CreateList();  //开始创建 
        L2 = CreateList();  //创建第二个顺序表 
    
        for(i=0; i<20; i++)  //赋值 
        {
            L->data[i] = i;
            L->length++;
        }
        ListDisplay(L); 
    
        printf("\n在第2位置插入66");
        ListInsert(L,2,66);  //在第2位置插入66 
        ListDisplay(L);
    
        printf("\n删除第二个位置\n");
        ListDel(L,2,&e);    //第二个位置删除,删除的数据保存到e中
        printf("del = %d ",e); 
        ListDisplay(L); 
    
        printf("\n数据6存在的是位置%d\n\n",ListFind_e(L,6)); //显示数据位置
    
        printf("已删除最小数据%d,且有最后一位数据做填补",ListDel_Min_From_FinElem(L));
        ListDisplay(L);
    
        printf("\n 转置所有数据 "); 
        ListReverse(L); //顺序表转置 
        ListDisplay(L);
        ListReverse(L); //顺序表转置 
        ListDisplay(L);
    
        printf("\n 删除所有5数据 "); 
        ListDel_All_e(L,5);  //删除所有5
        ListDisplay(L);
    
        printf("\n 删除位置5到8的值 "); 
        ListDel_FromSToT(L,5,8);
        ListDisplay(L);
    
        printf("\n 删除10,14 之间的数据 ");    
        ListDel_s_t(L,10,14); 
        ListDisplay(L);
    
    
        printf("\n 删除(3 <= x <= 11)之间的数据 ");    
        ListDel_s_t_disorder(L,3,11);
        ListDisplay(L);  
    
        //重新赋值
        printf("\n新赋值\n"); 
        L->length=0; 
        for(i=0; i<20; i++)   
        {
            L->data[i] = a[i];
            L->length++;
        } 
        ListDisplay(L); 
    
        printf("\n删除重复数据 "); 
        ListDel_Repeat(L);
        ListDisplay(L); 
    
        //给第二个顺序表赋值
        printf("\n第二个顺序表赋值"); 
        for(i=0; i<20; i++)   
        {
            L2->data[i] = i;
            L2->length++;
        } 
        ListDisplay(L2);    
    
    
        printf("\n链接两个顺序表 ");   
        L2 = ListMerge(L2,L); 
        ListDisplay(L2);
    
    
    
        printf("\n Hello word!!\n");
        return 0;
    }
    
    
    /*创*/ 
    List *CreateList(void)
    {
        List *L;
        L = malloc(sizeof(List));  //申请空间
        L->length = 0;  //长度从1开始 
        return L;   //返回指针地址 
    }
    
    /* 显示顺序表 */
    void ListDisplay(List *L)
    {
        int i;
        NewLine;
        for(i=0;  i < L->length;  i++)   {printf("%d, ",L->data[i]);}
        NewLine; 
    } 
    
    /* 在L中第k位插入e */
    int ListInsert(List *L, int k, int e)
    {
        int j;
        if(L->length >= MAX_SIZE)
        {
            printf("FULL\n");return;
        }
        if((k<1) || (k > (L->length+1)))  return -1;//超出范围 
        for(j=L->length; j>=k; j--)
        {
            L->data[j] = L->data[j-1];  //向前移位
        }
        L->data[k-1] = e;
        L->length++;
        return 1; 
    }
    
    /* 删除L中第k个位置,并删除的数据保存到e中 */ 
    int ListDel(List *L, int k, int *e)
    {
        int i;
        if((k<1) || (k > (L->length)))  return -1;//超出范围 
        *e=L->data[k-1];
        for(i=k; i<L->length; i++)
        {
            L->data[i-1]=L->data[i];
        }
        L->length--;
        return 1;
    } 
    
    /* 在L中查找数值e 在第几个位置 */
    int ListFind_e(List *L, int e)
    {
        int i=0;
        while( (e != L->data[i]) && (i != L->length-1) )
        {
            i++;
        }
        if(i>=L->length) return -1;
        return i+1; 
    } 
    
    /* 
    王道 数据结构 P18.1 
    从顺序表中删除具有最小值的元素,假设唯一,
    并由函数返回被删除的值, 且被删除的位置由最后
    一个元素填补,顺序表为空则显示出错信息 */
    
    int ListDel_Min_From_FinElem(List *L)
    {
        int del;
        int i=1,pos=0;
        if (L->length==0) 
        {
            printf("NULL!\n");
            return -1;
        }
        del=L->data[0];
        for(i=1; i<L->length; i++)
        {
            if(del > L->data[i]) 
            {
                del=L->data[i];
                pos=i;
            }
        }
        L->data[pos] = L->data[ L->length ];
        L->length--;
        return del; 
    } 
    
    /* 
    空间复杂度为O(1) 将顺序表中的数据逆置 
    
    分析: 将前后两半对换,只需要找到一个中间变量,或者使用逻辑运算进行转换 
    
    */
    
    int ListReverse(List *L)
    {
        int i;
        if(L->length == 0)
        {
            printf("NULL!\n");return -1;
        }
        for(i=0; i<L->length/2; i++) //1 2 3 4 5 6
        {
            L->data[i] = L->data[i] ^ L->data[L->length-1-i]; 
            L->data[L->length-1-i] = L->data[i] ^ L->data[L->length-1-i]; 
            L->data[i] = L->data[i] ^ L->data[L->length-1-i]; 
        } 
        return 1;
    } 
    
    /* 实现不使用中间变量,交换两个参数的数值 */
    void Swap(int *a, int *b)
    {
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    
    //  *a = *a + *b;
    //  *b = *a - *b;
    //  *a = *a - *b;
    //  
    //  *a = *a * *b;
    //  *b = *a / *b;
    //  *a = *a / *b;
    }
    
    /*
    编写时间复杂度O(n) 空间复杂度O(1)
    将顺序表中的所有元素e删除 
    */ 
    int ListDel_All_e(List *L, int e)
    {
        int i,timer=0;
        for(i=0; i<L->length; i++)
        {
            if(L->data[i] != e)
            {
                L->data[timer] = L->data[i]; 
                timer++;
            }
        }
        L->length = timer;
        return i;   
    }
    
    /*
    删除给定的位置s,t之间的所有值,包含s&t 
    如果s,t不合理,或者顺序表为空,打印错误 
    */
    int ListDel_FromSToT(List *L, int s, int t)
    {
        int i; 
        if(L->length == 0)
        {
            printf("NULL!\n");
            return -1;
        }
        if(s<1 || s > L->length || t<1 || t>L->length || s>=t)
        {
            printf("/n input ERROR!\n");
            return -1;
        }
    
        for(t; t<L->length; t++) //3,5 
        {
            L->data[s-1] = L->data[t-1];
            s++;
        }   
        L->length -= (t-s+1);   
    } 
    
    /* 
    删除有序顺序表中 数据全部s 到 t范围内的数据(包括数据s&t)  
    如 1 2 3 4 5 6 7 8 9 10 删除2 - 4 
    如果s,t不合理,或者顺序表为空,打印错误 
    */ 
    int ListDel_s_t(List *L, int s, int t)
    {
        int i=0,j=0; 
        if(L->length == 0)
        {
            printf("NULL!\n");
            return -1;
        }
        if(s >= t)
        {
            printf("/n input ERROR!\n");
            return -1;
        }
        while((L->data[i] != s)  && (i < L->length) )  //寻找第一个等于s的值 
        {
            i++;
        }
        j=i; 
        while ( ((L->data[j]) <= t)  && (j < L->length) )  //寻找第一个小于t的值 
        {
            j++;
        } 
        for(j; j<L->length; j++)
        {
            L->data[i] = L->data[j];
            i++;        
        }
        L->length = i++;  //当j==L->length for循环并没有执行,所以需要加1 
        return 1;   
    } 
    
    /*
    删除顺序表中所有在s t之间的所有数据,包括s,t 
    */ 
    int ListDel_s_t_disorder(List *L, int s, int t)
    { 
        int i,timer;
        if(L->length == 0)
        {
            printf("NULL!\n");
            return -1;
        }
        if(s >= t)
        {
            printf("/n input ERROR!\n");
            return -1;
        }   
        timer=0;
        for(i=0; i<L->length; i++)
        {
            if(L->data[i] <s || L->data[i] >t)
            {
                L->data[timer] = L->data[i];
                timer++;
            }
        }
        L->length = timer;
        return 1;   
    } 
    
    /*
    删除 有序 顺序表中重复data,
    
    */
    int ListDel_Repeat(List *L)
    {
        int i=0,next;
        if(L->length == 0)
        {
            printf("NULL!\n");
            return -1;
        }
    
        for(next=1; next < L->length; next++)
        {
            if( L->data[i] != L->data[next]  ) 
            {
                L->data[++i] = L->data[next];
            }   
        } 
        L->length = i + 1;  
        return 1; 
    }
    
    /*
    将两个有序顺序表合成一个有序顺序表 
    返回顺序表 
    
    先比较两个表的最小值,然后放到一个位
    在用这个值分别比较两个表的下一个值,哪个值更接近这个值,就是第二个 
    */
    List* ListMerge(List *L1, List *L2)
    {
        List *L;
        int i,j,k;
    
        if(L1->length + L2->length > MAX_SIZE)
        {
            printf("FULL!\n");return -1; 
        }
    
        i=j=k=0;
    
        while(i<L1->length && j<L2->length) 
        {
            if(L1->data[i] <= L2->data[j])
            {
                L->data[k] = L1->data[i]; 
                i++;
            } else
            {
                L->data[k] = L2->data[j]; 
                j++;
            }
            k++;        
        } 
    
        printf("\n   000 %d\n",L1->length); 
        if(i == L1->length) //L1已耗尽,向L中加剩余的j 
        { 
            while( j<L2->length ) 
            {
                L->data[k] = L2->data[j]; 
                k++; 
                j++;
            }       
        }else if(j == L2->length) //L2 已耗尽 
        {
            while( i<L1->length ) 
            {
                L->data[k] = L1->data[i]; 
                k++; 
                i++;
            }               
        }
        L->length = k;
        return L;
    }
    
    
    
    展开全文
  • C语言c语言基础知识梳理(超全)

    千次阅读 多人点赞 2020-04-08 18:27:10
    写此篇博客的目的主要为了梳理一下c语言基础知识,因为不会像学c语言那样有很多例子,或者按照初学c语言顺序,所以不推荐刚学习c语言的人阅读。 本篇文章有什么: 对c语言系统的梳理 对一些使用的细节...



    零、概述


    写此篇博客的目的主要是为了梳理一下c语言基础知识,因为不会像c语言教程那样有很多例子,或者按照初学c语言的顺序,所以不推荐刚学习c语言的人阅读。(期末复习可以看看)

    本篇文章有什么:

    1. 对c语言系统的梳理
    2. 对一些使用的细节进行梳理
    3. 解答对使用c语言时产生的一些疑惑
    4. 本篇内容基于“C语言程序设计-浙江大学-翁恺”、“C++ Primer”部分内容以及个人理解进行梳理,不充分之处欢迎指出


    一、变量和基本类型


    (一)基本类型

    1、有符号常见类型大小及其范围

    1byte(字节)=8bit(位);每个bit就是一个0或者1,byte是c语言里面数据的最小单位

    常用2的次方:
    27=128
    28=256
    215=32,768
    216=65,536
    231=2,147,483,648‬
    232=4,294,967,296
    263=9,223,372,036,854,775,808‬
    264=18,446,744,073,709,551,616

    类型 含义 32位编译器中大小(一般) 64位编译器中大小(一般) 最小值(32位) 最大值(32位)
    bool(stdbool.h) 布尔类型 1byte 1byte false true
    char 单个字符 1byte 1byte -27 27-1
    short 短整形 2byte 2byte -215 215-1
    int 整形 4byte 4byte -231 231-1
    long 长整形 4byte 8byte -231 231-1
    long long 长整形 8byte 8byte -263 263-1
    float 单精度浮点数 4byte 4byte -2127 2128
    double 双精度浮点数 8byte 8byte -21023 21024
    long double 扩展精度浮点数 12byte 16byte -216383 216384
    char* 字符常量或字符串常量 4byte 8byte 无意义 无意义

    2、浮点数范围来由及其有效数字

    这里单独讨论一下浮点数的取值范围,浮点数都遵循IEEE754标准,所以:
    4*8=32位的float的第1位是符号位,第2~9位有8位是指数位,第10~32位有23位是尾数位

    那么可以很容易看到float的范围是[-1*2127≈1.7*1038, 1*2128≈3.4*1038]

    因为转换成IEEE754都要进行标准化,也就是将原来的整数点整数的形式转化成二进制点二进制的形式,然后将点的位置移动到左边第一个1(2)之后,产生指数位。规定点之后的数填在尾数位上,所以31位前暗含了1(2),所以上面的范围会先乘个1。
    32位的指数位 = 移位数(左移一位+1,右移一位-1)+ 127得出。所以负数只有127(127-127=0),而正数有128(127+128=255)


    8*8=64位的double的第1位是符号位,第2~12位有11位是指数位,第13~64位有52位是尾数位
    那么可以很容易看到float的范围是[-1*21023≈8.988*10307, 1*21024≈1.797693*10308]

    12*8=96或16*8=128位的long double的第1位是符号位,第2~16位有15位是指数位,在32位系统中第17~96位有80位是尾数位,在64位系统中第17~128位有112位是尾数位,那么范围是[-1*216383≈5.9*104931, 1*216384≈1.1897*104932](与尾数大小无关)。

    其实float的范围就已经非常非常大了,那为什么还会有double甚至long double呢,这是因为浮点数能准确记录量级,但是无法准确记录太长的数字,数字的有效位数值取决于尾数位的长度,我们可以总结成下表:

    类型 有效位数计算 有效位数
    float 223+1=16,777,216 8-1=7
    double 252+1=9,007,199,254,740,992‬ 16-1=15
    long double 280+1=2.4*10 24 / 2112+1=1.038*1034 25-1=24 / 35-1=34

    3、字面值常量

    (1)十进制字面值

    对于一个20(10)=24(8)=14(16),在c语言中对应表达为24(10进制)、024(8进制)、0x14(16进制)。
    默认情况下,十进制字面值的类型是int,如果int装不下就是long,再装不下就是long long。

    (2)浮点数字面值

    对于一个浮点数可以表示为314.159(10)也可以表示为3.14159e+2(科学记数法)。
    默认情况下,浮点数字面值是一个double

    (3)指定字面值类型

    整形字面值
    后缀最小匹配类型例子
    u / Uunsigned20u / 20U
    l / Llong20l / 20L
    ll / LLlong long20ll / 20LL
    浮点形字面值
    f / Ffloat20.0f / 20.0F
    l / Llong double20.0l / 20.0L

    4、字符和字符串常量

    形如’a’"HelloWorld"都可以看作是常量,特别说明当例如char* s1="HelloWorld";char* s2="HelloWorld";时,s1和s2所指的都是内存中代码段的常量,可读不可写且地址相同,类似于const char* s1;

    字符是以单引号括住的单个字符,只占一个char(一个byte)
    字符串以双引号"括住一系列字符,最后隐含了’\0’,所以占n+1个char(n为字符串有意义的长度)

    特殊的常量:无穷,每个编译器的表示都不一样,可以使用如下代码输出:

    printf("%f\n", 1/0.0);  // 无穷大。我的电脑上为:1.#INF00
    printf("%f\n", -1/0.0);  // 无穷小。我的电脑上为:1.#INF00
    printf("%f\n", 0.0/0.0);  // 空。我的电脑上为:-1.#IND00
    

    5、总结

    有符号的类型(除浮点数)的范围都是由[-2n-1, 2n-1-1](n为类型所占bit)
    无符号的类型(除浮点数)的范围都是由[0, 2n-1](n为类型所占bit)
    浮点数的范围与其指数位大小有关,为[-2{[2^(m-1)]-1}, 2[2^(m-1)]](m为指数位位数)


    (二)变量

    1、定义变量

    变量由一个类型声明符一个或多个变量名组成的列表(c99及以后可以在函数内任意位置定义变量),例如:

    int a;  // a是int类型的变量
    double b=1.0;  //b是double类型的变量,赋1.0为初值
    char c, d;  // c, d是char类型的变量
    

    2、常用特殊前缀

    extern int a;  // 声明一个int类型的变量a,一般用在.h文件中声明项目全局变量
    const int b=1;  // 定义一个不可变的变量b,使用const关键字都要赋初值
    static int c=1;  // 在函数中使用,只在第一次使用时初始化,相当于作用域在函数内的全局变量
    typedef long long int;  // 把long long当作int使用
    

    3、数组与初始化变量

    int a=1;  // 给a初始化为1
    // 以下为C99加入的特性
    int b[10] = {1};  // 第一个元素初始化为1,其他9个元素初始化为0
    int c[10] = {0};  // 全部初始化为0,常用初始化手段
    int d[10] = {[1]=1, 2, [4]=4};  // 0 1 2 0 4 0 0 0 0 0
    

    4、变量作用域

    变量有两种类型:局部变量全局变量,变量作用域即变量可使用的范围。

    对于局部变量可以简单理解为大括号{}内即为一个作用域,变量在哪个大括号内,作用域就在哪。

    对于全局变量的作用域就是在当前的.c文件中,在.h文件声明后可以在整个项目内使用。

    对于同名变量,小作用域的变量会在其作用域中覆盖大作用域的变量。

    (1)局部变量与全局变量的差别

    差别因素 局部变量 全局变量
    初始值 初始值取决于内存里的数(随机) 一般为0,指针为null
    作用域 仅限于大括号内 .c文件甚至项目


    (三)字符串

    字符串在c语言中有两种形式char*和char[],这里简单分辨下两者之间的不同。
    char* c1="HelloWorld!"中,c1指向代码段中的常量,只读不写,且常量相同,指向的地址也相同。
    char c2[]="HelloWorld!"中,c2指向堆栈段中的数据,可读可写,相当于把代码端的数据拷贝了出来。


    (四) 自定类型——结构体

    结构体可以看作是一种个基础类型复合的类型。

    // 声明如下:
    struct DATE{
    	int year, month, day;
    };
    
    // 几种定义方式如下:
    struct DATE date1;  // 不赋初值
    struct DATE date2={2020, 4, 5};  // 根据结构体中的顺序赋初值,这里是年月日
    struct DATE date3 = {.year=2020, .day=5};  // 给单独变量赋初值
    struct DATE *date4 = &date3;  // 用指针取date3地址(指针后面会单独说)
    
    // 几种赋值方式如下:
    date3 = (struct DATE){.year=1999};  // 将数据强制转换成struct DATE类型赋值
    date3 = date2;  // 自动赋值
    date3.year=2010;  // 对变量中单一元素赋值
    date4->year=2010;  // 对指针所指变量中的单一元素赋值
    
    // 常用声明
    typedef struct DATE2{
    	int year, month, day;
    } D;
    D date5;  // 这样就可以不用写struct DATE2这么一长串,取而代之用D来表示
    

    扩展:union
    union作为关键字与struct类似,但是struct中每个成员都是单独的内存,而union只占最大成员变量的大小,通常用与二进制与十进制的转换。

    union DATE{
        int year;
        int month;
        int day;
    };  /* 一个union DATE只有一个int大小 */
    

    扩展:enum枚举,枚举类似#define,但是有体系些(c语言的枚举不好用)

    // 声明枚举, 默认下标RED:0, YELLOW:1, GREEN:2
    enum COLOR1 {RED1, YELLOW1, GREEN1};
    // 自定下标
    enum COLOR2 {RED2=1, YELLOW2, GREEN2=5};
    



    二、表达式


    这里给出运算符优先级

    优先级运算符名称或含义使用形式结合方向说明
    1[]数组下标数组名[整型表达式]左到右
    ()圆括号(表达式)/函数名(形参表)
    .成员选择(对象)对象.成员名
    ->成员选择(指针)对象指针->成员
    2-负号运算符-算术类型表达式右到左单目运算符
    (type)强制类型转换(纯量数据类型)纯量表达式
    ++自增运算符++纯量类型可修改左值表达式单目运算符
    --自减运算符--纯量类型可修改左值表达式单目运算符
    *取值运算符*指针类型表达式单目运算符
    &取地址运算符&表达式单目运算符
    !逻辑非运算符!纯量类型表达式单目运算符
    ~按位取反运算符~整型表达式单目运算符
    sizeof长度运算符sizeof 表达式 / sizeof(类型)
    3/ 表达式/表达式 左到右双目运算符
    *表达式*表达式双目运算符
    %余数(取模)整型表达式%整型表达式双目运算符
    4+表达式+表达式左到右双目运算符
    -表达式-表达式双目运算符
    5<<左移整型表达式<<整型表达式左到右双目运算符
    >>右移整型表达式>>整型表达式双目运算符
    6>大于表达式>表达式左到右双目运算符
    >=大于等于表达式>=表达式双目运算符
    <小于表达式<表达式双目运算符
    <=小于等于表达式<=表达式双目运算符
    7==等于表达式==表达式左到右双目运算符
    !=不等于表达式!= 表达式双目运算符
    8&按位与整型表达式&整型表达式左到右双目运算符
    9^按位异或整型表达式^整型表达式左到右双目运算符
    10|按位或整型表达式|整型表达式左到右双目运算符
    11&&逻辑与表达式&&表达式左到右双目运算符
    12||逻辑或表达式||表达式左到右双目运算符
    13?:条件运算符表达式1? 表达式2: 表达式3右到左三目运算符
    14=赋值运算符可修改左值表达式=表达式右到左
    /=除后赋值可修改左值表达式/=表达式
    *=乘后赋值可修改左值表达式*=表达式
    %=取模后赋值可修改左值表达式%=表达式
    +=加后赋值可修改左值表达式+=表达式
    -=减后赋值可修改左值表达式-=表达式
    <<=左移后赋值可修改左值表达式<<=表达式
    >>=右移后赋值可修改左值表达式>>=表达式
    &=按位与后赋值可修改左值表达式&=表达式
    ^=按位异或后赋值可修改左值表达式^=表达式
    |=按位或后赋值可修改左值表达式|=表达式
    15,逗号运算符表达式,表达式,…左到右从左向右顺序结合
    总结优先度: 特殊运算符(括号、地址类) > 单目运算符 > 算数运算符(乘除>加减) > (移位运算) > 判断运算符(比较>相等) > (位运算) > 逻辑运算符(&&>||) > 三目运算符 > 赋值运算符 > 逗号运算符

    针对十进制字面值
    <<:左移数据,相当于乘2(右边填0)
    >>:右移数据,相当于除2(unsigned左填0,signed左边填原来的最高位(因为负数移位还要是负数))



    三、语句


    简单语句;,只有一个分号的空语句。
    复合语句:由{}大括号嵌套起来的语句,空块(括号里什么都没用)等于空语句。

    (一)条件语句

    1、if语句

    if语句一般格式:if…else if…else(翻译为如果…否则如果…否则)

    if (age>18) {  // 如果年龄大于18岁
    } else if(age<18) {  // 如果年龄小于18岁
    } else {  // 上面的都不满足
    }
    

    可用搭配:
    if...
    if...else if...
    if...eles...
    if...else if...else if...else...

    tips:
    (1)if依据后面的条件语句的结果进行判断,非0为真,0为假
    (2)else不需要接条件
    (3)if语句后面不要接;

    2、switch语句

    switch语句一般格式:

    switch(ch){  // switch是传入整数并判断整数进行判断
    	case 'a':
    		...
    		break;
    	case 'b':
    		...
    		break;
    	default:
    		...
    }
    

    tips:
    (1)case只是入口,所以每个case都要用break;跳出
    (2)default类型if语句中的else,即上面的case都不满足时进入
    (3)switch只能传入整数进行判断,上面的例子就是将char类型的ch转换成了ASCII码进行比较
    (4)switch后面不要接;


    (二)迭代语句

    1、while语句

    while语句的一般格式:

    while(条件){
    	语句
    }
    

    tips:
    (1)while适用于不知道次数的循环
    (2)while后面不要接;

    2、do while语句

    do while语句的一般格式:

    do{
    	语句
    }while(条件);
    

    tips:
    (1)do while适用于不知道次数且要先做一遍的循环
    (2)do while后面要接;
    (3)do while后面要接;
    (4)do while后面要接;

    3、for语句

    for语句的一般格式:

    for (初始化变量; 条件; 变量操作) {
    	语句
    }
    
    int n=10;  // 定义循环次数
    // 例子1,循环n次
    for (int i=0; i<n; i++) {
    	;
    }
    等价于
    int i=0;
    while(i<n){
    	;  // 语句
    	i++;
    }
    
    // 例子2,多参数
    for (int i=0, j=10; i<n; i++, j--) {
    	;
    }
    等价于
    int i=0, j=10;
    while(i<n){
    	;  // 语句
    	i++;
    	j--;
    }
    

    tips:
    (1)for适用于知道次数的循环
    (2)for后面不要接;
    (3)for可以压缩行数,简化部分使用while的情况


    (三)跳转语句

    break;直接跳出当前条件语句或迭代语句,能且只能 跳出 当前一个 语句。

    continue;条件语句 中表示什么都不做(替代空语句);在 迭代语句 中表示 直接进入下一轮循环,不执行完当前循环

    goto;跳转到指定位置(该位置必须有声明),例子:

    start:  // goto声明
    	...  // 语句
    	...  // 语句
    	...  // 语句
    	goto start;  //跳转到start声明位置
    

    !!!注意,goto仅推荐用于跳出多重循环,例如:

    for (int i=0; i<n; i++) {
    	for (int j=0; j<m; j++) {
    		for (int k=0; k<o; k++) {
    			if (跳出条件) {
    				goto end;
    			}
    		}
    	}
    }
    end:
    



    四、函数


    (一)函数一般格式

    返回值类型 函数名(形参列表) {
    	...语句...
    	return 返回值;
    }
    // 例子,main函数
    int main(){
    	return 0;
    }
    

    tips:
    (1)特殊的返回值类型void(什么都不返回),此时return 返回值;写为return;
    (2)形参列表为空时,表明不需要传入函数。


    (二)函数声明

    函数声明一般写在程序开头。尽管部分c语言编译器没有要求在调用函数时,就要知道函数格式。但是让编译器提前知道格式,就可以在编译时进行检查,防止我们错误使用了函数。

    有一函数定义如下:

    int f(int a){
    	return a;
    }
    

    那么函数的声明可以写成:

    int f(int a);
    或者
    int f(int);
    

    特殊的对于返回值和参数都是void的函数,声明可以写成:

    void f(void);
    


    (三)结构体中的函数

    如果能在结构体中写函数,那么结构体就更接近一个类了,例子如下:

    struct SHOWDATE{
    	void (*show)(int year, int month, int day);
    };
    
    static void show(int year, int month, int day){
    	printf("%d-%d-%d", year, month, day);
    }
    
    static SHOWDATE showDate={.show=show};
    
    int main(){
    	showDate.show(2020, 1, 1);
    	return 0;
    }
    



    五、指针


    (一)定义

    int a=10;
    int *p=&a;  // (1)(2)
    *p = 12;  // (3)
    int * const p1;  // (4)
    const int * p2;  // (5)
    int const * p3;
    

    (1)*代表这是一个指针类型。具体到例子中就一个int*类型,代表p存放一个指向int类型的地址

    (2)&代表取地址。在例子中就是取int类型变量的地址,即变量a的地址

    (3)*p代表一个变量,这个变量就是p所指地址里面的变量

    (4)int * const p1;不能修改p里的地址

    (5)const int * p2;int const * p3;不能修改p里地址对应的值


    (二)结构体与指针

    typedef strcut stDATE{
    	int year, month, day;
    } DATE;
    
    int main(){
    	DATE date1={2020, 1, 1};
    	DATE* date2=&date1;
    	date1.year=2019;
    	date2->month=2;
    	printf("%d-%d-%d", date1.year, date1.month, date1.day);
    	
    	return 0;
    }
    

    (1)结构体变量访问结构体成员使用.,结构体指针变量访问结构体成员使用->


    (三)数组与指针

    int a[10] = {0}  // (1)、(2)
    
    int *p = a;  // (3)
    
    void *q = (void*)p;  // (4)
    
    int *new = (int*)malloc(10*sizeof(int));  // (5)
    free(new);
    

    (1)int a[10]里面的a实际上是数组第一个变量的地址,所以可以int *p = a;
    (2)*(p+n)a[n]等价。
    (3)int*指针变量加上一个数n,代表指针变量的数值加上n*32(int的bit)得到偏移。
    (4)q表示未定的类型(类似char*但不一样)。
    (5)使用int*指针变量来创建数组,使用完要free(程序关闭会自动释放,如果程序长时间使用则会造成内存泄露)。

    其他:
    char c[][]错误;
    char c[][10]正确且限制大小;
    char *c[]正确,c[n]是一个char*的字符或字符串
    char **c正确,一个指向指针的指针



    六、文件读取


    (一)文本文件

    函数定义:

    FILE* fopen(const char* restrict path, const char* restrict mode);  // 打开文件。参数:路径,模式
    int fclose(FILE* stream);  // 关闭文件
    fscanf(FILE*, ...);  // 文件读取(类似scanf,只是加了第一个参数,具体在八)
    fprintf(FILE*, ...);  // 文件输出(类似printf,只是加了第一个参数,具体在八)
    

    fopen的mode选项:
    r:只读
    r+:读写,从文件头开始
    w:只写,清空或新建
    w+:读写,清空或新建
    a:追加,追加或新建
    …x:只新建,若存在则不能打开(wx、ax等)

    例子:

    FILE* p=fopen("file", "r");
    if(fp) {
    	...
    	fclose(fp);
    }
    


    (二)二进制文件

    函数定义(打开文件和关闭文件与文本文件一致):

    // ptr:读入字符串存放的变量、size*nmemb:读多少字符、stream:文件句柄
    size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
    size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
    

    二进制文件读写主要是读写结构体,现在不常用,因为可移植性不好,不如读写文件



    七、编译预处理指令与.h文件


    (一)编译预处理指令

    在c语言中,所有#开头的语句都是编译预处理指令。
    c语言编译经过
    .c——处理编译预处理指令——》
    .i——c编译器编译成汇编文件——》
    .s——生成目标代码文件——》
    .o——生成可执行文件——》
    #.out / .exe
    四步得到可执行文件,第一步就是处理编译预处理指令。

    1、# include < stdio.h >

    # include <stdio.h>就是将stdio.h文件里面的内容复制到代码里面去

    2、#define 名称 操作(宏定义)

    # define被称为宏定义,格式为# define 名称 操作
    例子:

    #define PI 3.14159
    #define cube(x) (x*x*x)
    
    int main(){
    	cube(3);
    	return 0;
    }
    

    可以用宏定义定义一个变量PI或一个方法cube

    宏定义定义方法看起来很方便,但十分不推荐初学者使用,因为宏定义的方法是没有类型的,而且运算顺序也不好理解(看上面 二、表达式 15个运算等级的表,就知道多复杂了)。

    如果确实想用类似宏定义的方式来定义函数,可以使用下面的方法。

    3、(补充)inline内联函数

    inline char *dbtest(int a)
    {
        return (a % 2 > 0 ? "奇" : "偶");
    }
    


    (二).h文件

    .h文件主要用来声明对应.c文件里面的变量或函数,把.c文件里面的声明放到.h文件就可以了(全局变量需要加上extern前缀)。

    导入标准库时推荐使用<>,如# include <stdio.h>
    导入自定声明时推荐使用"",如# include "train.h"


    (三)一些常用宏

    printf("%d", __LINE__);  // 输出当前语句行号
    printf("%s", __FILE__);  // 输出当前文件名
    printf("%s", __DATE__);  // 输出编译日期
    printf("%s", __TIME__);  // 输出编译时间
    printf("%d", __STDC__);  // 当要求程序严格遵循ANSIC标准时该标识符被赋值为1
    printf("%s", __FUNC__);  // 输出当前函数名
    



    八、常用函数


    (一)常用函数

    size_t = unsigned int

    库名 函数定义 解释
    默认 size_t sizeof(type_name) 返回byte
    string.h size_t strlen(const char *s) 返回s的字符串长度(不包括最后的\0)
    string.h int strcmp(const char *s1, const char *s2) 比较两个字符串,返回0:相等; 1:s1>s2; -1:s1<s2
    string.h int strncmp(const char *s1, const char *s2, size_t n) 安全版本比较前n个字符的大小,其他同上
    string.h char* strcpy(char *restrict dst, const char *restrict src) 把src的字符串拷贝到dst,restrict表示不重叠
    string.h char* strncpy(char *restrict dst, const char *restrict src, size_t n) 安全版本,拷贝n个字符,其他同上
    string.h char* strcat(char *restrict s1, const char *restrict s2) 把s2拷贝到s1后面,s1要足够大
    string.h char* strncat(char *restrict s1, const char *restrict s2, size_t n) 安全版本,追加n个字符,其他同上
    string.h char* strchr(const char *s, int c) 在s串中找到c第一次出现的位置,返回指针,没有为null
    string.h char* strrchr(const char *s, int c) 在s串中从右边找到c第一次出现的位置,返回指针,没有为nulltring.h
    string.h char* strstr(const char *s1, const char *s2) 在字符串s1中不忽略大小写寻找字符串s2
    string.h char* strcasestr(const char *s1, const char *s2) 在字符串s1中忽略大小写寻找字符串s2
    string.h void *memset(void *s, int c, unsigned long n) 将指针变量s所指向的前n字节的内存单元用一个“整数”c替换
    string.h void *memcpy(void *dest, const void *src, size_t n) 从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。
    stdlib.h system(“pause”) 暂停程序,按任意键继续


    (二)scanf和printf

    scanf(stdio.h)函数声明:int scanf(const char *format, …)
    format格式:%[flag]type

    printf(stdio.h)函数声明:int printf(const char *format, …)
    format格式:%[flags][width][.prec][hlL]type

    flag 含义
    - 跟width一起用,左对齐(%-9d)
    + 正数强制输出正号(%+9d) 可以%±9d/%-+9d
    正常输出
    0 数字前填充0(%09d) 不可以%-09d(因为负号已经是左对齐了)

    width / prec 含义
    number 最小字符数
    .number 小数点后位数。%9.2f:一共9位,小数点后2位(正数部分7位)
    * 将number放到后面作为参数使用(%*d, number, int)
    .* 将.number放到后面作为参数使用(%.*d, .number, int)

    hlL 含义
    hh 单个字节(char 1byte)
    h short(2byte)
    l long(4byte)
    ll long long(8byte)
    L long double(16byte)

    type 用于 含义
    i / d int 接受整数值并将它表示为有符号的十进制整数,i是老式写法
    u unsigned int 无符号10进制整数
    o unsigned int 无符号8进制整数(不输出前缀0)
    x / X unsigned int 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF(不输出前缀0x)
    f / F / lf double 单精度浮点数和双精度浮点数用f(lf 在C99开始加入标准,意思和 f 相同)
    e / E double 科学计数法表示的数,此处"e"的大小写代表在输出时用的“e”的大小写
    g / G double 有效位数,如:%.8g表示单精度浮点数保留8位有效数字。
    c char 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
    s / char * / wchar_t * 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符
    p 指针(void *) 以16进制形式输出指针
    n 读入/写出的个数(int *) 到此字符之前为止,一共输出的字符个数,不输出文本
    % 不进行转换,输出字符‘%’(百分号)本身
    m 打印errno值对应的出错内容,(例: printf("%m\n"); )
    展开全文
  • 感觉我的代码没什么问题,编译也正常通过,但是每次运行都会出现这样的问题,不知道是什么原因,希望又高手能帮忙解答下,谢了 ![CSDN移动问答][1] #include<stdio.h> #include void chu(int a); void ...
  • C语言预习

    2018-01-30 21:27:54
    1、什么是栈? 栈一种只能在一端进行插入或者删除操作的线性表(说明栈还是线性表结构,只是操作受限而已)。其中允许进行插入或者删除操作的一端称为栈顶。栈的插入和删除一般叫入栈和出栈。栈的顺序存储结构...
  • 上面的邻接矩阵代码用的也结构体变量,为什么又可以执行,因为邻接表图的结构体中有指针吗,但是以下代码 ``` #include struct MyStruct{ int a; int *b; MyStruct *c; }; int main(){ ...
  • C语言编程要点

    2017-09-18 00:10:37
    1.14 取模运算符(modulus operator)“%”的作用是什么? 17 第2章 变量和数据存储 18 2.1. 变量存储在内存(memory)中的什么地方? 18 2.2. 变量必须初始化吗? 19 2.3. 什么是页抖动(pagethrashing)? 19 2.4. 什么是...
  • C语言讲义.doc

    2018-01-27 10:41:43
    1.10 C语言编译过程,GCC参数简介 16 1.10.1 C语言编译过程 16 1.10.2 -E预编译 16 1.10.3 -S汇编 16 1.10.4 -c编译 16 1.10.5 链接 16 1.11 操作系统结构 17 1.11.1 用户模式 17 1.11.2 内核模式 17 1.12 64位,32位...
  • 什么是流程控制 流程控制的分类 顺序执行 选择执行 循环执行 数组 为什么需要数组 数组的分类 函数 为什么需要函数 什么叫函数 如何定义函数 函数的分类 函数的声明 指针 指针的重要性 指针的定义 指针的...
  • 多维数组的各个下标必须单独出现在一对方括号内,在什么条件下,下列这些代码段可以通过编译而不会产生任何警告信息。 int array[10][20]; ... i = array[3,4]; 咋一看array[3,4] 不合法,实际上这合法的,因为...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    虽然C语言最普遍的一种高级语言,但不同的MCU厂家其C语言编译系统有所差别的,特别在一些特殊功能模块的操作上。如果对这些特性不了解,那调试起来就有的烦了,到头来可能还不如用汇编来的快。 5. 在教学中...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    6.3 那么,在C语言中“指针和数组等价”到底是什么意思? 6.4 既然它们这么不同,那为什么作为函数形参的数组和指针声明可以互换呢? 数组不能被赋值 6.5 为什么不能这样向数组赋值?externchar*getpass();...
  • c语言深度剖析

    2012-08-18 18:59:34
    c语言 深度 剖析 解开程序员面试笔试的秘密 第一章关键字..................................................................................................................................9 1.1,最宽恒...
  • C语言深度揭秘

    2012-04-12 13:21:16
    1.7.3,case语句的排列顺序.................................25 1.7.4,使用case语句的其他注意事项................27 1.8,do、while、for关键字......................................... 28 1.8.1,break与 ...
  • C语言深度解剖(c语言进阶的好教程) 目 录 第一章 关键字................................................................................................................................... 9 1.1,最宽...
  • Chapter 1 顺序结构1、编译器编译是按文件为单位的,第一次编译所有的文件,之后改动哪个文件就编译哪个文件,木有改动过的文件则不再次编译,这样做可以提高效率2、C语言中尽量不要使用goto语句,除非万不得已不要...
  • C语言深度解剖

    2012-08-09 19:43:35
    1.7.3,case 语句的排列顺序...........................................................................................25 1.7.4,使用 case 语句的其他注意事项...............................................
  • o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 ...
  • 一 1、算法,一个问题可以有多个算法。...为什么要定义数据类型:一是编译系统根据数据类型在内存中分配相应的字节数,二数据类型决定了数据类参与的运算类型。 3.2 double int全写[signed] i...
  • 就是因为printf函数对输出表中各量求值的顺序是自右至左进行 的。在式中,先对最后一项“-i--”求值,结果为-8,然后i自减1后为7。 再对“-i++”项求值得-7,然后i自增1后为8。再对“i--”项求值得8,然后i再自减1后...
  • 10月15号C语言感悟

    2019-10-16 21:37:57
    一、 1、程序 面向程序的语言 2、运行C的步骤 编辑 (.c)-编译 (.obj)-连接(.exe) 二 1、算法,一个问题可以有多个算法,算法的特点 ...为什么要定义数据类型:一是编译系统根据数据类型在内存中分配******...
  • 3.20 “semantics of‘’change in ANSI C”的警告是什么意思? 3.21 “无符号保护”和“值保护”规则的区别在哪里? 第4章 指针 基本的指针应用 4.1 指针到底有什么好处? 4.2 我想声明一个指针并为它分配一些空间...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 289
精华内容 115
关键字:

c语言编译顺序是什么

c语言 订阅