龙空技术网

程序员教你学C语言(十一)

轻松学C语言 587

前言:

而今大家对“c语言col”大致比较讲究,各位老铁们都需要知道一些“c语言col”的相关资讯。那么小编同时在网上搜集了一些关于“c语言col””的相关资讯,希望你们能喜欢,兄弟们快快来了解一下吧!

很多小伙伴都老是会碰到疑问,其实还是基础没打扎实,这些题如果你不看答案你能知道多少呢?如果还有很多不知道就证明基础没打扎实,如果你还在入门纠结,如果你还在苦恼怎么入门!小编有个建议,可以加小编弄的一个C语言交流基地,大家可以进入交流基地:565122788,里面新手入门资料,可以说从零到项目实战,都是可以免费获取的,还有程序员大牛为各位免费解答问题,热心肠的小伙伴也是蛮多的。不失为是一个交流的的好地方,小编在这里邀请大家加入我的大家庭。欢迎你的到来。一起交流学习!共同进步!小编等你!还有前面没有看的同学最好从程序员教你学C语言(一)开始看哦,尤其是基础还没打扎实的同学!

C语言是很实用的语言,但是它的语法也是比较怪异的,至少在我学了很多种编程语言后我才体会到这点,C语言的作者Dennis Ritchie后来开发了一种叫Limbo的语言,Limbo中各种标记的使用和C非常类似,但是声明语法完全设计成Pascal风格。由此可见,作者自己其实也在反省C语言的声明语法,所以不要误以为C是一门完美的语言,C追求的是便捷实用效率高,只要语法书写方便、编译器实现比较容易、执行效率高,在C语言看来就是好的。就拿数组来讲,可能很多新手都不解为什么数组的下标是从0开始而不是像Fortran一样从1开始,我举个例子,我之前上班的公司位于深圳一座5层的写字楼里,假设某人每爬一楼要花费10秒,那么此人从楼下爬到5楼,一共要多少秒?50秒?恭喜你,回答错误!答案是40秒;再比如你们老师问你19XX年是什么世纪?你总不能回答是19世纪吧,那还是20世纪啊,2000年也是属于21世纪啊。这些都是为什么呢?假如我们把写字楼和地面等高的那层计数为0层,最初的世纪技术为0世纪,最初的公历年计数为0年,那是不是都很好理解了?如果你还不理解,我们来举个二维数组(二维数组后面会将)的例子,假设我们定义了一个二维数组int array[M][N],我们要引用第line行第col列的元素我们可以使用array[line*width+col],那假设C语言里数组是从1开始,我们要引用这个元素我们就要写成array[(line-1)*width+col],这不麻烦吗,每次都要加括号多写个减1。所以如果再又新手问你为什么数组从0开始,因为语法书写简单,编译器实现起来方便。

学习了数组的原理,我们来写一个小程序,来复习下自己学过的知识,一个截图放不下我就直接贴代码了,再次告诫大家不要直接复制粘贴,要自己动手敲出来,只有这样你才能知道什么地方容易犯错,你犯的错越多,编程水平提高的越快,我前面只贴截图就是担心有些人偷懒不敲代码。

/* 使用选择法排序 */

# include <stdio.h>

void main()

{

int i, j, min, temp;

// 定义一个整型得一维数组

int array[10];

// 输入数据

printf("Please input ten integer: \n");

for(i=0; i<10; i++)

{

printf("array[%d] = ", i);

scanf("%d", &array[i]);

}

printf("The array is: ");

for(i=0; i<10; i++)

printf("%d ", array[i]);

printf("\n");

// 排序

for(i=0; i<9; i++)

{

min = i;

for(j=i; j<10; j++)

if(array[min]>array[j]) min = j;

temp = array[i];

array[i] = array[min];

array[min] = temp;

}

// 输出

printf("\nThe result: \n");

for(i=0; i<10; i++)

printf("%d ", array[i]);

printf("\n");

}

这段代码已经写了注释,输入数据和输出应该没什么问题,最主要的就是排序那段,

// 排序

for(i=0; i<9; i++)

{

min = i;

for(j=i; j<10; j++)

if(array[min]>array[j]) min = j;

temp = array[i];

array[i] = array[min];

array[min] = temp;

}

简单选择排序的基本思想:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。我们在代码里使用的是嵌套for循环来做的,而且要注意C语言数组是从0开始,所以我们是先选取array[0],然后依次和它身后的元素比较,如果array[0]较大,就发生交互,这样外层for循环一趟走下来,array[0]自然就会变成了最小的数;第二趟就是从array[1]开始了,这样又会在剩下的数里选出最小数,大家自己去测试结果吧。

我们前面都讲的数组大小和初始化是相同的情况,现在我们两个两种例外的情况,当定义的数组大小和后面的初始化列表不同时,看看会发生什么情况:

#include<stdio.h>

void main()

{

int a[5] = {1,2,3,4,5,6,7,8};

int b[5] = {1,2,3};

int i;

printf("sizeof(a)=%d\t sizeof(b)=%d\n",sizeof(a),sizeof(b));

for(i = 0;i < 10;i++)

{

printf("a[%d]=%-8d\t b[%d]=%d\n",i,a[i],i,b[i]);

}

}

输出结果为:

sizeof(a)=20 sizeof(b)=20

a[0]=1 b[0]=1

a[1]=2 b[1]=2

a[2]=3 b[2]=3

a[3]=4 b[3]=0

a[4]=5 b[4]=0

a[5]=4199376 b[5]=2293504

a[6]=2293576 b[6]=2293560

a[7]=4199478 b[7]=2293700

a[8]=4199376 b[8]=1

a[9]=0 b[9]=2

可以看到我们定义的两个数组a、b都是有5个元素的数组,其中a的初始化列表长度超出了5,而b的初始化列表长度只有3,观察我们的输出结果,我们可以发现a[4]后面的元素就是无用的数据了,说明初始化列表{1,2,3,4,5,6,7,8}里只有前面的5个元素被赋值给a了,然后超出的部分被截断了;而对于b,我们可以发现{1,2,3}赋值给了b的前三个元素,至于b[3]和b[4]都是使用0来填充的,这就是数组在这两种情况下的默认处理。注意for循环里我们使用了%-8d这么一句,-表示让输出左对齐,8表示输出的数占8个字节大小

前面我们学习了最简单的int数组,现在我们来看多维数组(这里只讲用的最多的二维数组),前面我们讲多重指针的时候说了,一个二级指针变量,它的值本身也是一个指针变量,我们可以对照起来理解,比如int a[2][3],这就是一个二维数组,它是第一维为2、第二维为3的数组,其实它就是一个数组的数组,它有两个元素,每个元素都是一个包含有3个int元素的数组,我们来用看看实际的例子,下面三种形式表示的二维数组其实是一样的:

注意多维数组在定义的时候,只有第一维的维数可以省略,比如上面的int b[][3]={{1,2,3},{4,5,6}},只要根据它后面的初始化列表编译器能够确定它的第一维数就行了。然后我把数组a在内存里的状态用图画出来让大家理解,二维数组a其实就是包含有两个元素a[0]和a[1]的数组,同时a[0]和a[1]本身也是包含有三个元素数组

前面我们讲了数组其实就是一个特殊的指针,它和普通指针还是还差别的,那么当数组和指针组合在一起会发生什么呢,我们来看下面一个小程序,虽然小,但是要认真理解:

C/C++学习交流群,欢迎大家一起来交流提升。565122788进群就能获取C语言新手学习大礼包

我们怎么理解(*p1)[2]和*p2[2]呢,我们要对比前面讲指针时遇到const的情况,int const *p是常量指针,int * const p是指针常量,我们当时用到的是就近原则,这里同样也要用就近原则。对于(*p1)[2],显然*里p1比较近,所以我们首先确定了p1是一个指针变量,然后我们看到后面的[2],说明它是一个指向带两个元素的数组的指针变量;对于*p2[2],[]的优先级是高于*的,所以[2]离p2比较近,我们先确定了p2是一个数组,再看它前面的*,我们就知道了p2是一个有两个指针变量的元素的数组。我们在后面使用sizeof时,可以明显看出p1是一个指针,它的长度只有4,而p2是一个有两个元素的数组,它的长度为8.

今天就到这里,欲知后事如何且听下回分解(手动滑稽)~

标签: #c语言col