每周一记之初学c/c++(1)

时间:2021-04-27 16:33:47
本周主要学习c/c++基础语法,练习c语言经典算法100题。
2015.4.26——2015.5.2

## c语言基础 ##

c语言记得先申明在使用;变量也尽量都赋予初值(否则可能引起莫名错误)。
变量或者函数可以多处声明但是只能在一处定义。
一、程序处理过程
1.预处理
预处理是C语言程序从源代码变成可执行程序的第一步,主要是C语言编译器对各种预处理命令进行处理,包括头文件的包含、宏定义的扩展、条件编译的选择等。
预处理:
#include <> 在库函数文件中寻找
#include “” 在先在自己的debug文件下寻找再到库文件中寻找
#define N 5 //替换

2.编译
编译之前,C语言编译器会进行词法分析、语法分析(-fsyntax-only),接着会把源代码翻译成中间语言,即汇编语言。如果想看到这个中间结果,可以用-S选项。
编译程序工作时,先分析,后综合,从而得到目标程序。

3.汇编
把作为中间结果的汇编代码翻译成了机器代码,即目标代码,不过它还不可以运行。如果要产生这一中间结果,可用gcc的-c选项,当然,也可通过as命令汇编汇编语言源文件来产生。
4.链接
链接是处理可重定位文件,把它们的各种符号引用和符号定义转换为可执行文件中的合适信息(一般是虚拟内存地址)的过程。链接又分为静态链接和动态链接,前者是程序开发阶段程序员用ld(gcc实际上在后台调用了ld)静态链接器手动链接的过程,而动态链接则是程序运行期间系统调用动态链接器(ld-linux.so)自动链接的过程。

二、程序存放方式
1.栈 - 由编译器自动分配释放
2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
4.另外还有一个专门放常量的地方。- 程序结束释放

int a = 0; //全局初始化区
char *p1; //全局未初始化区
void main()
{
    int b; //栈
    char s[] = "abc"; //栈
    char *p2; //栈
    char *p3 = "123456"; //123456{post.content}在常量区,p3在栈上,并且p[1]='a'会报错内存写入错误,不能修改。
    static int c = 0; //全局(静态)初始化区
    p1 = (char *)malloc(10); //分配得来得10字节的区域在堆区
    p2 = (char *)malloc(20); //分配得来得20字节的区域在堆区
    strcpy(p1, "123456");
    //123456{post.content}放在常量区,编译器可能会将它与p3所指向的"123456"优化成一块
}
## c语言经典算法100题及课后作业 ##
int gcd(int a,int b){//辗转相除法求最大公因子
    int t;
    if(a<b){
        t=a;
        a=b;
        b=t;
    }
    if(b==0)
        return a;
    else
        return gcd(b,a%b);
}
int main(){//十进制转其他进制
    unsigned int ival=0;
    int arr[32]={0};
    int base=10;
    int index=0;
    while(scanf("%d%d",&ival,&base)!=EOF){

        memset(arr,0,sizeof(arr));//习惯赋初值
        index=31;

        while(ival){
            arr[index]="0123456789abcdefghijklmnopqrstuvwxyz"[ival%base];
            index--;
//          arr[index--]=ival%2;
            ival=ival/base;
        }

        for(index++;index<32;index++){
            printf("%c",arr[index]);
        }

        printf("\n");

    }

    system("pause");
    return 0;

}
int main(){//其他进制转十进制
    int i=0,j=0,ival=0,res=0,index=0;
    int base=0.0;
    char arr[32]={0};

    for(i=0;i<32;i++){
        arr[i]=pow(2.0,i);
    }

    while((scanf("%d %s",&base,arr))!=EOF){
        j=0;
        res=0;
        index=strlen(arr);

        for(i=index-1;i>=0;i--){
            if('0'<=arr[i]&&arr[i]<='9')
                arr[i]-='0';
            else if('a'<=arr[i]&&arr[i]<='z')
                arr[i]-=('a'-10);

            res+=arr[i]*pow(base*1.0,j++);
        }

        memset(arr,0,sizeof(arr));

        printf("res:%d\n",res);
    }
}
int findOutTwo(int *a,int n,int &x,int &y){//出现2次的数位偶数出现1次的数有2个,找出他们利用亦或的性质
    assert(a);
    assert(n>2);
    int result=a[0];

    for(int i=1;i<n;++i)
        result^=a[i];

    int b=result&(-result);
    x=0;
    y=0;
    for(int i=0;i<n;++i)
    {
        if(b&a[i])
            x^=a[i];
        else
            y^=a[i];
    }
    return 0;
}
int fun(int year,int mon,int day){//计算两个日期相差的天数,选定某填为基准完成计算
    int i,n=0,dif_y=0;
    int a[12];
    a[1]=a[3]=a[5]=a[7]=a[8]=a[10]=31;
    a[4]=a[6]=a[9]=a[11]=30;
    a[0]=0;
    a[2]=28;
    for(i=0;i<mon;i++){
        n+=a[i];
    }
    n+=day;
    printf("n=%d\n",n);

    if(year>=1970){
        dif_y=year-1970;
        for(i=1;i<=dif_y;i++){
            if((year%4==0&&year%100!=0)||year%400==0)
                n++;
            year--;
            n+=365;
        }
    }
    else{
        dif_y=1970-year;
        for(i=1;i<=dif_y;i++){
            if((year%4==0&&year%100!=0)||year%400==0)
                n--;
            year--;
            n-=365;
        }
    }

    //printf("n=%d\n",n);
    return n;
}
int moveMinMax(int a[],int len){//最大数到最后最小数到最前,也可以使用2个循环分两次完成最大和最小值的移动
    int maxIndex=0,minIndex=0,i=0;
    int temp2=0,temp1=0,max=a[0],min=a[0];
    for(i=1;i<len;i++){
        if(max<a[i]){
            maxIndex=i;
            max=a[i];
        }
        if(min>a[i]){
            minIndex=i;
            min=a[i];
        }
    }

    if(maxIndex!=0){
        a[minIndex]=a[0];
        a[maxIndex]=a[len-1];
    }else{
        a[maxIndex]=a[len-1];
        a[minIndex]=a[0]; 
    }

    a[0]=min;
    a[len-1]=max;
}
#define N 6//控制人数

int numNe(int a[],int len){//每次数到3的人退出(循环)利用数组完成
    int i=0,index=0,j=0,left=len;

    while(left>1){
        if(a[index%len]!=0)
            j++;
        if(j%3==0&&a[index%len]!=0){//这里必须判断是否已经删除过,如果重复会导致留下的数比1多
            a[index%len]=0;
            left--;
        }
        index++;
    }

    for(i=0;i<len;i++){
        if(a[i]!=0)
            printf("left is %d ",a[i]);
    }
    system("pasue");
    return 0;
}' int main(){ int i,a[N]; for(i=0;i<N;i++) a[i]=i+1; numNe(a,N); system("pasue"); return 0; }