-
C第七天
今天講的主要是函數(shù)指針和字符串,到了這兒已經(jīng)做不出老師出的題目了,通常都是知道大概的思路但是無法用代碼表達出來复旬。老師針對我們近階段的學(xué)習(xí),給我們留了一道幾乎能用到之前所有知識點的作業(yè)——商人過河逢艘,思路很清晰,就是不知道怎么用代碼表達檩淋。
1.指向一個基本類型變量(int)的指針
int *p;
2.指向一個int型數(shù)組的指針菇爪,int a[5];
int (*p)[5]
3.定義一個函數(shù)的指針芽隆。
void func();
int func(int a,int b)
函數(shù)的指針——函數(shù)指針加匈。
void (*p)()=func;//定義一個指向函數(shù)返回值為void,并且函數(shù)不帶參數(shù)的函數(shù)的指針變量攘轩,并給這個指針變量賦了值洞辣,讓它指向此類型函數(shù)中的func函數(shù)漏设。
void (*p)()=&func;也是可以
int (*p)(int,int)=func;//定義了一個指向函數(shù)返回值為int恋脚,并且函數(shù)帶有2個int型參數(shù)的函數(shù)的指針變量煞檩,并給整個變量賦了值,讓它指向此類型函數(shù)中的func函數(shù)而涉。
例:
#include <stdio.h>
void func1()
{
printf("func1 be called!\n");
}
int func2(int a)
{
printf("func2 be called! a=%d\n",a);
return 0;
}
void main()
{
void (*pfun1)();
pfun1=func1;//讓pfun1指向func1函數(shù)
//pfun1=&func1;//也可以這樣寫
//(*pfun1)();
int (*pfun2)(int);
pfun2=func2;//讓pfunc2指向func2函數(shù)
pfun1();//通過指針調(diào)用func1函數(shù)
pfun2(10);//通過指針調(diào)用func2函數(shù)
}
#include <stdio.h>
/*
void func(int num1,int num2)
{
++num1;
++num2;
printf("num1=%d num2=%d\n",num1,num2);
}
void main()
{
int num1=1,num2=2;
func(num1,num2);//int num1=num1
printf("num1=%d num2=%d\n",num1,num2);
}
*/
/*錯誤寫法
void func()
{
int num=5;
}
void main()
{
func();
printf("num=%d\n",num);
}*/
void main()
{
int num;
printf("%d\n",num);
}
/*
局部變量:定義在函數(shù)內(nèi)的變量。
1.各個函數(shù)里面的變量可以同名联予,并且相互不影響啼县,因為局部變量的作用域只限于定義它的函數(shù)體內(nèi)。
2.它的生命周期始于定義它的那一刻沸久,終于定義它的函數(shù)的結(jié)束之前.在定義的時候會給他分配空間季眷,結(jié)束的時候空間會被釋放。
3.局部變量如果沒有賦值卷胯,將是隨機值子刮。
*/
#include <stdio.h>
int num=1;
void func1()
{
int num=3;
printf("num=%d\n",num);
}
void func2()
{
printf("num=%d\n",num);
}
void main()
{
int num=2;
printf("num=%d\n",num);
func1(); func2();
printf("num=%d\n",num);
}
/*
全局變量:定義在函數(shù)外面的變量。
特點:1.不賦值窑睁,默認為0
2.如果全局變量和局部變量同名挺峡,起作用的是局部變量。
3.在函數(shù)中如果沒有同名的局部變量担钮,那么起作用的是全局變量
*/
#include <stdio.h>
/*
void func()
{
int i;
for(i=1;i<=3;i++)
{
static int a=1;
a++;
printf("a:%d\n",a);
}
}
void main()
{
func();
// printf("a:%d\n",a);
}
*/
/*
void main()
{
static int a;
printf("a=%d\n",a);
}
*/
static int a;
void main()
{
printf("a:%d\n",a);
}
/*
static:靜態(tài)的
靜態(tài)變量:用static修飾的變量橱赠。
靜態(tài)局部變量:用static修飾的局部變量
特點:1.作用域只限于定義它的函數(shù)體內(nèi)。
2.它分配的空間會一直存在箫津,即使當定義它的函數(shù)結(jié)束了狭姨,它里面的值也能保留下來,只是出了函數(shù)就不能再用了苏遥,因為它的作用域只限于定義他的函數(shù)送挑。直到整個程序結(jié)束,空間被釋放暖眼。
3.靜態(tài)局部變量沒有賦初值惕耕,則默認為0.
靜態(tài)全局變量:static修飾的全局變量
特點:
1.沒有賦值的話,為0
2.只能在定義它的文件中用诫肠,在其他文件中不能用
全局變量的特點:
1.沒有賦值的話司澎,默認為0
2.作用于整個程序,除了定義它的文件可以使用它栋豫,其他文件中也能使用它挤安,但是在其他文件中使用它之前先聲明它,聲明語句:如:int a;
*/
#include <stdio.h>
void main()
{
const int a=1;
printf("a:%d\n",a);
// a=2;
// printf("a:%d\n",a);
}
//常變量:用const修飾的變量丧鸯,雖然是變量蛤铜,但體現(xiàn)著常量的特性,只能訪問它的值,不能修改它的值围肥,它的值只能在定義這個變量的時候以初始化的方式被賦值剿干。
練習(xí):給出年,月穆刻,日置尔,判斷該天是一年中的第幾天?
方法1
#include <stdio.h>
int a[]={31,28,31,30,31,30,31,31,30,31,30};
int Isleap(int);
int Sum(int,int);
void main()
{
int year,month,day;
printf("輸入年氢伟、月榜轿、日:");
scanf("%d %d %d",&year,&month,&day);
int days=Sum(month,day);
if(Isleap(year) && month>2)
days=days+1;
printf("總天數(shù):%d\n",days);
}
int Sum(int month,int day)
{
int i;
for(i=1;i<month;i++)
day=day+a[i-1];
return day;
}
int Isleap(int year)
{
return (year%4==0 && year%100!=0)||(year%400==0);
}
方法2
#include <stdio.h>
int Isleap(int);
void main()
{
int year,month,day;
printf("請輸入年、月朵锣、日:");
scanf("%d %d %d",&year,&month,&day);
switch(month-1)
{
case 11:
day += 30;
case 10:
day += 31;
case 9:
day += 30;
case 8:
day += 31;
case 7:
day += 31;
case 6:
day += 30;
case 5:
day += 31;
case 4:
day += 30;
case 3:
day += 31;
case 2:
day += Isleap(year)+28;
case 1:
day += 31;
}
printf("總天數(shù):%d\n",day);
}
int Isleap(int year)
{
return (year%4==0 && year%100!=0)||(year%400==0);
}
homework:
游戲說明:
有3個商人帶著3隨從和貨物過河谬盐,船每次最多只能載2個人,由他們自己劃行诚些,并且如何乘船渡河的大權(quán)由商人們掌握设褐。要求保證在過河期間的任一岸上商人的人數(shù)大于或者等于隨從的人數(shù),否則隨從會殺死商人搶奪貨物泣刹。設(shè)計一個符合上述要求的商人過河游戲助析。
游戲規(guī)則:
1.依次輸入過河的商人和隨從人數(shù)
2.非法輸入按鍵將重新開始游戲(例如:輸入的人數(shù)不能超過2,所以負數(shù)椅您,字符屬于非法輸入)
程序設(shè)計要點:
1.界面友好外冀,光標定位,字體或者背景顏色控制
2.多些功能子函數(shù)掀泳,主函數(shù)的功能只是負責調(diào)用子函數(shù)雪隧。
解題思路:
設(shè)商人為A,B,C。隨從為a,b,c 渡河過程:
1.A 帶a渡河
2.A將船劃回來
3.b.c兩名隨從接著劃船渡河
4.c將船劃回來
5.A B兩名商人劃船渡河
6.B b主仆二人劃船回來
7.B C兩人劃船渡河
8.a劃船回來
9.a b 渡河
10.商人C劃船回來
11.商人C帶c劃船渡河
字符串常量:用雙引號括起來的任意字符序列员舵。 “asdfg”.
因為在c語言中沒有專門字符串類型脑沿,所以無法定義一個字符串變量用來接受一個字符串常量。所以通常定義一個字符數(shù)組马僻,用來存儲字符串常量庄拇。
例:
char a[]="sdfghjk"; sizeof(a)<=>8
char a[]={'s','d','f','g'}; sizeof(a)<=>4
特點:
1.字符串常量默認以'\0'字符結(jié)尾。
sizeof(變量名/類型)韭邓;
sizeof(a):計算出以整個地址為起始地址的一段連續(xù)內(nèi)存的長度措近。
2.一個字符串常量,本身就表示一個指針女淑,即一個地址瞭郑,該字符串首元素的地址,作為一個指針指向的對象是該字符串中的字符鸭你。
例:
#include <stdio.h>
void main()
{
char *p="asdfgh";
printf("*p=%c *(p+1)=%c\n",*p,*(p+1));
printf("%d\n",sizeof(p));
}
//系統(tǒng)中32位指針長度是4;64位指針長度為8
gets(地址):從標準輸入(鍵盤)獲取一行字符串屈张,在獲取字符串時擒权,會把獲取的最后一個字符‘\n’,換成'\0'存儲阁谆。
例:
#include <stdio.h>
void main()
{
char name[30];
gets(name);
printf("%s\n",name);
}
練習(xí):從鍵盤獲取一行字符串碳抄,統(tǒng)計含有多少個空格
#include <stdio.h>
void main()
{
char name[30];
gets(name);
/*
int i=0,count=0;
while(name[i]!='\0')
{
if(name[i]==' ')
count++;
i++;
}
*/
char *p=name;
int count=0;
while(*p!='\0')
{
if(*p==' ')
count++;
p++;
}
printf("%d\n",count);
}
homework:利用遞歸函數(shù),逆序輸出一個字符串笛厦。這是昨天的作業(yè),直到講到這兒才拿出來講,因為需要用到今天學(xué)到的內(nèi)容
#include <stdio.h>
void Inverse(char *str)
{
if(*str=='\0')
return;
Inverse(str+1);
printf("%c",*str);
}
void main()
{
char *str="abcdefgh";
Inverse(str);
printf("\n");
}
puts(地址):向屏幕輸出字符串纳鼎,括號里面的地址可以是數(shù)組名/字符串常量/指針變量俺夕。輸出字符串會自動換行
#include <stdio.h>
void main()
{
char name[30]="asdfghj";
char *p="aaaaaaa";
puts("bbbbbbbb");
puts(name);
puts(p);
}
練習(xí):自己寫個函數(shù)mygets(),實現(xiàn)gets的功能裳凸,但不會出現(xiàn)越界。
#include <stdio.h>
void mygets(char *a,int len)
{
int i;
for(i=0;i<len-1;i++)
{
a[i]=getchar();
if(a[i]=='\n')
break;
}
if(a[i]!='\n')
{
while(getchar()!='\n');//吸收多余的字符劝贸。
}
a[i]='\0';
}
void main()
{
char a[30];
mygets(a,30);
printf("%s\n",a);
}
strlen():計算字符串的字符個數(shù)姨谷,并把計算結(jié)果返回出來,用整個函數(shù)要包含頭文件:string.h
例:
#include <stdio.h>
#include <string.h>
void main()
{
char a[]="i love beijing";
int len1,len2;
len1=strlen(a);
len2=strlen("i love beijing");
printf("%d %d\n",len1,len2);
}
練習(xí):自己寫個函數(shù)mystrlen()實現(xiàn)strlen的功能映九。
#include <stdio.h>
#include <string.h>
int mystrlen(char *str)
{
int c=0;
while(*str!='\0')
{
str++;
c++;
}
return c;
}
void main()
{
char *str="asdfghjk";
int n=mystrlen(str);
printf("%d\n",n);
}