黑马程序员---C语言学习笔记之数组的基本概念和分类

------Java培训、Android培训、iOS培训、.Net培训--------
08-03 数组的基本概念和分类


1.基本概念
在程序设计中,为了处理方便,把具有相同各类型的若干变量按有序的形式组织起来,这些按序排序的同类数据元素的集合称为数组。
在c语言中,数组属于构造数据类型,一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。


1.1数组的几个名词
1) 数组:一组具有相同数据类型的数据的有序集合
2) 数组元素:构成数组的数据,数组中的每一个数组元素具有相同的名称,不同的下标,可以作为单个变量使用,所以也称为下标变量
3)数组的下标:是数组元素的位置的一个索引或指示
4) 数组的维数:数组元素下标的个数,根据数组的维数可以分为一维,二维,三维,多维数组。


2.按存储的内容分类
可分为:
a.数值数组:用来存数数值
b.字符数组:用来存储字符
c.指针数组:用来存储指针变量(地址)
d.结构数组:用来存储结构类型的数据


3.一维数组介绍
3.1.介绍
如果一个数组的所有元素都不是数组,那么该数组称为一维数组


3.2. 定义
在C语言中舒勇数组必须先进行定义,定义方式位
类型说明符 数组名[常量表达式]; 如: int a[22];

[变量的使用流程]:定义--》初始化--》使用
[数组的使用流程]:定义数组--》给数组初始化--》使用数组


a.类型说明符 是任一种基本数据类型或构造数据类型
b.数组名 用户定义的数组标识符
c.常量表达式 表示根据元素的个数,也称为数组的长度


3.3 数组定义的注意点


a.数组的长度可以是一个常量,也可以是一个常量表达式
b.数组名不可以同其他变量同名
c.数组的长度不可以为一个变量,
例如:int len =4;
int a[len]; //在xcode中编译器做过优化,编译通过,但是在vs中会报错
d.数组的长度可以使用宏定义

4.一维数组让人疑惑的问题
4.1 如果数组没有初始化,数组中到底有没有值?是什么?
答案:有,但是值是不确定的垃圾值


4.2 如果进行了部分初始化,数组中的其他元素都有值了,没初始化的那部分被系统自动初始化位0了。字符数组中也是如此


5.一维数组的遍历和引用
5.1介绍
数组元素是组出现横数组的基本单元,数组元素也是一种变量,其标识方法是数组名后面跟一个下标。数组的下标从0开始,范围是0~n-1


数组的引用方式:数组名[下标] 例如a[2];


5.2如果要逐个访问数组的元素的话,这就叫做数组的遍历

5.3 特别强调: 使用先定义后初始化的方式,如果部分数组元素被初始化,那么其他未被初始化的部分不会被系统自动初始化位0


6.一维数组的存储方式
1)计算机会给数组分配一块连续的存储空间
2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个到第n个元素
3)每个元素占用相同的字节数
4)元素之间的地址是连续的


7.数组的长度
7.1 数组在内存中占用的总字节数: 
		int a[5];
		int len = sizeof(a);//结果是20

7.2 数组的长度
= 数组的总长度(占用字节数) / 每个元素占用的字节数


例如:
		 int a[5];
		 int len = sizeof(a)/sizeof(a[0]);//结果是5


8.一维数组的越界问题
如果有如下代码,就会发生数组越界
	int a[2] = {1,2};
	int b = a[2];

因为数组下标是从0开始,数组a只能存储两个数据。所以会发生越界。取到了不该访问的内存空间,这样会有不可预料的后果。


9.数组应用举例


找一个数组中的最大值

    int a[10];
    int max;
    
    for (int i = 0; i < 10; i++) {


        scanf("%d", &a[i]);
        
        if(0 == i){
            max = a[i];
        }else{
            if (a[i] > max) {
                max = a[i];
            }
        }
    }
    
    printf("max = %d", max);




    运行结果:
    1 3 4 5 12 6 2 65 456 13
max = 456


10.数组名作为函数的实参传递


在C语言中,数组名除了作为标识符外,数组名还代表了该数组在内存中的起始地址,因此,当数组名作为函数参数时,实参与形参之间不是“值传递”,而是“地址传递”,实参数组名将该数组的其实地址传递给形参数组,两个数组共享一段内存单元,编译系统不再位形参数组分配存储单元,


例如:
	void test(int b[]){
	    printf("形参地址:%p", b);
	}




	int main(int argc, const char * argv[])
	{
	    int a[10];
	    printf("实参地址:%p\n", a);
	    test(a);
	    return 0;
	 }


打印结果:
实参地址:0x7fff5fbff8f0
形参地址:0x7fff5fbff8f0


11.数组名作为函数参数的注意点
a.形参数组和实参数组的类型和长度必须一致,否则会引起错误
b.形参数组和实参数组的长度可以不相同,因为在调用时,只是传递了首地址而不检查形参数组的长度,当形参数组的长度与实参数组不一致时,虽不至于出现语法错误,但程序执行结果将不可预料
c.在函数形参表中,允许不给出形参数组的长度,或用一个变量来表示数组元素的个数
例如可以写成 void test(int b[])或void test(int b[4])


d.多维数组也可以作为函数的参数,在函数定义时对形参数组可以指定每一维的长度,也可以省略第一维的长度。以下写法都是合法的
例如:int test(int a[][3]) 或int test(int a[2][3])


12.冒泡排序的思想
冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地走访过要排序的数列,依次比较两个元素,如果他们的顺序错误就把他们交换过来,走访数列的工作时重复地进行指导没有再需要交换,也就是说该数列已经排序完成,这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。


冒泡排序 分为:大数下沉法 和 小数上浮法


冒泡排序代码实现:
	    int num[] = {123,1,123,123,2342,10,5,1,2,7,4,8,12,23,4,234,24412,31};
	    int len = sizeof(num) / sizeof(int);
	    int i = 0;
	    int times = 0;  
	    for ( ;i < len - 1; i++) {
	        for (int j = 0; j < len - i - 1; j++) {//因为每次都会把最大的一个放在最后面,所以每次都有一个值是确定的
	            if (num[j + 1] < num[j]) {
	                num[j + 1] = num[j + 1]^num[j];
	                num[j] = num[j + 1]^num[j];
	                num[j + 1] = num[j + 1]^num[j];
	                //show(num,i);
	                times++;
	                // break;
	            }
	        }
	    }
	     printf("sotr a times:%d\n",times);

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值