您的位置:首页 > 其它

C 小问题集锦

2015-11-24 01:26 363 查看
摘要:在学习 C 语言编程中遇到的一些容易混淆出错的问题,记录下来备忘。

C语言学习 小问题集锦

作者:乌龙哈里

时间:2015-11-24

平台:Window7 64bit,C# :Visual Studio Community 2015, C:TCC 0.9.26(x86-64 Win64)

参考:

章节:

数组元素 a[n++] 是 a
还是 a[n+1]?

2个递归到底如何运行?

传递数组的元素个数?

正文:

一、数组元素 a[n++] 是 a
还是 a[n+1]?

在学习排序中,看到了一种写法,a[n++],这个a[n++]到底是 a
还是 a[n+1]?不用多说,上测试代码:

#include <stdio.h>

int main(void){

int a[4]={1,2,3,4};

printf("Array: ");

for(int i=0;i<4;i++){printf("%d ",a[i]);}

printf(" n=%d \n",n);

int n=0;

a[n++]=8;

printf("Array: ");

for(int i=0;i<4;i++){printf("%d ",a[i]);}

printf(" n=%d \n",n);

return 0;

}

/*结果:

Array: 1 2 3 4 n=0

Array: 8 2 3 4 n=1

*/

结果表明:a[n++] 还是指 a
,然后n=n+1了。

二、2个递归如何运行?

在学习快速排序的时候,遇到了同时有2个递归的情况,如:

QuickSort(a,left,i-1);

QuickSort(a,i+1,right);

他们到底是怎么运行的呢?上测试代码:

#include <stdio.h>

int n=0;

void Recursion(int a,int b){

if (b>3 ) return;

if(a!=3) printf("%2d : R: %d %d \n",n,a,b);

n++;

b++;

Recursion(0,b);

Recursion(1,b);

}

int main(void){

Recursion(3,0);

return 0;

}

/*结果:

1 : R: 0 1

2 : R: 0 2

3 : R: 0 3

4 : R: 1 3

5 : R: 1 2

6 : R: 0 3

7 : R: 1 3

8 : R: 1 1

9 : R: 0 2

10 : R: 0 3

11 : R: 1 3

12 : R: 1 2

13 : R: 0 3

14 : R: 1 3

*/

根据递归的原理,用栈记录函数的出入口,我简单地认为把函数压入栈,根据栈后进先出的特性,我把上面的用符号记录过程,把两个函数分别标记为R0,R1。R0-1--代表第1个递归函数,b值为1;R1-2,代表第2个递归函数,b值为2,下来分解:

步 执行及b值 栈内及b值 描述

1 R0-1 R1-1 b=1,执行R0-1,把R1-1压入栈

2 R0-2 R1-1, R1-2 进入R0,b++为2,执行R0-2,把R1-2压入栈

3 R0-3 R1-1, R1-2, R1-3 进入R0,b++为3,执行R0-3,把R1-3压入栈

4 R1-3 R1-1, R1-2 进入R0,b++为4,触发退出,回到栈内取最后一个R1-3执行

5 R1-2 R1-1 R1-3执行,触发退出,执行R1-2

6 R0-3 R1-1, R1-3 进入R1-2,b++为3,执行 R0-3,把R1-3压入栈

7 R1-3 R1-1 R0-3触发退出,从栈内取出 R1-3运行

8 R1-1 R1-2 运行R1-1,进入R0-2,把R1-2压入栈

9 R0-2 R1-2, R1-3 运行R0-2,进入R0-3,把R1-3压入栈

10 R0-3 R1-2, R1-3 运行R0-3,触发退出

11 R1-3 R1-2 运行R1-3,触发退出

12 R1-2 R1-3 运行R1-2,b++为3,准备进入R0-3,把R1-3压入栈

13 R0-3 R1-3 运行R0-3,触发退出

14 R1-3 运行R1-3,触发退出,栈内为空,全部结束。

脑袋都疼了,那么复杂,这些人到底怎么想出来的,难道他只用知道退出机制及计算过程,根本不关注执行顺序。

三、传递数组的元素个数?

在学习排序中,经常要循环,需要知道数组的长度(元素个数),在同个函数内,用

int len=sizeof(a)/sizeof(a[0]);

就能知道,把数组传递进函数后,难道也能这样?上测试代码:

#include <stdio.h>

void Test(int a[]){

printf("byref: a %2d, a[0] %d,num %d\n",sizeof(a),sizeof(a[0]),sizeof(a)/sizeof(a[0]));

}

int main(void){

int a[]={1,2,3,4};

printf("none : a %2d, a[0] %d,num %d\n",sizeof(a),sizeof(a[0]),sizeof(a)/sizeof(a[0]));

Test(a);

return 0;

}

/*输出:

none : a 16, a[0] 4,num 4

byref: a 8, a[0] 4,num 2

*/

明显在传递数组的函数内再用这种方式是错误,原因在于数组作为形式参数是指针化了,显示的是指针的大小,64位平台指针是8 byte的。查了一堆资料,除了用结构 struct 把数组包装一下,如下:

struct A{

int count;

int a[];

};

这样能通过 count 取得数组大小,但这样又涉及数组的初始化等问题,很是麻烦。

若还在学习的过程中碰到这些小问题,继续补充。

未完待续...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: