C面经——基础部分

1、计算机内部的内存单位换算

	1G = 2^10 M = 2 ^ 20 K = 2 ^30 B
	1B = 8bit
	例:100万个整形数据占多大?
	答:1M

2、fwrite函数的参数是什么?

答:int fwirte(const void *ptr,int size,inr count,FILE * stream)
		ptr:指向保存数据的指针
		size:每个数据类型的大小
		count:数据个数
		stream:文件指针
	扩展:给定一个文件,如何计算文件的大小?提示:使用fseek和ftell
#include
#include
int main()
{
	FILE *p;
	int len;
	P = fopen("xxxx.xxxx","r");
	assert(p != NULL);
	fseek(p,0,SEEK_SET);
	len = ftell(p);
	printf("%d",len);
	return 0;
};

3、extern关键字的作用

在一个文件中引用另一个文件的变量或者函数
在C++语言中穿插C语言就需要使用extern “C”{}将代码括起来

4、malloc,calloc,realloc的作用和区别

  1. C语言动态开辟内存有三个函数,分别是malloc,calloc,realloc,释放内存的只有一个函数free
  2. malloc是使用最多也是最简单的,只需要一个参数(开辟内存空间的大小),如果堆内有连续空间可以满足用户需求,则返回内存首地址,否则返回NULL;
  3. calloc实在malloc的基础上将分配好的每个字节赋值为0;
  4. realloc函数之前开辟的储存空间改变为给定的大小size。 size可以是任意大小,大于或小于原尺寸都可以。
    返回值是指向新空间的指针,如果错误发生返回NULL。

(重点)开辟空间之后一定要free释放,否则会导致内存泄漏问题

5、strcpy为什么不安全?(西安诺瓦科技)

因为如果被拷贝字符串长度大于“空”字符串的长度的话会造成月结问题,所以说是不安全的。
因此使用strcpy_s(const char * p1,sizof(p2),const char *p2)函数

6、大小端问题

小端:低地址存放低字节数据
大端:低地址存放高字节数据

例:如何测试大小端?
方法有很多:可以使用指针偏移,可以使用联合体等

bool is_big()
{
	short int a = 0x1234;
	char b = (char)a;
	if(b == 0x12)
	{
		return true;
	}
	return false;
};


bool is_big()
{
	union num
	{
	 	int a;
	 	char b;
	 }:
	 num p.a = 0x1234;
	 if(p.b == 0x12)
	 {
	 	return true;
	 }
	 return false;
};
*
	 

7、二分查找

二分查找也称为折半查找,二分查找的前提是数据必须有序!!!
有重复的数字返回其左边的数据

//非递归方式
int BinSearch(int *arr,int left,int last,int val)
{
//left左位置下标 last右位置下标
	assert(arr != NULL);
	
	while(left <= right)
	{
		int order =(ringht + left) / 2;
		if(arr[order] == val)
		{
			if(arr[order - 1] = val) order -= 1;
			return order;
		}
		if(arr[order] > val)
		{
			left = order;
		}
		if(arr[order] < val)
		{
			right = order;
		}
	}
	return -1;	
}

	

8、static关键字的用法和作用

static主要是定义全局静态变量,定义局部静态变量,定义静态函数。
一、定义静态变量:在全局变量前面加上static关键字
特点:1、如果初始化且初始化不为0的在.data分配内存,如果没有初始化或者初始化为0的在.bss存储
2、如果没有初始化,其默认值为0
3、该变量在本文件定义到文件结束可见
二、定义静态函数;在函数返回值类型加上static关键字,函数即被定义成静态函数。
特点:1、静态函数只能在本文件中使用
2、在文件作用域中声明的inline函数默认为static
3、在C++中,静态成员方法与类相联系,不依赖对象调用。静态成员函数不能访问非静态数据成员。
4、静态成员函数和静态成员都没有this指针。
在《C深度剖析》中有一道很经典的题
C面经——基础部分_第1张图片
问i和j的值分别是多少?

9、括号匹配问题(深信服)

使用栈从左到右依次入栈,当入栈第一个右括号的时候找到距离栈顶最近的第一个左括号与其匹配,然后将两个括号之间的所有元素或者符号出栈。

10、魔方阵

魔方阵,是指元素为自然数1、2、3、4…n^2的n*n的仿真,其中无重复元素,且每行、每列以及主、副对角线上个n个元素之间的和相等
奇数魔方阵构造算法描述如下:
1、数字1方阵第一行中间。
2、当数字放在前一个数字的上一行,后一列,注意如果已经到顶行则上一行为最后一行即把线性看着环形
3、如果当前位置有已经有数据,则放在前一个数字的下一行,同列

#define N 15
#define M N
void MagicMatrix()
{
	int arr[N][M] = {0};
	assert(N % 2 != 0);
	int curn = 0;
	int curm = curn / 2;
	arr[curn][curm] = 1;
	for(int i = 2;i < M * N;++i)
	{
		curn--;
		if(curn < 0)
		{
			curn = N - 1;
		}
		curm = (curm + 1) % N;
		if(arr[curn][curm] != 0)
		{
			curn = (curn + 2) % N;
			curm = (curm - 1 + M) % M;
		}
		arr[curn][curm] = i;
	}
}

11、翻转句子中的单词顺序,但是单词内字符顺序不变

void str_reverse(char *start,char *end)
{
	char temp;
	while(start < end)
	{
		temp = *start;
		*start = *end;
		*end = temp;
		start++;
		end--:
	}
}
char* str_reverse(char *sen)
{
	char *start = sen;
	char *end = sen + sizeof(sen) - 1;
	str_reverse(start,end);//先反转所有句子,包括单词
	end = start;
	while(*start != '\0');
	{
		if(*end == ' ' || *end == '\0')
		{
			str_reverse(start,end - 1);
			if(*end == '\0')break;
			end += 1;
			start = end;
		}
		else
		{
			++end;
		}
	}
	return sen;
}
	
int main()
{
	char str[] = "hello,i am a student!";
	char *res = str_reverse(str);
	printf("%s\n",res);
	return 0;
}

12、指针和数组的区别

1、大小不同,在32位系统下是四个字节,数组大小为数组长度*sizeof(数组单元格):sizeof(arr) / sizeof(arr[0].
2、访问权限不同,数组arr指向的永远是数组的开头元素不能移动,指针可以发生移动
3、访问方式不同,arr[i] 是在数组名后面偏移i个单元格,然后取值,而p[i]是先将p的值加上i然后再跳转地址取值。

13、循环数组

环形数组在遍历完最后一个下标后不结束,而是将数组的第一个元素作为最后一个元素的下一个
约瑟夫环

#define NUM 3
int joseph(int n)
{
	assert(n > 0);
	int *arr = (int *)malloc(n * sizeof(int));
	int i = 0 ;
	int count = n;
	int tmp = 0;
	for(i = 0;i < n;i++)
	{
		arr[i] = 1;
	}
	i = 0;
	while(count > 1)
	{
		if(arr[i] == 1)
		{
			tmp++;
			if(tmp == NUM)
			{
				arr[i] = 0;
				tmp = 0;
				count--;
			}
		}
		i++;
		if(i == n)
		{
			i = 0
		}
	}
	for(i = 0;i < n;i++)
	{
		if(arr[i] ==1)
		{
			break;
		}
	}
	free(arr);
}
int main()
{
	printf("%d\n",joseph(1));
	printf("%d\n",joseph(2));
	printf("%d\n",joseph(3));
	printf("%d\n",joseph(4));
	return 0;
}

14、数字判断(葡萄城)

题目描述: 判断一个字符串是否是一个十进制数字 。

题目要求:

  1. 不允许使用正则或者框架或者第三方提供的判断数字的方法。需要自行实现判断逻辑
  2. 需要支持用科学计数法表示的数字

示例:

以下字符串是合法的十进制数字:
0
123
1.23
-123
1.23E+10
以下字符串是不合法的十进制数字:
000
123abc
.123
0.1.2

/*
示例类型展示不太齐全:"01"是否属于十进制范畴,在下述代码中将其视为非十进制数
*/
#define MAXINT 2147483647
bool  Str_Dec(const char *str)
{
	long long max = 0;
	bool res = true;
	int tag1 = 0;//小数点标志位
	int tag2 = 0;//科学计数标志位
	while ('\0' != *str)
	{
		if (isdigit(*str))
		{

			++str;
		}
		else
		{
			if (*str == '.' && tag1 == 0)
			{
				str++;
				tag1++;
				continue;
			}
			else
			{
				if ((*str == 'e' || *str == 'E') && (*(str + 1) == '-' || *(str + 1) == '+') && tag2 == 0)
				{
					str += 2;
					tag2++;
					continue;
				}
				else
				{
					res = false;
					return res;
				}
			}
		}
	}
	return res;
}
bool judge(const char *str)
{
	int res = false;
	if (!isdigit(*str))
	{
		if (*str == '+' || *str == '-')
		{
			str++;
			res = Str_Dec(str);
		}
		return res;
	}
	else
	{
		if (*str == '0' && *(str + 1) == '\0')
		{
			res = false;
			return res;
		}
		res = Str_Dec(str);;
	}
	return res;
}
int main()
{
	const char *ptr = "0100.0.0000004";
	bool res = judge(ptr);
	if (res == false)
	{
		printf("字符串:%s不是十进制数字", ptr);
	}
	else
	{
		printf("字符串:%s是十进制数字", ptr);
	}
	return 0;
}

15、杨辉三角

题目5:杨辉三角
编程语言:不限

题目描述: 杨辉三角是我国古代一个重要的数学成就 。
杨辉三角是一个满足以下条件的几何排列:

  1. 每个数等于它上方两数之和。
  2. 每行数字左右对称,由1开始逐渐变大。
    第 n 行的数字有 n 项。
    请编写一个程序,按题目要求输出杨辉三角中第 n 行第 m 个数字。
    输入
    第一行,两个数字 n 和 m ,表示需要输出的数字在杨辉三角上的位置,行列均从 1 开始,(1<=n,m<=10000),以空格分隔。
    输出
    仅包含一个整数,即杨辉三角中第 n 行第 m 列处的数字。
    输入示例
    7 5
    输出示例
    15
    题解:除了前两行每一行都遵循一定的规律,故用递归。



int triangle(int n, int m)
{
	if (n == m || m == 1)
	{
		return 1;
	}
	return triangle(n - 1, m - 1) + triangle(n - 1, m);
}
int main()
{
	int n, m;
	while (cin >> n >> m, (n > 0 && m > 0))
	{
			cout << triangle(n, m) << endl;
	}
	return 0;
}

你可能感兴趣的:(c语言,面试)