c一般的な筆記試験の一般的な質問
1. gccコンパイラーのコンパイルの4つのプロセス
前処理、コンパイル、アセンブリ、リンク
gcc –E hello.c –o hello.i
gcc –S hello.i –o hello.s
gcc –c hello.s –o hello.o
gcc hello.o –o hello
2.静的ライブラリと動的ライブラリ
違い
a。命名:静的ライブラリファイル名の命名方法は「libxxx.a」、ライブラリ名の接頭辞は「lib」、接尾辞は.a "、および「xxx」は静的ライブラリ名です。動的ライブラリの命名方法は静的ライブラリに似ています。 、プレフィックスは「lib」と同じで、サフィックスは「.so」になります。「libmytime.so」
b。リンク:静的ライブラリのコードはコンパイルプロセス中にプログラムに読み込まれます。動的ライブラリはコンパイル時にターゲットコードにコンパイルされませんが、プログラムが関連する関数を実行すると関数ライブラリが呼び出されます対応する関数
c。更新:使用される静的ライブラリが更新および変更された場合、プログラムを再コンパイルする必要があります。動的ライブラリの変更はプログラムに影響を与えず、動的関数ライブラリのアップグレードがより便利です
d。同じプログラムが静的ライブラリと動的ライブラリを使用して2つの実行可能ファイルを生成する場合、静的リンクによって生成されたファイルが占めるメモリは、動的リンクによって生成されたファイルよりもはるかに大きくなります。
e。メモリ上:静的ライブラリコードは、静的ライブラリをコンパイルするたびにロードする必要があります。これにより、メモリオーバーヘッドが高くなります。システムは動的ライブラリを一度ロードするだけでよく、異なるプログラムは、メモリオーバーヘッドの少ない同じ動的ライブラリのコピーをメモリに取得できます。
f。静的ライブラリはプログラムリンクに関連し、実行中のプログラムとは関係ありません。動的ライブラリとプログラムリンクは実行中のプログラムに関連していません。
3.変数aを使用して、次のタイプの変数を定義します
(1)整数
(2)整数へのポインタ
(3)ポインターへのポインター、ポイントされたポインターは整数を指す
(4)10個の整数の配列
(5)10個のポインタを持つ配列。配列要素は整数を指します
(6)10個の整数の配列へのポインター
(7)整数パラメータを持ち、整数を返す関数へのポインタ
(8)10個のポインターを持つ配列、配列メンバーは関数を指し、関数は整数パラメーターを持ち、整数を返します
回答:
(1)int a;
(2)int * a;
(3)int ** a;
(4)int a [10];
(5)int * a [10];
(6)int(* a)[10];
(7)int(* a)(int);
(8)int(* a [10])(int);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dP7bvcnW-1600769219290)(D:\work\主题串讲\图片\运算符优先级.jpg)]
4. x=x+1 , x+=1 , x++ 哪个效率高?
x=x+1 先读取等号右边的x的地址,计算x+1的值,然后读取等号左边的x地址,最后将等号右边的值传递给等号左边的值
x+=1 读取等号右边的x的地址,计算x+1的值,将得到的值传给左边的x,之前已读过,故省去传值的过程
x++ 读取x的地址,然后x自增1
X++ 的效率最高
5. 浮点数的相等比较是否可以用“==”
不可以,因为计算机中的数都是用二进制表示的,大部分十进制小数对应的二进制小数是无限小数,也就是说,计算机可以精确表示整数,但不能精确表示小数,
if(a3)应写成if(fabs(a-3)<le-6)
if(ab) 应写成f(fabs(a-b)<le-6)
fabs是求绝对值的函数,le-6是0.000001
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hDvVxvlP-1600769219307)(D:\work\主题串讲\图片\浮点数表示方法.png)]
6.请写出 float x 与“零值”比较的 if 语句
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON))
7. do … while
宏函数的定义一定要封闭地包含在do { … } while (0)中
#define macrofun(a, b, c) \
do { \
if (a == 5) \
do_this(b, c); \
} while(0)
摘自Linux3.14内核源码中的Codingstylec
8. break 、continue 、return 和 exit()
break :用于从循环体内跳出循环体,即提前结束循环。break只能用在循环语句和switch语句中。
続行:このサイクルを終了し、次にサイクルを実行するかどうかを決定します。
return:関数を終了するか、関数の戻り値を取得します。メイン関数の戻り値はシステムに渡されます。
exit():プロセスを終了します。渡されるパラメーターはプログラマーによって完全に決定されます。(システムで通常実行されるデフォルト関数は0を返します)
9.アレイとは何ですか?その保管の特徴は何ですか?
配列要素は、配列を構成する基本単位です。同じ配列内のデータ要素は、同じデータ型である必要があります。配列要素は、配列を順序付けられたデータの組み合わせとして識別するための「配列名」と添え字で識別されます。順序とは、システムが保存される時間を指しますデータ要素には連続した記憶領域が割り当てられ、配列要素はこの領域に順番に格納されます。
10.文字列と文字配列の違いは何ですか?
文字配列は厳密に言えば、配列が複数の個体の集まりであることを強調しています。文字列は、全体として複数の個体から構成される文字列です。末尾にエンドマーク「\ 0」があるため、全体として使用できます。 」のように、終了マーク付きの1次元文字配列は文字列と言えます。C言語には文字列などのデータ型はありません。1次元文字配列と終了マークで構成されます。
11.文字列関数と実装
#include <string.h>
size_t strlen(const char * s);
機能:文字列の長さを計算します
パラメーター:
s:文字配列
戻り値: '\ 0'を除いた文字列の実際の長さを返します
//自己实现
int my_strlen(const char *s)
{
char * sc;
for (sc = s; *sc != '\0'; ++sc);
return sc - s;
}
#include <string.h>
char * strcpy(char * dest、const char * src);
関数:srcのデータをdestにコピーします
パラメーター:
dest:ターゲット文字配列
src:ソース文字配列
戻り値:
コピー文字配列
注:dest文字配列1は
接続前に十分な大きさである必要があります。両方の文字列は '\ 0'で終わります。接続後、destの '\ 0'はキャンセルされ、新しい文字列は '\ 0'で終わりに追加されます
//自己实现
char *my_strcpy(char *dest, const char *src)
{
int i=0;
while(src[i] != '\0')
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
return dest;
}
#include <string.h>
char * strcat(char * dest、const char * src);
関数:srcのデータをdestの後ろに追加します
パラメーター:
dest:ターゲット文字配列
src:ソース文字配列
戻り値:
finalと同じdestの
説明:
文字配列1は
接続前に十分な大きさである必要があります。両方の文字列は '\ 0'で終了します。接続後、文字列1の '\ 0'はキャンセルされ、新しい文字列は最後に '\ 0'が追加されます
//自己实现
char *strcat(char *dest, const char *src)
{
int i = 0, j = 0;
while(dest[i] != '\0'){
i++;
}
while(src[j] != '\0'){
dest[i++] = src[j++];
}
dest[i] = '\0';
return dest;
}
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:比较两个字符串的大小
返回值:
若字符串1< 字符串2, 返回负整数
若字符串1> 字符串2, 返回正整数
若字符串1== 字符串2, 返回零
说明:
对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或‘\0’为止
字符串比较不能用“==”,必须用strcmp
//自己实现
int my_strcmp (const char *s1, const char *s2)
{
int ret;
while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++);
return ret;
}
12.如何用指针表示多维数组
a是二维数组名,a代表整个二维数组的首地址
a+i、a[i]、*(a+i)、&a[i][0]是等同的(%p打印出来的数值是相同的)
a[i]+j=(*(a+i)+j)该元素的值等于*(*(a+i)+j)
13.二级指针如何应用于一维数组?
int a=[10],*p1,**p2,i;
p1=a;
p2=&p1;
a[i]=*(*p2+i)= *(p1+i)=*(a+i)
14.什么是形参和实参?如何使用
函数名后面括号中的变量名就是“形式参数”(简称形参)
实参就是在主调函数中调用一个函数时,函数名后面括号中的参数
形参出现在函数定义中,在整个函数体中都可以使用,离开该函数则不能使用。
实参出现在主函数调用中,进入被调函数后,实参变量也不能使用。
函数形参和实参特点:
(1) 形参变量只有在被调用时才分配内存单元,在调用结束时将释放所分配的内存单元。
(2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用之前,每个实参都必须具有确定的值,以便把这些值传递给形参,因此,应预先用赋值、输入等方法使实参获得确定值。
15.请问运行Test 函数会有什么样的结果
//题目
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(“%s\n”,str);
}
答案:
Segmentation fault (core dumped)
//修改
void GetMemory(char **p)
{
*p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(“%s\n”,str);
}
16.以下语句哪个是非法语句,(D)
A . int i = 1;
b. const int ic = i;
c. const int *pic = ⁣
d. int *const cpi = ⁣