之前學習語言都只是看視頻,到自己寫的時候什麼都寫不出來,現在要改掉這個壞習慣O(∩_∩)O哈哈~。都是很基礎的東西。
首先第一題(參考了視頻中的答案。嘗試自己寫的):輸入年份、和這一年的第N天,最後算出這一天是這一年的幾月幾日。(區分閏年)
#include <stdio.h>
int main()
{
int month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int Leap_month[12] = { 31,29,31,30,31,30,31,31,30,31,30,31 };
int year, day, i;
int Leap_flag;
int R_flag = 1;
while (R_flag == 1)
{
printf("Please input year and day\n");
scanf_s("%d,%d", &year, &day);
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
{
Leap_flag = 1;//這裏寫的並不好,可以用指針直接修改28到29就不用列出兩個數組以及再加一個leap判斷
}
else
{
Leap_flag = 0;
}
if (day>365 && Leap_flag == 0 || day>366 && Leap_flag == 1)
{
printf("Please input right day");
}
else
{
R_flag = 0;
// break;
}
}
if (Leap_flag == 1)
{
for (i = 0; day>*(Leap_month + i); i++)
{
day -= *(Leap_month + i);
}
printf("Years=%d,Month=%d,Day=%d", year, i + 1, day);
}
else
{
for (i = 0; day>*(month + i); i++)
{
day -= *(month + i);
}
printf("Years=%d,Month=%d,Day=%d", year, i + 1, day);
}
return 0;
}
第二題
取十個1-100的隨機整數,並倒序打印出來(用指針,不要用數組下標)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
void func(int *num)
{
int i;
srand((unsigned int)time(NULL));// srand()函數初始化隨機數種子,rand()產生隨機數
for (i = 0; i < N; ++i)
printf("num[%d] = %d.\n", i, *(num + i) = rand() % 100 + 1);// 循環產生0~99的隨機數,再加上1, 放入num裏,同時打印出來
}
int main()
{
int num[N] = {0};
int *p = num;
func(num);
for (p = num + N - 1; p >= num; --p)
printf("%d ", *p);
// 把p的下標移動到數組的最後一位,然後從後往前循環遍歷,
// 如果當前下標的地址大於數組的首地址,那就每次往前移動一個int,同時打印出來
printf("\n");
return 0;
}
第三題
通過隨機函數獲取到26個小寫英文字母,存儲到數組裏並小寫字母順序打印出來。
這題對我而言還是比較難的,直接參考原文吧-_-||
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LEN 26
void func(char *s)//用這個函數直接實現按順序把字母放進去,就不用在後面再排序!!!
{
srand((unsigned int)time(NULL));
int n = 0;
while(n < LEN) // 循環條件是,數組存滿了26個字母
{
int temp = rand() % LEN;// 設定一個變量用來接收 0~25 的隨機數
if(*(s + temp) == 0) // 如果數組裏的某個下標的值是 0,那麼就進入後面的語句,如果數組裏的某個下標的值是字母,說明就賦值過了,就不執行後面的語句,對應一下這個函數的功能就能懂這裏
{
*(s + temp) = temp + 'a'; // 把隨機到的數字,加上字符'a',隱式轉換成字母,對應下標存放到字符數組裏
n++; // 每次放入一個正確的字母,n就自增1,
}
}
}
int main()
{
char a[LEN] = { 0 };
func(a);
for (int i = 0; i < LEN; ++i)
printf("%c\n", *(a + i));
printf("\n");
return 0;
}
第四題
將字符串“We Are Family!”,去除空格後打印出來。(WeAreFamily!)
先按照我自己的思路寫一下試試吧ヾ(◍°∇°◍)ノ゙
#include <stdio.h>
char *func(char *str)
{
int i = 0;
int j = 0;
for (; *(str + i) != '\0'; ++i)
{
if (*(str + i) != ' ')
{
*(str + j++) = *(str + i);//只要是不爲空格,i 和 j都會自增,並且做替換;如果是空格,那麼i會自增,j不動
}
}
*(str + j) = '\0';
return str;
}
int main()
{
char str[] = "we are family";
func(str);
printf("After delete spaces = %s\n", func(str));
return 0;
}
第五題
輸入一個字符串,判斷其是否是迴文。(迴文:即正讀和反讀都一樣,如abcba, abccba)
兩種方法:1。
#include <stdio.h>
#include <string.h>
#define N 50 //50個足夠了
int func(char *p, int len) // 獲取字符串的首地址,和字符串長度
{
for(int i = 0; i < len / 2; ++i) // 循環次數是字符串長度的一半
if( *(p + i) != *(p + len - i - 1)) // 比較前面的字符和後面的字符是否不等
return 0; // 如果不相等,就返回0,表示字符串不是迴文
return 1; // 如果循環接收一直沒有返回 0, 則表示字符串是迴文,返回1 給調用函數
}
int main(void)
{
char str[N] = { 0 }; // 創建一個長度爲50的字符串
scanf("%s", str); // scanf()接收用戶輸入的字符串
if(func(str, strlen(str))) // 這裏做了三步:1.獲取字符串長度,並且和字符串首地址一起傳給被調用函數的形參
// 2. 調用了func()函數,同時接收函數的返回值
// 3. 接收函數的返回值,決定了分支語句的執行
printf("Yes! %s is huiwen! \n", str);
else
printf("Sorry! %s is not huiwen! \n", str);
return 0;
}
方法2
int func(char *p, int len) // 獲取字符串的首地址,和字符串長度
{
for(int i = 0; i < len / 2; ++i) // 循環次數是字符串長度的一半
if( *(p + i) != *(p + len - i - 1)) // 比較前面的字符和後面的字符是否不等
return 0; // 如果不相等,就返回0,表示字符串不是迴文
return 1; // 如果循環接收一直沒有返回 0, 則表示字符串是迴文,返回1 給調用函數
}
int main(int argc, char *argv[])
{
if(func(argv[1], strlen(argv[1]))) // argv[0]是程序名字,argv[1]是緊接着的字符串。這裏做了三步:1.獲取字符串長度,並且和字符串首地址一起傳給被調用函數的形參// 2. 調用了func()函數,同時接收函數的返回值// 3. 接收函數的返回值,決定了分支語句的執行
printf("Yes! %s is huiwen! \n", argv[1]);
else
printf("Sorry! %s is not huiwen! \n", argv[1]);
return 0;
}
問題6
輸入一段字符串,無論是否有重複字母出現,都只打印出現過的小寫字母,並按照小寫字母順序打印。(如輸入qewqwr322rqw<>211qESFSSEraZz, 打印aeqrwz)感覺和第三題差不多,只是判斷條件有點區別
#include <stdio.h>
#include <stdlib.h>
#define N 500
int main()
{
char str1[N] = { 0 }; // 存儲用戶輸入的字符串
char str2[N] = { 0 }; // 存儲要打印的字符串
scanf("%s", str1); // 接收用戶輸入
int index = 0;
for (int i = 0; *(str1 + i) != '\0'; ++i) // 遍歷str1字符串,直到字符串結尾'\0'
{
index = *(str1 + i) - 97; // 取出*(str + i)的字符,減去 小寫字母a的ascii碼 97,當作數組下標,給index
*(str2 + index + 97) = '+'; // 在str2裏面,把 index下標的元素置爲 + 號,做爲標記
}
for (int i = 97; i < 26 + 97; ++i) // 下標從97開始,循環遍歷str2
if( *(str2 + i) == '+') // 如果遍歷到的下標有 + 號標記,之前判斷這裏是有出現過字母,
printf("%c ", i); // 那麼就打印這個下標對應的字母ASCII碼,也就是打印字母了。
printf("\n");
return 0;
}
問題7
輸入某個月的第N周和這一週的第M天,通過int *GetDay() 函數獲取參數並返回結果,來得出這一天是這個月的第多少天。
(如輸入:3,4,即這個月的第3周的第4天,即這個月的第18天)
#include <stdio.h>
int *GetDay(int n, int m)
{
// 在函數返回時,函數內部的局部變量會被銷燬
// static 定義靜態變量,這個變量的聲明週期是整個源程序,作用域不變
static int calc[5][7] =
{
{1,2,3,4,5,6,7},
{8,9,10,11,12,13,14},
{15,16,17,18,19,20,21},
{22,23,24,25,26,27,28},
{29,30,31}
};
return &calc[n-1][m-1];
// 返回數組下標的地址,數組下標是從0開始的,所以要減 1
}
//如果函數返回局部變量的值,程序是不會出錯的
//如果函數返回局部變量的地址,雖然你把地址返回了,但是地址裏的值已經被銷燬了
// 如果其他程序用了這塊內存,那麼程序執行結果將不可預估
// 作用域: 表示某個變量的作用範圍,一般在某個代碼塊了,用 {} 分隔
// 生命週期: 決定這個變量什麼時候被銷燬,靜態變量的生命週期是整個源程序
int main(int wk, int dy, char Y)
{
int a = 0;
do
{
int b = 0;
printf("Please input week and day: \n");
scanf("%d %d", &wk, &dy);
getchar();
if(wk > 5 || wk < 1 || dy > 31 || dy < 1)
{
printf("Error input! Byebye!\n");
return 0;
}
printf("The days is %d\n", *GetDay(wk, dy));
printf("If you want again, inpyt 'Y' (other for quit): \n");
scanf("%c", &Y)
}while(Y == 'Y')
printf("\n \n");
}
這個思路好棒,看來還需要加油啊!