c基础常见笔试题

c基础常见笔试题

1.gcc编译器编译的四个流程

预处理 、编译 、汇编 、链接

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.当同一个程序分别使用静态库,动态库两种方式生成两个可执行文件时,静态链接所生成的文件所占用的内存要远远大于动态链接所生成的文件

e.内存上:静态库每一次编译都需要载入静态库代码,内存开销大;系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,内存开销小

f.静态库和程序链接有关和程序运行无关;动态库和程序链接无关和程序运行有关

3.用变量a定义如下类型的变量

(1)一个整形数

(2)一个指向整形数的指针

(3)一个指向指针的指针,被指向的指针指向一个整形数

(4)一个有十个整形数的数组

(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(a
b) 应写成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语句中。

continue :结束本次循环,接着判定下一次是否执行循环。

return :退出一个函数,或者获取函数的返回值。main函数的返回值传递给系统。

exit():结束一个进程,传入的参数完全由编程人员自己决定。(系统中默认正常执行的函数返回0)

9.什么是数组?其存储有何特点?

数组元素是组成数组的基本单元,同一数组中的数据元素必须具有相同的数据类型,数组元素由“数组名”和下标来标识数组是有序数据组合,有序是指系统在存放的时候会为数据元素分配一段连续的存储空间,数组元素在这段空间内按照先后顺序进行存放。

10. 字符串和字符数组有什么区别?

严格来讲,字符数组强调数组是多个个体的集合,字符串是由多个个体构成的一个整体作为整体操作的字符串,能作为整体的基础是因为他的最后有一个结束标志“\0”,因此可以说有结束标志的一维字符数组就是字符串,C语言中没有字符串这种数据类型,它是由一维字符数组加上结束标志构成的。

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:源的字符数组
返回值:
同最终的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 = &ic;
d. int *const cpi = &ic;

猜你喜欢

转载自blog.csdn.net/weixin_48430195/article/details/108737849