1. エラーを見つけます
void test1() { char string[10]; char* str1="0123456789"; strcpy(string, str1); }
ここの文字列配列は、文字列の長さが 10 で終端文字があるため、範囲外です。 \0' 。つまり、合計 11 文字の長さになります。文字列配列のサイズは 10 であり、範囲外です。
PS: strcpy 関数を使用するときは、前の宛先配列のサイズが後続の文字列のサイズよりも大きくなければならないことに注意してください。そうしないと、アクセスが範囲外になります。
void test2() { char string[10], str1[10]; for(i=0; i<10;i++) { str1[i] ='a'; } strcpy(string, str1); }
変数 i が定義されていないという一目でわかる問題がありますが、コンパイラはコードのコンパイル段階でこの問題を見つけることができ、簡単に修正できます。ただし、多くの問題は自ら引き起こした脆弱性であり、コンパイラは解決できません。ここでの最大の問題は、strcpy の 2 番目のパラメータは文字列定数である必要があるため、str1 にターミネータがないことです。この関数は、2 番目のパラメータの終了文字を使用して、コピーが完了したかどうかを判断します。したがって、for ループの後に str1p[9] = '\0' を追加する必要があります;
PS: 文字配列と文字列の最も明らかな違いは、文字列にターミネータ '\0' が追加されることです。デフォルトでは。
void test3(char* str1) { char string[10]; if(strlen(str1)<=10) { strcpy(string, str1); } }
ここでの問題はやはり一線を越えることです。 strlen 関数は、ターミネータを除いた文字列の長さを取得します。それが <=10 であれば、明らかに一線を超えていることになります。
概要: 上記の 3 つのエラー検出関数は主に、文字列と文字配列の概念の習熟と、strcpy 関数と strlen 関数の理解をテストします。
2. エラーを見つける
DSN get_SRM_no() { static int SRM_no; int I; for(I=0;I<MAX_SRM;I++) { SRM_no %= MAX_SRM; if(MY_SRM.state==IDLE) { break; } } if(I>=MAX_SRM) return (NULL_SRM); else return SRM_no; }
ここのforループの判定文は私が後から追加したもので、ネット上に流布した際に紛失した可能性があります。プログラムの解析を補足しました。間違いはここにあるべきではないと思います。
この関数を読むだけで、この関数の機能が空き SRAM ブロックを割り当てることであることが大まかに推測できます。方法: SRAM の各 RAM ブロックを最後に割り当てられた RAM ブロック以降の RAM ブロックから検出し、IDLE 状態であるかどうかを確認し、IDLE 状態であれば現在の RAM ブロック番号 SRM_no を返します。すべての RAM ブロックが IDLE 状態でない場合は、関数呼び出し元に RAM を割り当てることができないことを意味し、RAM を割り当てられないことを示すフラグ (NULL_SRM) を返します。
上記の分析後、この関数のエラーは、変数 SRM_no が for ループ内で 1 ずつ累積されないことであることがわかります。
3. プログラムの実行結果を書き込みます
int sum(int a) { auto int c=0; static int b=3; c+=1; b+=2; return(a+b+c); } void main() { int I; int a=2; for(I=0;I<5;I++) { printf("%d,", sum(a)); } }
実行結果は次のとおりです: 8,10,12,14,16,
合計sum の関数 c は auto 変数です。auto 変数の特性により、sum 関数が呼び出されるたびに、変数 c には自動的に値 0 が割り当てられます。 b は静的変数です。静的変数の特性により、sum 関数が呼び出されるたびに、変数 b は最後に sum 関数を呼び出したときに b によって保存された値を使用します。
関数を簡単に分析すると、渡されたパラメーターが変わらない場合、sum 関数が呼び出されるたびに返される結果は前回より 2 大きくなることがわかります。したがって、答えは次のようになります。 8,10,12,14,16,
4, func(1) = ?
int func(int a) { int b; switch(a) { case 1: 30; case 2: 20; case 3: 16; default: 0; } return b; }
case ステートメントで変数 b に値を代入するのを忘れている可能性があります。これを次のコードに変更すると、
int func(int a) { int b; switch(a) { case 1: b = 30; case 2: b = 20; case 3: b = 16; default: b = 0; } return b; }
case 文に Break 文が抜けているため、関数にパラメータをいくつ渡しても実行結果は 0 になります。
5. a[q - p] = ?
int a[3];
a[0]=0; a[1]=1; a[2]=2;
int * p, *q;
p=a;
q=&a[2];
それは明らかです: a[q - p] = a[2] = 2 ;
6. メモリ空間占有の問題
define int **a[3][4] の場合、変数が占有するメモリ空間は 24 in 16 となります。 -bit システム。32 ビット コンパイル システムでは 48 です。
PS: 式: 3 * 4 * sizeof(int **)。
7. プログラミング
年、月、日、時、分、秒の入力を必要とし、その次の秒を出力する関数を作成します。年、月、日、時、分、秒。たとえば、2004 年 12 月 31 日の 23:59:59 と入力すると、出力は 2005 年 1 月 1 日の 0:00:0 となります。
void ResetTheTime(int *year,int *month,int *date,int *hour,int *minute,int*second) { int dayOfMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31}; if( *year < 0 || *month < 1 || *month > 12 || *date < 1 || *date > 31 || *hour < 0 || *hour > 23 || *minute < 0 ||*minute > 59|| *second <0 || *second >60 ) return; if( *year%400 == 0 || *year%100 != 0 && *year%4 == 0 ) dayOfMonth[1] = 29; if(*second >= 60) { *second = 0; *minute += 1; if(*minute >= 60) { *minute = 0; *hour += 1; if(*hour >= 24) { *hour = 0; *date += 1; if(*date > dayOfMonth[*month-1]) { *date = 1; *month += 1; if(*month > 12) { *month=1; *year += 1; } } } } } return; }
推奨: 「c 言語チュートリアル 」
以上がC言語に関するHuaweiの面接でよくある7つの質問(共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。