プログラミングスキルが少しずつ向上します!
序文
今日は私が夏休み中に練習した小問を紹介したいと思います!
読んだらみんな元気になると思います!
来て!
1. エスケープ文字
次の間違った定義文は ( )
A: double x[5] = {2.0, 4.0, 6.0, 8.0, 10.0};
B: char c2[] = {'\x10', '\xa', '\8 ' };
C: char c1[] = {'1','2','3','4','5'}; D: int y[5+3]={0, 1, 3, 5
, 7、9};
質問分析:
8 進数は 0 ~ 7 で、8 はないので、選択肢 B の「\8」は間違っています
質問の答え:
B
ナレッジ ポイント メモリ: \ddd ddd は 1 ~ 3 の 8 進数を表します。文字 3 桁に
例: \130、さらに、3 桁を超える場合、または 8 進数以外の数値が見つかった場合、変換は終了し、最後の桁が直接取得されます。
詳細がわからない場合は、この人の詳細な分析を見てください:
エスケープ文字
2. 名前変更とマクロ定義
test.c ファイルには次のステートメントが含まれており、ファイル内で定義されている 4 つの変数のうち、ポインタ型の変数は [複数選択] ( ) です。
#define INT_PTR int*
typedef int* int_ptr;
INT_PTR a, b;
int_ptr c, d;
A: a B: b C: c D: d
質問分析:
#define はマクロ定義であるため、単なる直接置換です、INT_PTR a, b;
マクロ置換後のコードは次のようになります: int *a, b; ここで int * は a の型であり、 b の型は int なので、今回の b は int 型のみです。
Typedef は、型の別名を定義します。別名は独立した型です。この型を使用して作成されたすべての変数は、この型になります。
#define INT_PTR int*
typedef int* int_ptr;
int* a, b;//但是不会与后面的b结合成为整形指针
int* c, d;//c,d都是重命名之后的类型
したがって、a、c、d はポインタ型です
質問への答え:
ACD
3. 三項演算子
条件式 (M)?(a++):(a–) が与えられた場合、式 M ( )
A: および (M
0) B: および (M)と同等1) 相当
C: (M!=0) に相当
D: (M!=1) に相当
質問分析:
この式では、M=0 の場合は false、a– を計算します。M≠0 の場合は true、a++ を計算します。M と同等であることが必要な場合は、M が 0 の場合を満たさなければなりません
。 、それは false で、ゼロ以外の値の場合は True となります。
オプション c: M が 0 であると仮定すると、M は false を表します。M が 0 の場合、式 M!=0 は true ではなく false です。a– を計算します。M が 0 以外の値を取る場合、M は true となり
、式 M !=0 が成り立つ、真である、a++ を計算する; 質問の意味を満たしていれば、
質問 C を答えとして選択します:
C
知識点記憶:
(式 1)? (式 2): (式 3) ) は三項演算子です。
計算ルールは次のとおりです: 最初に式 1 が真かどうかを判断します。真の場合は式 2 を計算し、式 2 の結果を式全体の最終結果として使用します。式 3 は計算されません。そうでない場合は式
3 result は最終結果です。式 2 は評価されません
4. 日付から日への換算を計算する
質問リンク: OJ リンク
質問分析:
この質問は、最初に入力された年によってうるう年であるかどうかを判断し、
次にスイッチ関数を使用して入力された月の前の日数を追加し、
最後にこれを経過した日数を追加します。 month、これは最終的な日数です。
質疑応答:
#include <stdio.h>
int main() {
int a, b, c;
while (scanf("%d %d %d", &a, &b, &c) != EOF) {
int days=0;//统计天数
switch(b-1){
//相加输入月份之前的天数
case 11:
days+=30;
case 10:
days+=31;
case 9:
days+=30;
case 8:
days+=31;
case 7:
days+=31;
case 6:
days+=30;
case 5:
days+=31;
case 4:
days+=30;
case 3:
days+=31;
case 2:
if((a%4==0&&a%100!=0)||a%400==0){
days+=29;
}
else{
days+=28;
}
case 1:
days+=31;
case 0:
days+=c;//加上本月已过天数
}
printf("%d",days);
}
return 0;
}
知識ポイントの記憶:
うるう年の判定:
4 で割り切れるが 100 では割り切れない、
または 400 で割り切れる。
5. 文字列の長さを計算する
次のプログラムセグメントの出力結果は ( ) です。
#include<stdio.h>
int main()
{
char s[] = "\\123456\123456\t";
printf("%d\n", strlen(s));
return 0;
}
A: 12 B: 13 C: 16 D: 上記に当てはまらない
質問分析:
\\ は文字 '' を表し、\123 は文字 '{' を表し、\t はタブ文字を表します。これらはすべて 1 文字であるため、
有効な文字列長は 12 です。
質問の答え:
A
6. マクロ定義アプリケーション
以下のようなプログラムがあった場合、実行後の出力結果は( )となります。
#include <stdio.h>
#define N 2
#define M N + 1
#define NUM (M + 1) * M / 2
int main()
{
printf("%d\n", NUM);
return 0;
}
A: 4 B: 8 C: 9 D: 6
質問分析:
マクロは置き換えただけです。置き換え後の NUM は (2+1+1)*2+1/2 のようになり、8 と計算されます。
質問の答え:
B
7. const 定数
次の 3 つのプログラム コードは同じ効果を持っていますか? ( )
int b;
(1)const int *a = &b;
(2)int const *a = &b;
(3)int *const a = &b;
A: (2)=(3) B: (1)=(2) C: 全部違う D: 全部同じ
質問分析:
const が の左側にある場合、ポインタが指す変数の値はポインタを介して直接変更できません (他の方法で変更できます); の右側では、ポインタが指す変数の値は不変です。
略称は「左固定値、右方向」で、(1)(2)ではconstが の左側、(3)ではconstが右側なのでBを選択します。
質問の答え:
B
8. C言語の基礎
5. 次のステートメントの正しいステートメントは ( )
A: struct X{short s;int i;charc;} の場合、sizeof( X ) は sizeof(s) + sizeof( i ) + sizeof( c ) に等しいです。 B:
ある double 変数 a について、a == 0.0 を使用してゼロかどうかを判断できます。
C: 初期化メソッド char a[14] = “Hello, world!”; および char[14]; a = “ Hello, world!”; 効果は同じです
D: 上記の文はどれも正しくありません
質問分析:
オプション A ではメモリのアラインメントが考慮されていません。オプション B、double 型の比較を検討します。浮動小数点数の誤差のため、2 つの数値が等しいかどうかを直接判断することはできません。通常、2 つの数値の差の絶対値を比較して、等しいかどうかを確認します。非常に小さい数値より小さい (具体的には、そのような数値を自分で設定できます。 をエラーとして) 等しいかどうかを判断します。選択肢 C、a は配列の最初のアドレスであり、定数で変更できないため、A、B、C はすべて間違っています。D を選択してください。
質問の答え:
D
9. const定数(2)
次の式のうち、コンパイラによって禁止されるものはどれですか? [複数選択] ( )
int a = 248, b = 4;
int const *c = 21;
const int *d = &a;
int *const e = &b;
int const * const f = &a;
A: *c = 32; B: *d = 43 C: e=&a D: f=0x321f
質問分析:
const が * の左側にある場合、const はポインターが指す変数を変更するために使用されます (つまり、ポインターは定数を指します)。
*c と *d は変更できません。
const が * の右側にある場合、const はポインター自体を変更します。つまり、ポインター自体は定数であり、
e と f は変更できません。
質問の答え:
ABCD
10. 記号操作
次のコード スニペットの出力は ( ) です。
int main()
{
int a=3;
printf("%d\n",(a+=a-=a*a));
return 0;
}
A: -6 B: 12 C: 0 D: -12
質問分析:
a+=a-=a a はa=a+(a=aa a) と同等です。つまり、最初に a=aa a を計算します。そのため、このときの a の値は 3-3 3=-6 です。次に、-6 +(-6)=-12 を計算します。a に代入されるため、a の値は -12 となり、これが式全体の値となるため、D を選択する必要があります。
質問の答え:
D
ナレッジポイントメモリ:
11. ネガティブとポジティブを記録する
質問リンク: OJ リンク
質問分析:
実際、この質問は難しくありません。2 つの変数を記録して正と負の整数の数を記録し、変数を使用して整数の合計を計算します。最後に、計算を通じて、次のことができます。すべての負が正であることを理解します
が、この問題には大きな落とし穴があります。つまり、データがすべて 0 の場合、0 を約数として使用することはできず、-NAN が表示されるため、計算を微分する必要があります
。
質疑応答:
#include <stdio.h>
int main() {
int n = 0;
while (scanf("%d", &n) != EOF) {
// 注意 while 处理多个 case
int count1 = 0, count2 = 0, tmp;
float sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &tmp);
if (tmp < 0) {
count1++;
} else if (tmp > 0) {
sum += tmp;
count2++;
}
}
if(count2==0){
printf("%d %.1f",count1,0.0);
}
else{
printf("%d %.1f",count1,sum/count2);
}
}
return 0;
}
12. スイッチ、ケース
次のプログラムを実行するときにキーボードから ADescriptor<Enter> と入力すると、次のプログラムの実行結果は次のようになります。
#include <stdio.h>
int main()
{
char c;
int v0=0,v1=0,v2=0;
do
{
switch(c=getchar())
{
case'a':case'A':
case'e':case'E':
case'i':case'I':
case'o':case'O':
case'u':case'U':v1 += 1;
default:v0+= 1;v2+=1;
}
}while(c!='\n');
printf("v0=%d,v1=%d,v2=%d\n",v0,v1,v2);
return 0;
}
A: v0=7、v1=4、v2=7 B: v0=8、v1=4、V2=8 C: v0=11、v1=4、v2=11 D: v0=12、v1=4、v2 =12
質問分析:
コードの switch ステートメントに中断がない場合、エントリが見つかって入力されるたびに、コード ブロックの終わりまでシーケンスが実行されます。例えば、c が 'A' の場合は case 'A' から入って v1+=1; v0+=1; v2+=1; を連続実行し、c が 'p' の場合はデフォルトから入って v0+=1; を連続して実行します。 v2+=1; の場合、v0 と v2 が最終的に等しいことが簡単にわかります。
そのため、プログラム内の v0 と v2 は文字列の長さを計算し、
v1 は aeiouAEIOU 文字の出現数をカウントします。
質問回答
D
13. エラーの収集
質問リンク: OJ リンク
ヒント:
2 <= nums.length <= 10^4 ;
1 <= nums[i] <= 10^4;
質問分析:
繰り返しの数字はマーキングを使用して見つけることができます。配列内にどの数字が現れるか、対応する数字が対応する位置 1 の添字として使用され、マークされていることが示されます。データの対応する位置が設定されている場合を 1 にすると、それはただの数字の繰り返しであることを意味します。重複する数値がある場合は、[1, n] の合計を取得し、重複データを削除した配列の合計を減算して欠落データを取得します。実際、表記法を使用すると、表記法を使用したときに表示される数字の対応する桁が毎回 ++ になり、最後の 0 が失われ、2 が重複します。この方法も可能ですが、複数のトラバースが必要です。
凡例の分析:
質疑応答:
int* findErrorNums(int* nums, int numsSize, int* returnSize){
*returnSize = 2;
//遍历nums数组,将其中数据对应的位置1, 哪一位如果已经重置过则意味着数据重复了
int *arr = (int *)calloc(numsSize + 1, sizeof(int));//申请numsSize个整形空间,并初始化为0
int *ret = (int *)calloc(*returnSize, sizeof(int));//申请2个整形空间,并初始化为0
int cur_sum = 0, old_sum = 0;
for (int i = 0; i < numsSize; i++) {
if (arr[nums[i]] == 1) {
//这个数字在上边数组的对应位置已经置过1了,则重复
ret[0] = nums[i];//找到重复的数字
}
arr[nums[i]] = 1; //将标记数组的对应数据位置1
old_sum += i + 1; // 1~n的求和
cur_sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的)
}
ret[1] = old_sum - (cur_sum - ret[0]);//原始总和,减去去掉重复后的当前总和就是丢失的数字
free(arr);
return ret;
}
14. パスワードチェック
質問リンク: OJ リンクの
質問分析:
この質問では、文字列の先頭から末尾までの各文字 (大文字、小文字、数字、その他の文字) を数えるだけです。次に、条件を満たすかどうかを 1 つずつ判断します。条件の判定には、
. 長さが 8 文字以上である.
数字で始めることはできない
. 文字と数字のみを含めることができる
. 大文字と小文字の 2 種類以上が必要である
質疑応答:
#include <stdio.h>
int main() {
int n;
while (scanf("%d", &n)!=EOF) {
for(int i=0;i<n;i++){
char arr[101]={
0};
scanf("%s",arr);//捕捉输入的密码
if(strlen(arr)<8){
//密码长度小于8
printf("NO\n");
continue;
}
if(arr[0]>='0'&&arr[0]<='9'){
//密码以数字开头
printf("NO\n");
continue;
}
int upper = 0, lower = 0, digit = 0, other = 0;
char*p=arr;
while(*p!='\0'){
//统计各种字符个数
if(*p>='a'&&*p<='z')lower++;
else if(*p>='A'&&*p<='Z')upper++;
else if(*p>='0'&&*p<='9')digit++;
else other++;
p++;
}
if(other>0){
{
// 有其他字符(注意:密码只能由数字和字母组成)
printf("NO\n");
continue;
}
if((upper>0)+(lower>0)+(digit>0)<2){
//大写,小写,数字,必须具有两种以上,而比较运算真则1,假则0
printf("NO\n");
continue;
}
printf("YES\n");
}
}
return 0;
}
要約する
今回の共有はこれで終わりです!
本当に内容が盛り沢山です!
皆さんがこの記事から何かを実際に得られたことを願っています。