C语言(初遍学的一些零乱笔记)
本課中所有的程序都需要這一段,直到學函數之前,我們的代碼都只是在這個框架中間,也就是xxx的位置。
? 做事情的句子之后必須有分號,不過換行無所謂,在C里面,換行/空格不代表任何。
printf("%d",12+34); printf("12+34=%d",12+34) #%d 說明后面有一個整數要輸出在這個位置上int price; int amount; int price,amount;scanf("%d",&price)const int AMOUT=100; #后期不能被賦值修改 int price=0; int change=AMOUNT-price;條件判斷
//如果符合括號里的條件,就做,不符合就不會做了//常規形式 if(im<0){im+=60;ih--; }else{xxx }//如果沒有大括號,那么只有緊跟在它后面的那一句是有效的 //(好的編程習慣)建議是要加大括號的,因為else的歸屬情況是,嚴格遵循就近原則(即使有時候不再符合縮進),所以加上大括號會更加明了一些 if(im<0)im+=60; elsexxx;//if嵌套 int a,b,c; scanf("%d %d %d",&a,&b,&c);int max=0; if(a>b){if(a>c){max=a}else{max=c} }else{if(b>c){max=b}else{max=c} } printf("The max is %d\n",max);我有一個問題:為什么print f那個引號里面最后的地方要加個\n呢??都有什么句子必須加呢??
//多路分支 switch(type) { case 1: case 2:printf("hhh\n");break; //加了break就跳出 case 3:printf("ggg\n"); //沒加break會繼續進行4 case 4:printf("kkk\n");break; //以上幾個數字都沒出現,則執行default后面的語句 default:printf("a\n");break; }//有時候劃分范圍的問題,可以取其中的十位數/百位數那種(方法就是那個除并取整),然后轉化為數字多分類問題循環
//普通while循環 int x; int n=0; scanf("%d",&x);n++; x/=10; while(x>0){n++;x/=10; } printf("%d\n",n);//do-while循環 /*在進入循環的時候不做檢查,而是在執行完一輪循環體的代碼之后,再來檢查循環的條件是否滿足,如果滿足則繼續下一輪的循環,不滿足則結束循環*/int x; int n=0; scanf("%d",&x); do{x/=10;n++; }while(x>0); printf("%d\n",n);//for循環 int count=1; /*常用套路:若是乘積,則初始化為1,若是加和,則初始化為0*/ int i; for(i=10;i>1;i--){count*=i; } /*完全等同于以下while循環*/ int i; while(i>1){count*=i;i--; } /*這種一般是用于n需要保住這個值,后面可能還會用到的情況*/ int n=10; int i; for(i=n;i>1;i--){count*=i; }/*用于n不需要保值,,以后用不到了的情況*/ int n=10; for(n=n;n>1;n--){count*=n; } /*for循環語句里n=n可以省略,但分號不能省略*/ int n=10; for(;n>1;n--){count*=n; }//可以看出 for(;條件;){} == while(條件){}· 三種循環對比:
如果有固定次數,用for循環;
如果必須執行一次,用do-while循環;
其他情況用while循環。
//循環控制 break continue /*不過它們只能對自己所在的那層循環進行跳出/重來,如果要逐層跳出循環的話,一種方法是——需要使用接力break,如下所示*/exit=1;break;} } if(exit=1) break;//另一種方法是:int main() {xxx//此處代表省略了前面的一大堆,只展示結尾跳出部分goto out;}} } out:return 0; }? 有的時候,上一步的結果可以通過給一個新變量賦值,再通過新變量值的判斷輸出結果的方式來進行,并且有的時候,這種方式,比其他的一些比較大小要優越一點。
//五個一行 if(cnt%5==0){printf("\n"); } //對的整整齊齊 printf("%d\t",x); 這個\t使它對齊 //題目練習:正序輸出整數 int main() {int x;scanf("%d",&x);int mask=1;int t=x;while(t>=10){t/=10;mask*=10;}while(mask>0){a=x/mask;x=x%mask;mask/=10;printf("%d",a);if(mask>0){printf(" ");}} /*我認為我這樣做是沒錯的,沒必要do-while,因為mask它必然大于0,它初始都是1了,而且你前面唯一的可能是讓它變大,所以你直接用while應該是沒什么問題的。當然你do-while從邏輯上也是對的,更直白地表現出了它必須要進行一次。*/ return 0; }? 現在的問題就是,奧,我了解這個語法了,但是我做的題少,用起來還是很不熟悉,還是有可能在一些條件設置上犯錯誤,或者是選擇了不太合適的語法。就是還要多練,多做題,這一遍過去之后回來一定要多做題練習熟練一點。
? ·關于do-while和while,前者雖然是在后面判斷,但是它影響的是會不會進行下一次循環,所以它并不是使它可以后驗,超出了這個要求就取消本次循環;恰恰相反,它還是必須要做一次的,還不如while。由于并沒有后判斷再取消操作的這種函數,所以只能是修改條件,把前置條件等價轉化成若它在后置條件為此的時候所等價對應的前置條件,便如上所示,把 t>0 修改為 t>=10。
//使用輾轉相除法計算最大公約數 #include <studio.h> int main() {int a,b;int t;scanf("&d &d",&a,&b);do{if(b=0){printf("gcd=%d",a);}else{t=b;b=a%b;a=t;}}while(b!=0);return 0; } //例題一:求符合給定條件的整數集【這個的數字位數是確定的】int a,b,c,d; scanf("%d",&a); b=a+1; c=a+2; d=a+3; //這是我的嘗試,我想先列出來,但這樣并不明智……做不出來了? 計算機為什么不能利用我們的方法枚舉——因為它不能記憶上一個,還要去比對,看是不是重復,這個條件判斷就很離譜,所以我們只能使用更適合計算機的也就是更普適的方法——遞歸。
//例題一:求符合給定條件的整數集【這個的數字位數是確定的】 int a; scanf("%d",&a); int i,j,k; int cnt=0; i=a; j=a; k=a; while(i<=a+3){while(j<=a+3){while(k<=a+3){if(i!=j){if(i!=k){if(j!=k){printf("%d%d%d",i,j,k);cnt++;if(cnt%6=0){print("\n");}else{print(" ");}}}k++;} j++;}i++;} }我覺得不對勁啊…有點質疑這個答案
??是我對while的特性掌握不清還是對if的特性掌握不清?剛才讀到了這句指令,但由于當時不符合條件而跳過了這句指令,之后因為操作使得條件符合了,就會去執行剛才那個指令嗎??
//例題二:水仙花數【這個相比上一題,多了位數的不確定性和一個輸出的條件判斷】 //我在平板打草紙上寫了一遍,今天就先不打上來了? 一開始沒做出來主要是因為思路跑偏了,被上一個例題帶的,一直想一位數一位數的處理,至于每個用哪個方法我還沒完全想清楚,再往后學學再回來考慮吧。
//例題三:下三角九九乘法表 //較為簡單,暫時略 //例題四:統計素數求和 int main() {int m,n;scanf("%d %d",&m,&n);int i;int cnt=0;int sum=0;if(m==1){m=2;}for(i=m;i<=n;i++){int isprime=1;int k;for(k=2;k<=n;k++){if(i%k==0){isprime=0;break;/*我一開始這里忘記加break了,邏輯上沒錯但是就要白費很多功夫,都已經知道它不是素數了你還算什么算…*/}}if(isprime=1){cnt++;sum+=i;}}printf("%d %d",cnt,sum);return 0; } //例題五:猜數字游戲 //比較簡單,暫時略過 //例題六:求序列前n項和 //比較簡單,暫時略過 //但此處引出了int上界和double上界的問題 //例題七:約分最簡分式 int a,b; scanf("%d/%d",&a,&b); int m=0; int n=1; int t=1; while(t>0){ m=b;b=a%b;t=a/b;a=m;if(a%b=0){n=b;} } if(m=0){printf("分母不能為0!"); } printf("%d/%d\n",a/n,b/n);//例題八:念數字 int a; scanf("%d",&a); int m=a; int n=a; int count=0; int i; /*因為后續用到余數相關,需要按0判別,所以首先處理完本身就是0的情況*/ if(a=0){printf("ling"); }/*因為要從左往右讀,所以先算出它是幾位數*/ while(m!=0){m=m/10;count++; } /*得到最大的除數*/ for(i=1;i<=count;i++){int j=1;j*=10; }/*改進1:上面兩個步驟可以合二為一,算出是幾位數的同時得到應該除的部分 while(m>=10){int j=1;m/=10;j*=10; } 只能說還是經驗不足+基本模型沒有很好的掌握,每次都在重新寫一遍模型*//*逐個取出并念出*/ int b=1; int k; while(j>=1){k=n/j;if(k<0){printf("fu");printf(" ");k=-k;if(k=1){printf("yi");}else if(k=2){printf("er");}else if(k=3){printf("san");}else if(k=4){printf("si");}else if(k=5){printf("wu");}else if(k=6){printf("liu");}else if(k=7){printf("qi");}else if(k=8){printf("ba");}else if(k=9){printf("jiu");}else if(k=0){printf("ling");}}else if(k>0){if(k=1){printf("yi");}else if(k=2){printf("er");}else if(k=3){printf("san");}else if(k=4){printf("si");}else if(k=5){printf("wu");}else if(k=6){printf("liu");}else if(k=7){printf("qi");}else if(k=8){printf("ba");}else if(k=9){printf("jiu");}else if(k=0){printf("ling");}}n=n%j;j/=10; } /*改進2:其實這里k<0只要一上來就輸出fu然后變成正的就不用費兩遍事了*/ /*改進3:我這里是刪掉了每條后面贅余的空格的,首先你想每個后面加空格,你不用每句加一個呀好不,你直接在那后面寫就行;另一方面,最后一個后面是不需要輸出空格的,所以在改進二進行了的條件下,只需要在恰當的位置處加上: if(j>=10){printf(" "); } *///例題九:求a的連續和 int a,n; scanf("%d %d",&a,&n); int i; int sum1=0; int sum2=0; int j=1; //錯了 int k; int k=1; for(i=1;i<=n;i++){sum1+=2*j;sum2+=sum1;//這是一種辦法,還有一種辦法是可以b=b*10+a,比我這種更好想一點for(;k<=i;k++){ //錯了 for(k=1;k<=i;k++){ //錯了 t*=10;j*=10;} //錯了 j*=t;} printf("%d\n",sum2);/*這里多套了一層是一個大錯;另一個大錯也是很重要的教訓點: 在for循環里如果嵌套for循環,一定要注意,內部嵌套的那個很有可能不該寫初始條件!!因為這樣內部就會進行兩次循環,所以說建議酌情,最好是把變量的初始值拿到最前面去,防止犯錯!*/? 務必要整理基本模型!!!比如素數、最大公約數、從左到右逐個輸出、從右到左逐個輸出等。
sizeof() //注意它并不會對里面進行運算操作,只會按照規律去預判一下將獲得的類型 char short int long long long數組
//例題:輸入一堆不定量的個位數,并統計每個數字出現的次數 const int num=10; int array[num]; int i; int x; for(i=0;i<=num;i++){array[i]=0; } /*可以直接 int array[num]{0}; */ scanf("%d",&x); while(x!=-1){if(x>=0&&x<=9){array[x]++;}scanf("%d",&x); } for(i=0;i<num;i++){printf("%d:%d\n",i,array[i]); } //一個是我還不太明白&是干嘛,為啥交替用i和x,另一個是我還是對循環的理解不太夠 //數據的集成初始化 int a[]={1,2,3,4,5,6,7}; int a[13]={2,4,6} //剩余的都補位為0 //以下是一個C99 only的做法,也可以不給出數組大小,讓編譯器算 int a[10]={[0]=2,[2]=3,6, }//這種方法特別適合初始數據稀疏的數組 sizeof(a)/sizeof(a[0])//是數組元素個數 //這樣的代碼,一旦修改數組中初始的數據,不需要修改遍歷的代碼 //還是素數那個題,我接下來用多種方式去構建//方法1,較為常規,數學思維,sqrt方法int i; int isprime(i);//函數聲明 //主函數 int main(){for(i=2;i<=20;i++){if(isprime(i)){printf("%d\n",i)}}return 0; } //定義的isprime()函數 int isprime(i){int t;isprime=1;for(t=2;t<=sqrt(i);t++){if(i%t=0){isprime=0;break; }}return isprime; }//方法2,考慮到除了2以外的偶數都不可能,所以先構建一個包含了2的數組,然后逐漸往里面加//其實還有一種是你可以就是只考慮到偶數那一塊兒,我放到方法4了int primes[20]={2}; int length=1; const int max=20; int i; int addprime(i,primes[],length);int main(){for(i=3;i<=20;i+=2){addprime(i,primes[],length)}return 0; }int addprime(i,primes[],length){int t;for(t=2;t<=sqrt(i);t++){if(i%t==0){break;}else{primes[length++]=i;//我想知道,這里好像沒有把真正的 length++ 哎…這不是個獨立的變量空間嗎…//!!對呀,所以完全搞錯了。。}} }//方法二修改版: int i; int primes[length]={2}; int length=20; int cnt=1; int isprime(int i,int primes[],int length);int main(){for(i=2;i<length;i++){if(isprime(i,primes[],length)){primes[cnt++]=i;}}//下面增加一段,以進行格式較為規整的輸出for(i=0;i<length;i++){printf("%d",primes[i]);if((i+1)%5==0){printf("\t");}else{printf("\n");}}return 0; }int isprime(int i,int primes[],int length){ret=1;int x;for(x=0;x<length;x++){if(i%primes[x]==0){ret=0;break; }}return ret; } //方法3:使用刪除的方法 /*先構建一個數組,全是1 只挑選為1的,從0到滿,去判斷是不是isprime,是的就保持為1,并把它們的每個倍數全都設置為0,如果不是就把它自己弄成0 isprime依然是比較淳樸的樣子 */ //方法:使用數組來記錄0,1:考慮到你無法直接說,我除去這個數(至少說目前我不知道如何完成這件事),所以還是那樣,設計一個變量,然后我是1/0;再考慮好多好多數呢,所以就設置一個數組,它的鍵是數字,內部是0/1/*int array[20]={1}; 一上來就不對!!這樣的話其他補位可都是0呀!*/int i; int isprime(i); int sum=0; const int max=20; int array[max];int main(){for(i=0;i<max;i++){array[i]=1;}for(i=2;sum<=20;i++){isprime(i);sum++;}printf("%d\n",array); }int isprime(i){int t;for(t=2;t<sqrt(i);t++){if(i%t==0){array[i]=0;break;}else{int x;for(x=2;x*i<20;x++){array[i]=0;}}} } //又犯了這個錯…改吧//方法三修改版1.2 : int main(){int i;//int isprime(i);int array[max];const int max=20;for(i=0;i<max;i++){array[i]=1;}/*第一次注掉的for(i=2;i<max;i++){if(!isprime(i){array[i]=0;}else{int t;for(t=2;t*i<max;;t++){array[t*i]=0;}}}for(i=0;i<max;i++){if(isprime(i)){printf("%d\n",array[i]);}}*//*第二次又被我注掉了,不錯for(i=0;i<max;i++){for(x=2;x<sqrt(i);x++){if(i%x==0){array[i]=0;break;}else{for(t=2;t*i<max;t++){array[t*i]=0;}}}}for(i=2;i<max;i++){if(array[i]){printf("%d\n9",i);}}*///其實吧它這就是一個簡單的數字邏輯問題,所有的非素數(除1外)一定是素數的整數倍,所以說,你只要從前往后地去掉所有已知素數的整數倍,那么在你往后走的過程中,遇到的沒有被剔除的每個數都一定是素數了…來吧int i;int array[i];const int max=20;for(i=0;i<max;i++){array[i]=1;}for(i=2;i<max;i++){if(array[i]){int x;for(x=2;x*i<sum;x++){array[x*i]=0;}}}for(i=2;i<max;i++){if(array[i]){printf("%d\n",i);}}return 0; }//ok了! /*int isprime(int i){int ret=1;for(t=2;t<=sqrt(i);t++){if(i%t==0){ret=0;break;}} }*/ //好家伙,我想說,我覺得我這個修改后的確實沒錯,但我還是封裝了函數,我突然發現,老師講的意思是你不封裝函數……那個0/1是數組的值!!好家伙,怪不得我找了半天都找不到老師寫的函數在哪/*//方法4→不想了,我直接注掉了 int i; int ret; int isprime(i); int cnt=20;int main(){for(i=1;cnt>0;i++){//我想知道在函數isprime里放上cnt--有用嗎…不是說因為變量處于不同空間,所以改不了其他變量的值來?if(isprime(i)){printf("%d\n",i);}}return 0; }int isprime(i){ret=1;if(i==1||i%2==0&&i!=2){ret=0;cnt--;}else if(i!=2){int t;for(t=3;t<=sqrt(i);t+=2){if(i%t==0){ret=0;break;}else{cnt--;}}else{cnt--;}return ret;}}*/· 切記,一定不要只顧著趕進度,每一個章節對應的題都要認認真真再自己做一遍,看懂不等于理解,更不等于會做,一定要自己全部敲一遍,并且把老師所寫代碼的思想吃透!!
· 我這個犯錯的思想其實有點受之前學python的影響,我覺得,把更多的東西封裝進函數里,主函數越簡潔越好,但這對于我目前學到的C語言的部分來說是不合理的,因為你的函數目前只是可以return一個值而已,并不能去修改你原本有的值。
總結
以上是生活随笔為你收集整理的C语言(初遍学的一些零乱笔记)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安恒信息范渊:AI+安全这条路是可以走通
- 下一篇: 程一笑:快手电商GMV已达到万亿规模