【面试题三】c数组做为参数退化的问题,二维数组中的查找

一,c数组做为参数退化的问题

1.c/c++没有记录数组的大小,因此用指针访问数组中的元素的时候,我们要确保没有超过数组的边界,

通过下面的程序了解数组与指针的区别。

array.c:

#include <stdio.h>
#include <string.h>

int GetSize(int data[])
{
	return sizeof(data);
}

int main()
{
	int data1[] = {1, 2, 3, 4, 5};
	/*data1是一个数组*/
	int size1 = sizeof(data1);

	int* data2 = data1;
	/*data2是一个指针,经管他指向了数组data1的第一个数字,但他的本质任然是一个指针*/
	int size2 = sizeof(data2);

	/*在C/C++中,当数组做为函数的参数进行传递时,数组自动退化为同类型的指针*/
	int size3 = GetSize(data1);

	printf("%d, %d, %d\n", size1, size2, size3);
	return 0;
}

Makefile:

.PHONY:clean
CC=gcc
CFLAGS=-Wall -g
BIN=test
OBJS=array.o
LIBS=
$(BIN):$(OBJS)
	$(CC) $(CFLAGS) $^ -o $@ $(LIBS)
%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@
clean:
	rm -f *.o $(BIN)

结果:

20, 4, 4


二,二维数组中的查找


a < 0; a = 0 ; a > 0;这个是微积分基本定理;这个很重要!!!

二维数组,每行每列都是递增排序,给你个数字,判断这个数字是不是这个二维数组当中的。


与数组的右上角的数字进行比较,如果大于这个右上角的数字,剔除这一行;如果小于这个右上角的数字,剔除这一列;

这样子每一次比较范围就减少了一行或者一列,知道找到最终的位置或者遍历结束没有找到这个数字;

其实我们也可以选取左下角的那个数字做为比较的“轴”;

但是不能够选择左上角和右下角,这两个位置不能够每次遍历消除一行或者一列;


DouArr.cpp:

#include <iostream>
#include <stdio.h>

using namespace std;

/*bool是标准C++数据类型,可取值true和false。单独占一个字节,*/
bool Find(int* matrix, int rows, int columns, int number)
{
	bool found = false;

	if(matrix != NULL && rows > 0 && columns > 0)
	{
		/*初始化第一次右上角的坐标位置--记得在循环中更新这两个坐标*/
		int row = 0;
		int column = columns - 1;

		/*循环的过程中row区域rows,column趋于0*/
		while(row < rows && column >= 0)
		{

			/*C/C++二维数组是可以这么搞的,因为二维数组在内存中占据连续的内存空间,千万不要用java这么搞*/
                        /*在内存中从上倒下存储各行元素,在同一行中按照从左到右的顺序存储。根据行号和列好计算出相对于数组首地址的偏移量,从而找到对应元素*/
                        if (matrix[row * columns + column] == number)
			{
				found = true;
				break;
			}
			else if(matrix[row * columns + column] > number)
			{
				-- column;
			}
			else
			{
				++ row;
			}
		}
	}

	return found;
}


// ====================测试代码====================
void Test(char* testName, int* matrix, int rows, int columns, int number)
{
    if(testName != NULL)
        printf("%s begins: ", testName);

    bool result = Find(matrix, rows, columns, number);
    if(result == true)
    {
    	cout<<"Find it!"<<endl;
    }
    else
    {
    	cout<<"No find it!"<<endl;
    }
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数在数组中
void Test1()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test1", (int*)matrix, 4, 4, 7);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数不在数组中
void Test2()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test2", (int*)matrix, 4, 4, 5);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数是数组中最小的数字
void Test3()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test3", (int*)matrix, 4, 4, 1);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数是数组中最大的数字
void Test4()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test4", (int*)matrix, 4, 4, 15);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数比数组中最小的数字还小
void Test5()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test5", (int*)matrix, 4, 4, 0);
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的数比数组中最大的数字还大
void Test6()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    Test("Test6", (int*)matrix, 4, 4, 16);
}

// 鲁棒性测试,输入空指针
void Test7()
{
    Test("Test7", NULL, 0, 0, 16);
}


int main()
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
    Test7();
	return 0;
}

Makefile:

.PHONY:clean
CPP=g++
CFLAGS=-Wall -g
BIN=test
OBJS=DouArr.o
LIBS=
$(BIN):$(OBJS)
	$(CPP) $(CFLAGS) $^ -o $@ $(LIBS)
%.o:%.cpp
	$(CPP) $(CFLAGS) -c $< -o $@
clean:
	rm -f *.o $(BIN)

运行结果:

Test1 begins: Find it!
Test2 begins: No find it!
Test3 begins: Find it!
Test4 begins: Find it!
Test5 begins: No find it!
Test6 begins: No find it!
Test7 begins: No find it!




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值