-
C基礎第五天
最近幾天的學習給我最大的感觸就是懵逼,沒有頭緒,周六那天從學習C基礎的第一天筆記開始敲命令,敲了一天,結果最后除了坐的久帶來的身體上的不舒服,其他什么感想都沒有,也沒敲出一點頭緒。
今天上午老師先帶著我們把上周留的作業(yè)解決了,不做記錄,只靠我的邏輯思維,想了好幾種方法最后商人都會被仆人殺死,結果通過代碼得出是可以渡河的。
#include <stdio.h>
#include <stdlib.h>
char a[6],b[6];
//過河
void Surface()
{
system("clear");
printf("這是一個過河游戲:\n");
}
void Print(char a[],char b[])
{
int i,j,ab=0,aa=0,bb=0,ba=0; //ab:a岸的商人數(shù) aa:a岸的仆人數(shù),bb:b岸的商人數(shù),ba:b岸的仆人數(shù)
for(i=0;i<6;i++)//統(tǒng)計a岸的人數(shù)
{
if(a[i]=='B')
ab++;
else if(a[i]=='A')
aa++;
}
//統(tǒng)計b按的人數(shù)
for(j=0;j<6;j++)
{
if(b[j]=='B')
bb++;
else if(b[j]=='A')
ba++;
}
printf("此按的商人數(shù):%d\n",ab);
printf("此岸的仆人數(shù):%d\n\n",aa);
printf("彼岸的商人數(shù):%d\n",bb);
printf("彼岸的仆人數(shù):%d\n",ba);
if(ab==0 && aa==0 && bb==3 && ba==3)
{
printf("\n\n恭喜你,渡河成功!\n");
getchar();
exit(0);
}
}
void Process()
{
//預處理:
int i,j,ab,aa,bb,ba,go_b,go_a,back_b,back_a;
char c;
Start: for(i=0;i<3;i++)
a[i]='B';
for(i=3;i<6;i++)
a[i]='A';
for(j=0;j<6;j++)
b[j]='o';
Surface();
printf("按任意鍵開始游戲(按q/Q退出游戲)\n");
c=getchar();
if(c=='q' || c=='Q')
{
system("clear");
exit(0);
}
Print(a,b); //把2按的人員情況打印一下,判斷是否渡河成功
while(1)
{
//過去
for(ab=0,aa=0,i=0;i<6;i++)//統(tǒng)計a岸的人數(shù)
{
if(a[i]=='B')
ab++;
else if(a[i]=='A')
aa++;
}
printf("請輸入過河的商人數(shù):");
scanf("%d",&go_b);
printf("請輸入過河的仆人數(shù):");
scanf("%d",&go_a);
if(go_b<0 || go_a<0 || go_b>ab || go_a>aa || go_a+go_b>2 || go_a+go_b<1)
{
printf("輸入有誤,請重新開始!");
getchar();
goto Start;
}
//重新統(tǒng)計a,b按的人數(shù)
for(j=1;j<=go_b;j++)
for(i=0;i<6;i++)
{
if(a[i]=='B')
{
a[i]='o';
break;
}
}
for(j=1;j<=go_a;j++)
for(i=0;i<6;i++)
{
if(a[i]=='A')
{
a[i]='o';
break;
}
}
for(j=1;j<=go_b;j++)
for(i=0;i<6;i++)
{
if(b[i]=='o')
{
b[i]='B';
break;
}
}
for(j=1;j<=go_a;j++)
for(i=0;i<6;i++)
{
if(b[i]=='o')
{
b[i]='A';
break;
}
}
for(ab=0,aa=0,i=0;i<6;i++)//統(tǒng)計a岸的人數(shù)
{
if(a[i]=='B')
ab++;
else if(a[i]=='A')
aa++;
}
for(bb=0,ba=0,i=0;i<6;i++)//統(tǒng)計b岸的人數(shù)
{
if(b[i]=='B')
bb++;
else if(b[i]=='A')
ba++;
}
//判斷能夠進行下一次渡河的條件
if((ab==aa) || (bb==ba) || (ab==3) || (bb==3))
{
Print(a,b);
}
else
{
printf("商人被殺,仆人越貨!\n");
printf("游戲重新開始...\n");
getchar();
getchar();
goto Start;
}
//回來
for(bb=0,ba=0,i=0;i<6;i++)//統(tǒng)計b岸的人數(shù)
{
if(b[i]=='B')
bb++;
else if(b[i]=='A')
ba++;
}
printf("請輸入回來的商人數(shù):");
scanf("%d",&back_b);
printf("請輸入回來的仆人數(shù):");
scanf("%d",&back_a);
if(back_b<0 || back_a<0 || back_b>bb || back_a>ba || back_a+back_b>2 || back_a+back_b<1)
{
printf("輸入有誤,請重新開始!");
getchar();
goto Start;
}
//重新統(tǒng)計a,b按的人數(shù)
for(j=1;j<=back_b;j++)
for(i=0;i<6;i++)
{
if(b[i]=='B')
{
b[i]='o';
break;
}
}
for(j=1;j<=back_a;j++)
for(i=0;i<6;i++)
{
if(b[i]=='A')
{
b[i]='o';
break;
}
}
for(j=1;j<=back_b;j++)
for(i=0;i<6;i++)
{
if(a[i]=='o')
{
a[i]='B';
break;
}
}
for(j=1;j<=back_a;j++)
for(i=0;i<6;i++)
{
if(a[i]=='o')
{
a[i]='A';
break;
}
}
for(ab=0,aa=0,i=0;i<6;i++)//統(tǒng)計a岸的人數(shù)
{
if(a[i]=='B')
ab++;
else if(a[i]=='A')
aa++;
}
for(bb=0,ba=0,i=0;i<6;i++)//統(tǒng)計b岸的人數(shù)
{
if(b[i]=='B')
bb++;
else if(b[i]=='A')
ba++;
}
//判斷能夠進行下一次渡河的條件
if((ab==aa) || (bb==ba) || (ab==3) || (bb==3))
{
Print(a,b);
}
else
{
printf("商人被殺,仆人越貨!\n");
printf("游戲重新開始...\n");
getchar();
getchar();
goto Start;
}
}
}
void main()
{
Process();
}
字符串常量:
用雙引號擴起來的任意字符序列 “sdfghj”.
通常是用字符數(shù)組存儲它。例:
char a[]="sdfghj";
char a[8]="asdfg";
char a[10]={'a','h'};
例:
#include <stdio.h>
void main()
{
char a[]="asdfg";
printf("%ld\n",sizeof(a));
char b[5]="asdfg";
printf("%ld\n",sizeof(b));
char c[]={'a','s','d','f','g'};
printf("%ld\n",sizeof(c));
}
1.一個字符串常量后面默認以'\0'結尾。如果數(shù)組的長度不夠,那么就不會存'\0';
2.在c語言中沒有專門的數(shù)據(jù)類型變量用來接收一個字符串,所以通常是放在字符數(shù)組里面
3.sizeof(地址):計算以這個地址為其實地址的一段連續(xù)內存的長度
gets(地址):
從標準輸入(鍵盤)獲取一行字符串。會把獲取的字符串最后的\n換成'\0',然后存儲到地址中。
例:
#include <stdio.h>
void main()
{
char name[20];
gets(name);
printf("%s\n",name);
}
puts(地址):輸出地址中的字符串
例:
#include <stdio.h>
void main()
{
char name[20];
gets(name);
puts(name);
puts("asdfghj");
}
字符串常量的特點:表示的是該字符串首元素的首地址
#include <stdio.h>
void main()
{
char *p="qwertyui";
printf("%c %c\n",*p,*(p+1));
}
mygets():實現(xiàn)從鍵盤上獲取一行字符串,但是不會出現(xiàn)越界問題。
#include <stdio.h>
void mygets(char *,int);
void main()
{
char name[30];
mygets(name,30);
printf("%s\n",name);
}
void mygets(char *str,int len)
{
int i;
for(i=0;i<len-1;i++)
{
str[i]=getchar();
if(str[i]=='\n')
break;
}
if(str[i]!='\n')
{
while(getchar()!='\n');
}
str[i]='\0';
}
練習:利用gets統(tǒng)計獲取的字符串中有多少個空格
#include <stdio.h>
void main()
{
int i=0,count=0;
char str[20];
gets(str);
while(str[i]!='\0')
{
if(str[i]==' ')
count++;
i++;
}
printf("count:%d\n",count);
}
strlen(地址):計算字符串的長度,返回字符串的個數(shù)
頭文件:string.h
#include <stdio.h>
#include <string.h>
void main()
{
char str[]="i love beijing";
int a=strlen(str);
printf("a:%d %ld\n",a,strlen("hello hello"));
}
mystrlen() :自己實現(xiàn)strlen的功能。
例:
#include <stdio.h>
#include <string.h>
int mystrlen(char *);
void main()
{
char str[]="i am falling in love";
int a=mystrlen(str);
printf("a=%d\n",a);
}
int mystrlen(char *str)
{
int n=0;
while(*str!='\0')
{
str++;
n++;
}
return n;
}
strcpy(目標地址,源地址):拷貝字符串,把源地址里面的字符串拷貝到目標地址里。目標地址里的內存要足夠容納的下源地址里的數(shù)據(jù)。包含頭文件:string.h 有返回值,返回目標地址。
例:
#include <stdio.h>
#include <string.h>
void main()
{
char src[]="i am a good student";
char tar[50];
char *p=strcpy(tar,src);
puts(p);
}
mystrcpy();
#include <stdio.h>
#include <string.h>
char *mystrcpy(char *,char *);
void main()
{
char src[]="i am a good student";
char tar[50];
char *p=mystrcpy(tar,src);
puts(p);
}
char *mystrcpy(char *tar,char *src)
{
int i=0;
while(src[i]!='\0')
{
tar[i]=src[i];
i++;
}
tar[i]='\0';
return tar;
}
#include <stdio.h>
#include <string.h>
void main()
{
char src[]=" a good student";
char tar[50]="i am";
char *p=strcpy(tar+4,src);
puts(p);
puts(tar);
}
//p是源字符串拷貝到目標字符串的起始地址
//注意,不要在目標字符串'\0'之后接入拷貝的源字符串
#include <stdio.h>
#include <string.h>
void main()
{
int n;
char src[50]=" a good student";
char tar[10]="i am";
char *p=strncpy(tar,src,10);//把src中的10個字符拷貝到tar中。
puts(p);
p=strncpy(tar+4,src,10);
puts(tar);
}
strcat(desc,src):拼接字符串,把src字符串接在desc后面,desc要足夠大,能夠容納下拼接后的字符串,返回desc的地址。
包含頭文件:string.h
#include <stdio.h>
#include <string.h>
void main()
{
int n;
char src[20]=" a good student";
char tar[50]="i am";
char *p=strcat(tar,src);
puts(p);
puts(tar);
}
strncat():
#include <stdio.h>
#include <string.h>
void main()
{
int n;
char src[20]=" a good student";
char tar[50]="i am";
char *p=strncat(tar,src,7);//把src中的前7個字符拼接到tar中字符串的后面保存在tar中
puts(p);
puts(tar);
}
strcmp(a,b):比較2個字符串是否完全一致.如果a與b一致,返回0,如果a大于b返回一個正數(shù),否則返回一個負數(shù)
頭文件:string.h
#include <stdio.h>
#include <string.h>
void main()
{
char a[]="i am a boy";
char b[]="i am a student";
int c=strcmp(a,b);
printf("%d\n",c);
}
//a,b大小比較的規(guī)則:從一個字符開始比,第一個不相同的字符的ascii值大的,字符串大。
strncmp(a,b,n);
#include <stdio.h>
#include <string.h>
void main()
{
char *list[5]={"awayken is good","awayken is young","awayken is smart","awayken is wise","awayken is nb"};
for(int i=0;i<5;i++)
{
if(strncmp(list[i],"awayken is a good boy",7)==0)
printf("%s\n",list[i]);
}
}
擴充:
- strchr();
- strrchr();
static:
#include <stdio.h>
void func();
void main()
{
int i=0;
for(;i<3;i++)
func();
// printf("a=%d\n",a);
}
void func()
{
static int a;
a++;
printf("a=%d\n",a);
}
static:靜態(tài)變量修飾符,靜態(tài)局部變量的生命周期是整個程序,但是作用域只限于定義它的函數(shù)。
靜態(tài)局部變量沒有初始化,默認為0。
全局變量:
1.沒有賦值,默認為0
2.作用域是整個程序,定義在1.c中的變量在2.c中也能用
局部變量:
1.沒有賦值,為隨機值
2.作用域只限于定義它的函數(shù),出了函數(shù)不能訪問它,
3.生命周期也只限于定義它的函數(shù)
4.可以和全局變量同名,在定義它的函數(shù)里,會隱藏同名的全局變量的作用
5.可以和其他局部變量同名,互相不影響
靜態(tài)全局變量:
1.沒有賦值,默認為0
2.只能的是定義它的文件能使用它,其他文件不能使用。
3.存在于整個程序,作用域為定義它的文件。
const:被修飾的變量體現(xiàn)出常量的特性,只能在定義的時候以初始化的方式給它賦值,之后不能改變它的值。
#include <stdio.h>
void main()
{
const a=1;
a=2;
}
常量指針與指針常量
const int *p; <=> int const *p;
int *const p;
例:
#include <stdio.h>
void main()
{
int a=10;
const int *p=&a;//const 修飾的是*p,則不能改變*p的值,但可以改變p
printf("%d\n",*p);
int b=20;
p=&b;
printf("%d\n",*p);
}
#include <stdio.h>
void main()
{
int a=10;
int *const p=&a;//const 修飾的是p,則不能改變p的值,但可以改變*p
printf("%d\n",*p);
int b=20;
// p=&b;
*p=20;
printf("%d\n",*p);
}
#include <stdio.h>
void main()
{
int a=10;
int const *const p=&a;//const 修飾的是p,則不能改變p的值,但可以改變*p
printf("%d\n",*p);
int b=20;
// p=&b;
// *p=20;
// printf("%d\n",*p);
}