C语言---面试之数据类型篇

Posted 今天天气眞好

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言---面试之数据类型篇相关的知识,希望对你有一定的参考价值。

1.用变量a给出下列定义
(1)一个整型数:int a;

(2)一个指向整型数的指针(一重指针):int* a;

(3)一个指向指针的指针,他指向的指针是指向一个整型数的指针(二重指针):int **a;

(4)一个有10个整型数的数组:int a[10];

(5)一个有10个指针的数组,这10个指针是指向整型数的(指针数组):int* a[10];

(6)一个指向有10个整形数数组的指针(数组指针):int (*a)[10];

(7)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(函数指针):int *a(int)

(8)一个有10个指针的数组,这10个指针均指向函数,该函数有一个整型参数并返回一个整型数(函数指针数组):int (*a[10])(int)

2.下面代码输出是什么,为什么?

void foo(void)
{
	unsigned int a = 6;
	int b = -20;
	(a+b>6)?printf(">6"):printf("<=6");
}

答案:输出结果为“>6”
解读:当运算符中存在有符号数和无符号数的时候,有符号数隐式转换成了无符号数(即底层的代码不变,但是此数从有符号数变成了无符号数)。注意,正数的补码为其本身,负数的补码是其反码加1,因此-20变成了一个非常大的正数,所以最后相加结果肯定“>6”。

3.写出float与"零值"比较的if函数
答案:if(x>=-0.000001 && x<=0.000001);
解读:因为计算机在处理浮点数的时候是有误差的,因此不能将浮点型变量用“==”或者“!=”来与数字进行比较,应该设法转换成“>”或者"<"此类形式。同时注意float的有效数字为6~7位。

4.下面代码有什么错误?

#include <stdio.h>
void main()
{
	char *s = "AAA";
	s[0] = 'B';
	printf("%s",s);
}

答案:
(1)“AAA”是字符串常量,s是指针,指向这个字符串常量,所以申明s的时候就有问题,应该加上const。
(2)因为是常量,所以对s[0]的赋值操作是不合法的。

5.下面代码输出什么?

void main()
{
	int *a = (int *)2;
	printf("%d",a+3);
}

答案:14
解读:代码将数值2强制类型转换为int *类型指针,int指针类型加3相当于指针后面第三个int类型变量的首地址,int类型变量占用4字节,所以加3相当于指针往后移动了12个字节,指向地址14处。

6.下面代码运行后会是什么现象?

#include <stdio.h>
#define N 500
void main()
{
	unsigned char count;
	for(count=0;count<N;count++)
	{
		printf("--%d--\\n",count);
	}
}

答案:进入不断打印count值的死循环
解读:因为unsigned char类型的变量最大值为255,所以count只能从0一直增加到255,然后又恢复为0,无法退出for循环。

7.下面函数的返回值是?

int foo(void)
{
	int i;
	char c = 0x80;
	i = c;
	if(i > 0)
		return 1;
	return 2;
}

答案:返回值为2
解读:因为0x80 == 128,超过了char类型变量c的表示范围(-128~127),所以c == -128,进而i == -128,i < 0.

8.结构体内存对齐原则是?
答案:
(1)第一个成员的首地址(地址偏移量)为0

(2)成员对齐:以4字节为例,如果自身类型小于4字节,则该成员的首地址是自身类型大小的整数倍。如果自身类型大于等于4字节,则该成员的首地址是4的整数倍。若内嵌结构体,则内嵌结构体的首地址也要对齐,只不过自身类型大小用内嵌结构体的最大成员类型大小来表示。数组可以看成拆分为n个数组元素,不用整体看作一个类型。

(3)最后结构体总总体补齐:以4字节对齐为例,如果结构体的最大类型成员小于4字节,则大小补齐为结构体中最大成员类型大小的整数倍;如果大于等于4字节,则大小补齐为4的整数倍。内嵌结构体也要补齐。

注意:32位编译器,一般默认对齐方式是4字节。

9.结构体内存对齐的原因?
(1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据
(2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐,因为访问未对齐的内存,处理器需要做两次内存访问,而访问对齐的内存仅需要一次。

如下图所示,访问对齐的short变量只需要一次,而访问未对齐的int变量则需要访问两次
在这里插入图片描述

10.结构体内存分配的原则?
(1)结构体中元素按照定义顺序存放在内存中,但并不是紧密排列。从结构体存储的首地址开始,每一个元素存入内存的时候,他都会认为内存是以自己的宽度来划分空间的,因此元素存放的位置一定是以自己的宽度来划分空间的。
(2)在原则一的基础上,检查计算出的存储单元是否为所有元素中最宽的元素长度的整数倍。若是,则结束;若不是,则将其补齐为他的整数倍。

11.在32位操作系统中,有如下结构体,那么sizeof(fun)的数值为?

#pargma pack(1)
struct fun
{
	int i;	4字节
	double d;	8字节
	char c;	1字节
};

答案:sizeof(fun)得到的结果为13
解读:因为预处理语句“#pargma pack(1)”将编译器的字节对齐改为1了,根据结构体内存对齐原则,共占用13字节

12.数组首元素地址与数组地址的异同?
(1):不同的概念,举个例子:int a[10]
a的值是数组首元素的地址,所以a+1就是第二个元素的地址,int类型占用4字节,所以两者相差4,。而&a是数组地址,所以&a+1就是向后移动(10*4)个单位,所以两者相差40。

(2):数组首地址和数组地址的值是相等的。

13.下面代码输出什么?

#include <stdio.h>
void main()
{
	int a[5] = {1,2,3,4,5};
	int *p = (int *)(&a + 1);
	printf("%d %d",*(a+1),*(p-1));
}

答案:输出:2 , 5
解读:
a是数组首元素地址,所以*(a+1)就是第二个元素a[1],即2
&a是数组地址,所以&a+1就是整个数组结尾的下一个地址,*(p-1)就是a[4],即5

14.判断下列表达式正确与否?
(1)char str[2][3] = {"a","b"};
正确,str是一个可存放两个字符串的字符串数组

(2)char str[2][3] = {{1,2},{3,4},{5,6}};
错误,行列不匹配

(3)char str[] = {"a","b"}
错误,字符数组不能存放字符串

(4)char str[2] = {"a","b"}
错误,字符数组不能存放字符串

注意:C语言中字符用' '括起来,而字符串用“”括起来

15.查看下列代码,p[6]等于?

int a[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = &a[1];

答案:等于8
解读:p是一个int类型的指针,指向a[1],p[6]表示p往后移动了6个单位(每个单位占据4字节)并解引用,因此p[6] = 8。

16.下面代码的输出结果为?

#include <stdio.h>
void main()
{
	char *str[] = {"ab","cd","ef"."gh","ij","kl"};	//指针数组
	char *t;
	t = (str + 4)[-1];
	printf("%s",t);
}

结果:输出“gh
解读:str表示数组首元素地址,str + 4表示数组第五个元素地址,(str + 4)[-1]表示在第五个元素地址的基础上往前移动一个元素并解引用,因此输出的是第四个元素。

17.变长数组是什么?
在C99标准中,允许定义数组时[]中的值是整型变量或者整型表达式,比如下面这个例子:

void main()
{
	int n;
	scanf("%d",&n);
	int arr[n];
}

18.bool类型包含在哪个头文件中?
答案:stdbool.h

19.结构体struct和联合体union的区别?
(1)两者最大的区别在于内存的使用
(2)结构体各成员拥有自己的内存,各自使用且互不干涉,遵循内存对齐原则;联合体所有成员公用一块内存,并且同时只能有一个成员可以得到这个内存的使用权。一个联合体变量的总长度至少能够容纳最大的成员变量,且需要进行内存补齐。

20.执行完下列代码,c的值为多少?

unsigned int a = 1;
int b = 0;
int c = 0;
c = a + b > 0 ? 1 : 2;

答案:c的值为1
解读:有符号数和无符号数一起运算时候,有符号数转换为无符号数。有符号数int b = 0在内存中的补码是0,因此转换为无符号数之后任然是0,a+b==1>0,因此c = 1.

以上是关于C语言---面试之数据类型篇的主要内容,如果未能解决你的问题,请参考以下文章

[C/C++笔试面试题] 程序设计基础 - 位操作函数数组篇

如何系统学习C 语言(中)之 数组篇

T4模板:T4模板之菜鸟篇

Python基础之变量,常量,注释,数据类型

面向面试编程代码片段之GC

前端面试题之手写promise