本周主要学习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; }