关于数据结构课上的一些错误9.27

  1. C++ main() 函数的返回值问题
  2. C语言函数的传参方式
  3. 一些写法问题

怕查水表,有些话就略了

C++ main() 函数的返回值问题

这个问题我曾在不止一位老师的课件上见过了,只能说在C语言中,C89时代,void main() 是可以接受的,但是自从C99开始,标准规定只有以下两种定义方式是正确的:

1
2
int main(void)
int main(int argc,char* argv[])

然而在C++中,这种写法是根本不被允许的.C++ 之父Bjarne Stroustrup 在他的主页上的 FAQ 中明确地写着

C语言函数的传参方式

C语言中函数传参只有值传递一种方式.因此不管是传一个指针还是一个变量,其本质都是给函数传递一份参数的副本.也就是函数对这个副本进行修改并不会影响程序实际传给它的参数.

很经典的一个例子是swap函数,交换两个变量的值.

1
2
3
4
5
6
void swap(int a,int b) {
int temp = a;
a = b;
b = temp;
return ;
}

上述程序是错误的,如果是新手,往往会觉得这个逻辑没有问题,但是问题就在于值传递,在这个函数执行的过程中,a,b都是传入了一份拷贝,因此最终只是修改了拷贝的值,而并未影响到真实的a,b的值.

为了成功实现这个功能,C语言中可以使用指针.

1
2
3
4
5
6
void swap(int* a,int* b) {
int temp = *a;
*a = *b;
*b = temp;
return ;
}

那上述程序执行的过程中依然是值传递,但这个不一样的地方在于传入了两个变量的地址,然后通过间接操作两个变量的内存实现了两个变量值的交换.

今天上课则举出了这样一个例子:

1
2
3
4
5
6
void swap(int* a,int* b) {
int* temp = a;
a = b;
b = temp;
return ;
}

这个很显然也是无法实现该功能的,那么这么牵扯出一个问题,如果要在函数中修改函数外的指针,那么需要用指针的指针或者指针的引用.

一些写法问题

我记得上课老师课件上有一段判断线性表是否为空的代码,原代码是这么写的

1
2
3
4
5
6
7
bool IsEmpty(List l) {
if(l -> length == 0) {
return true;
} else {
return false;
}
}

这种写法尽管没问题,但我觉得太过繁琐,显得很啰嗦.因为我在用IDEA写Java的时候发现它有一个代码优化的功能.像上述程序,一般会被优化为

1
2
3
bool IsEmpty(List l) {
return l -> length == 0;
}

这样不就更加简单易读了吗. 还有很多类似的例子比如图的搜索时,我们可以将是否越界拿出来写一个函数,有些人往往会这么写

1
2
3
4
5
6
7
8

bool isCorssLine(int x,int y) {
if(x > 0 && x < Edge && y > 0 && y < edge) {
return true;
} else {
return false;
}
}

但事实上有种更易读更简洁的写法,跟上面的道理一样:

1
2
3
bool isCorssLine(int x,int y) {
return (x > 0 && x < Edge && y > 0 && y < edge);
}
script>