iOS开发-C语言-数组
2015-08-27 12:20
316 查看
一、数组的基本概念及分类
1、基本概念
在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基 本数据类型或是构造类型。
数组的几个名词
1)数组:一组具有相同数据类型的数据的有序的集合
2)数组元素:构成数组的数据。数组中的每一个数组元素具有相同的名称,不同的下标,可以作 为单个变量使用,所以也称为下标变量。
3)数组的下标:是数组元素的位置的一个索引或指示。
4)数组的维数:数组元素下标的个数。根据数组的维数可以将数组分为一维、二维、三维、多维 数组。
2、按存储的内容分类
按数组元素的类型不同,数组又可分为:
数值数组:用来存储数值得
字符数组:用来存储字符 ‘a’指针数组:用来存放指针(地址)的
结构数组:用来存放一个结构体类型的数据
3、按维度分类
一维数组
二维数组
多维数组
二、一维数组定义及注意事项
1、一维数组介绍
如果一个数组的所有元素都不是数组,那么该数组称为一维数组
2、一维数组的定义
变量的使用流程:定义—>初始化—>使用
数组的使用流程:定义数组—->给数组初始化—>使用数组
在C语言中使用数组必须先进行定义。一组数组的定义方式为:
类型说明符 数组名[常量表达式];
类型说明符:
是任一种基本数据类型或构造数据类型。
数组名
用户定义的数组标识符。
方括号中的常量表达式
表示数据元素的个数,也称为数组的长度。
3、数组定义的注意点
1) 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。第一个数组元素的地址是数组所占内存块的首地址
2) 数组名的书写规则应符合标识符的书写规定。
1、只能由字母、数字、下划线组成
2、不能数字开头
3、不能与关键字重名
4、严格区分大小写
命名规则:
1、起一个有意义名字
2、驼峰标示
命名规范:
3) 数组名不能与其它变量名相同。
4) 方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]
5) 不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。
c99不支持使用变量作为元素个数,但llVM编译器,它支持
6)允许在同一个类型说明中,说明多个数组和多个变量。
一维数组的定义
三、一维数组初始化
1、一维数组的初始化
数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样
将减少运行时间,提高效率。
初始化方式有两种:定义的同时初始化、先定义,后初始化
2、定义的同时初始化
常见形式为:
类型说明符 数组名[常量表达式] = { 值, 值……值 };
其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。
又细分以下几种情况:
1)指定元素的个数的同时,对所有的元素进行显式的初始化 int nums[5] = {1,2,3,4,5};
2)指定数组的元素个数,对数组进行部分显式初始化 定义的同时对数组进行初始化,没有显式初始化的元素,那么系统会自动将其初始化为0
intnums[10] = {1,2};
3)不指定元素个数,定义的同时初始化,它是根据大括号中的元素的个数来确定数组的元素 个数
intnums[] = {1,2,3,5,6};
4)指定元素个数,同时给指定元素进行初始化 intnums[5] = {[4] = 3,[1] = 2};
给数组赋值的方法除了用赋值语句对数组元素逐个赋值外 还可采用初始化赋值和动态赋值的方法
注意: 使用变量定义的数组不可以定义数组的同时对数组进行初始化
3、先定义,后初始化
//先定义数组,然后对数组进行初始化
//使用常量作为元素个数
intnums[3];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
// 使用变量作为元素个数:c99不支持使用变量作为元素个数,但llVM编译器,它支持
intlen = 5;
intscores[len];
scores[0] = 90;
scores[1] = 88;
scores[2] = 80;
scores[3] = 77;
scores[4] = 99;
4、为什么要初始化数组?
1)数组如果没有初始化,数组中到底有没有值?啥东西?
如果定义数组后,没有初始化,数组中是有值的,是随机的垃圾数,所以如果想要正确使用数组应该要进行初始化。
2)数组如果部分初始化,那么没有初始化的元素是什么?
对于数组来说,一旦有元素被初始化,其他元素都被赋值0
一维数组的初始化
四、一维数组的引用
1、一维数组的引用方式
数组元素是组成数组的基本单元。数组元素也是一种变量, 其标识方法为数组名后跟一个下标。 下标表示了元素在数组中的顺序号。
数组元素访问一般形式为:
数组名[下标]
其中下标只能为整型常量或整型表达式。如为小数时,C编译将自动取整。
例如:
a[5] a[i+j] a[i++]
都是合法的数组元素。
数组元素通常也称为下标变量。必须先定义数组,才能使用下标变量。在C语言中只能逐个地使 用下标变量,而不能一次引用整个数组。
2、一维数组的遍历
一维数组的遍历:就是通过循环访问数组的每一个元素。
数组的引用方式
五、一维数组的存储方式
1、数组的存储方式
假设有数组如下:
intx[]={1,2};
charca[5]={‘a’,‘A’,‘B’,‘C’,‘D’};
存储方式:
1)计算机会给数组分配一块连续的存储空间
2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个….、第n个元素
3)每个元素占用相同的字节数(取决于数组类型)
4)并且数组中元素之间的地址是连续。
模拟该数组的内存存储细节如下:
intx[2]={1,2};
intca[5]={‘a’,’A’,’B’,’C’,’D’};
注意:字符在内存中是以对应ASCII值的二进制形式存储的,而非上表的形式。 在这个例子中,数组x的地址为它的首元素的地址0x08,数组ca的地址为0x03。
一维数组的存储
六、一维数组的地址
1、一位数组的地址
1)数组内部的元素地址是连续的
在内存中,内存从大到小进行寻址,为数组分配了存储空间后,数组的元素自然的从上往下排列 存储,整个数组的地址为首元素的地址。
2)数组名存放的是数组的首地址
数组的首地址:数组的第一个元素首地址(第一个元素的第一个字节地址)
3)数组每个元素的地址
charchars[] = {‘a’,’b’,’c’,’d’,’e’};
//根据下标计算这个下标的地址:chars + sizeof(char) * 下标
printf(“%c\n”,chars[1]);
intnums[] = {1,2,3};
//nums + sizeof(int) * 下标
一维数组的地址
一维数组长度的计算
一维数组的越界问题
应用:找最大值
七 、数组和函数参数
inta[4]={1,2,3,4};
a[0] a[1] a[2] a[3]=12;
数组可以作为函数的参数使用,进行数据传送。
数组用作函数参数有两种形式:
一种是把数组元素(下标变量)作为实参使用;
一种是把数组名作为函数的形参和实参使
1、数组元素作函数实参
数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相 同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。
2、数组名作为函数参数
用数组名作函数参数与用数组元素作实参有几点不同
1)用数组元素作函数参数不要求形参也必须是数组元素,但是用数组名作函数参数时,则要求形 参和相对应的实参都必须是类型相同的数组
2)在C语言中,数组名除作为变量的标识符之外,数组名还代表了该数组在内存中的起始地址, 因此,当数组名作函数参数时,实参与形参之间不是”值传递”,而是”地址传递”,实参数组名将 该数组的起始地址传递给形参数组,两个数组共享一段内存单元,编译系统不再为形参数组分配 存储单元。
3)在变量作函数参数时,所进行的值传送是单向的。即只能从实参传向形参,不能从形参传回实参。形参的初值和实参相同,而形参的值发生改变后,实参并不变化,两者的终值是不同的。
数组传递的时候,数组长度会丢失。所以传送数组名的同时也要传递长度!
利用冒泡法实现排序功能
利用双重for循环控制实现数组的排序
其中
if (arr[j]>arr[j+1])
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
)
就是冒泡排序的核心思想,将两个变量的值进行交换,实现排序的功能。
学习心得:
通过本章知识点的学习,掌握了数组的基本概念,了解了数组的定义,存储方式,地址,遍历,初始化,重要的两点数组元素最为函数参数和数组名作为函数参数,前者是值传递,后者是地址的传递,比较重要的一个应用就是用冒泡法对数组元素进行排序,利用for的双重循环来实现。
1、基本概念
在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基 本数据类型或是构造类型。
数组的几个名词
1)数组:一组具有相同数据类型的数据的有序的集合
2)数组元素:构成数组的数据。数组中的每一个数组元素具有相同的名称,不同的下标,可以作 为单个变量使用,所以也称为下标变量。
3)数组的下标:是数组元素的位置的一个索引或指示。
4)数组的维数:数组元素下标的个数。根据数组的维数可以将数组分为一维、二维、三维、多维 数组。
2、按存储的内容分类
按数组元素的类型不同,数组又可分为:
数值数组:用来存储数值得
字符数组:用来存储字符 ‘a’指针数组:用来存放指针(地址)的
结构数组:用来存放一个结构体类型的数据
3、按维度分类
一维数组
二维数组
多维数组
二、一维数组定义及注意事项
1、一维数组介绍
如果一个数组的所有元素都不是数组,那么该数组称为一维数组
2、一维数组的定义
变量的使用流程:定义—>初始化—>使用
数组的使用流程:定义数组—->给数组初始化—>使用数组
在C语言中使用数组必须先进行定义。一组数组的定义方式为:
类型说明符 数组名[常量表达式];
类型说明符:
是任一种基本数据类型或构造数据类型。
数组名
用户定义的数组标识符。
方括号中的常量表达式
表示数据元素的个数,也称为数组的长度。
3、数组定义的注意点
1) 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。第一个数组元素的地址是数组所占内存块的首地址
2) 数组名的书写规则应符合标识符的书写规定。
1、只能由字母、数字、下划线组成
2、不能数字开头
3、不能与关键字重名
4、严格区分大小写
命名规则:
1、起一个有意义名字
2、驼峰标示
命名规范:
3) 数组名不能与其它变量名相同。
4) 方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]
5) 不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。
c99不支持使用变量作为元素个数,但llVM编译器,它支持
6)允许在同一个类型说明中,说明多个数组和多个变量。
一维数组的定义
#include <stdio.h> #define N 5 int main(int argc, const char * argv[]) { int a[5]; float f12[4]; char ch[3+3]; int len=2; int a1[len]; int a2 ; int a3[N+3]; int a4['A']; int b,c,a5[2],a6[2]; return 0; }
三、一维数组初始化
1、一维数组的初始化
数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样
将减少运行时间,提高效率。
初始化方式有两种:定义的同时初始化、先定义,后初始化
2、定义的同时初始化
常见形式为:
类型说明符 数组名[常量表达式] = { 值, 值……值 };
其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。
又细分以下几种情况:
1)指定元素的个数的同时,对所有的元素进行显式的初始化 int nums[5] = {1,2,3,4,5};
2)指定数组的元素个数,对数组进行部分显式初始化 定义的同时对数组进行初始化,没有显式初始化的元素,那么系统会自动将其初始化为0
intnums[10] = {1,2};
3)不指定元素个数,定义的同时初始化,它是根据大括号中的元素的个数来确定数组的元素 个数
intnums[] = {1,2,3,5,6};
4)指定元素个数,同时给指定元素进行初始化 intnums[5] = {[4] = 3,[1] = 2};
给数组赋值的方法除了用赋值语句对数组元素逐个赋值外 还可采用初始化赋值和动态赋值的方法
注意: 使用变量定义的数组不可以定义数组的同时对数组进行初始化
3、先定义,后初始化
//先定义数组,然后对数组进行初始化
//使用常量作为元素个数
intnums[3];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
// 使用变量作为元素个数:c99不支持使用变量作为元素个数,但llVM编译器,它支持
intlen = 5;
intscores[len];
scores[0] = 90;
scores[1] = 88;
scores[2] = 80;
scores[3] = 77;
scores[4] = 99;
4、为什么要初始化数组?
1)数组如果没有初始化,数组中到底有没有值?啥东西?
如果定义数组后,没有初始化,数组中是有值的,是随机的垃圾数,所以如果想要正确使用数组应该要进行初始化。
2)数组如果部分初始化,那么没有初始化的元素是什么?
对于数组来说,一旦有元素被初始化,其他元素都被赋值0
一维数组的初始化
#include <stdio.h> int main(int argc, const char * argv[]) { int a[5]={1,23,3,4,45}; int a1[]={1,2,3}; int a2[4] = {1}; int a3[5] = {[2]=3,[4]=100}; int a4[3]; a4[0] = 1; a4[1] = 10; a4[2] = 100; return 0; }
四、一维数组的引用
1、一维数组的引用方式
数组元素是组成数组的基本单元。数组元素也是一种变量, 其标识方法为数组名后跟一个下标。 下标表示了元素在数组中的顺序号。
数组元素访问一般形式为:
数组名[下标]
其中下标只能为整型常量或整型表达式。如为小数时,C编译将自动取整。
例如:
a[5] a[i+j] a[i++]
都是合法的数组元素。
数组元素通常也称为下标变量。必须先定义数组,才能使用下标变量。在C语言中只能逐个地使 用下标变量,而不能一次引用整个数组。
2、一维数组的遍历
一维数组的遍历:就是通过循环访问数组的每一个元素。
#include <stdio.h> int main(int argc, const char * argv[]) { int i; int a[3]={1,2,3}; for (i=0;i<3;i++) printf ("a[%d]=%d\n",i,a[i]); return 0; }
#include <stdio.h> int main(int argc, const char * argv[]) { int i; int a[10]; for ( i=0; i<10; i++) { printf("请输入数组的第%d个值\n",i+1); scanf("%d",&a[i]); } for ( i=0;i<10;i++) { printf("%d\t",a[i]); } printf("\n"); return 0; }
数组的引用方式
#include <stdio.h> int main(int argc, const char * argv[]) { int a[5]={1,2,3,4,5}; printf("%d\n",a[0]); //1 printf("%d\n",a[1]); //2 printf("%d\n",a[2]); //3 printf("%d\n",a[3]); //4 printf("%d\n",a[4]); //5 for (int i=0; i<5; ) { // 0 1 2 3 4 printf("%d\t",a[i++]); } return 0; }
五、一维数组的存储方式
1、数组的存储方式
假设有数组如下:
intx[]={1,2};
charca[5]={‘a’,‘A’,‘B’,‘C’,‘D’};
存储方式:
1)计算机会给数组分配一块连续的存储空间
2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个….、第n个元素
3)每个元素占用相同的字节数(取决于数组类型)
4)并且数组中元素之间的地址是连续。
模拟该数组的内存存储细节如下:
intx[2]={1,2};
intca[5]={‘a’,’A’,’B’,’C’,’D’};
注意:字符在内存中是以对应ASCII值的二进制形式存储的,而非上表的形式。 在这个例子中,数组x的地址为它的首元素的地址0x08,数组ca的地址为0x03。
一维数组的存储
#include <stdio.h> int main(int argc, const char * argv[]) { int a[3]={1,2,3}; int ch,len; printf("a[0]=%p\n",&a[0]); printf("a = %p\n\n",a); printf("a[1]=%p\n",&a[1]); printf("a[2]=%p\n",&a[2]); printf("-----------------\n"); printf("%zd\n",sizeof(a)); int len = sizeof(a)/sizeof(int); printf("len = %d\n",len); char ch[]={'a','b','c','d'}; len = sizeof(ch)/sizeof(char); len = sizeof(ch); printf("len = %d\n",len); return 0; }
六、一维数组的地址
1、一位数组的地址
1)数组内部的元素地址是连续的
在内存中,内存从大到小进行寻址,为数组分配了存储空间后,数组的元素自然的从上往下排列 存储,整个数组的地址为首元素的地址。
2)数组名存放的是数组的首地址
数组的首地址:数组的第一个元素首地址(第一个元素的第一个字节地址)
3)数组每个元素的地址
charchars[] = {‘a’,’b’,’c’,’d’,’e’};
//根据下标计算这个下标的地址:chars + sizeof(char) * 下标
printf(“%c\n”,chars[1]);
intnums[] = {1,2,3};
//nums + sizeof(int) * 下标
一维数组的地址
#include <stdio.h> int main(int argc, const char * argv[]) { int x[]={1,2}; char ca[5]={'a','B','C','D','E'}; printf("x = %p\n",x); printf("ca= %p\n",ca); printf("数组名x=%p\n",x); printf(" &x[0] = %p\n",&x[0]); printf(" &x[1] = %p\n",&x[1]); printf("ca = %p\n",ca); for (int i=0; i<5; i++) { printf("&ca[%d] = %p\n",i,&ca[i]); } return 0; }
一维数组长度的计算
#include <stdio.h> int main(int argc, const char * argv[]) { int a[5]={0}; int a1[]={1,2,3,4,5,6,7,78}; char ch[3]; double d1[10]; int len = sizeof(a); len = sizeof(ch); len = sizeof(d1); len = sizeof(a)/sizeof(int); len = sizeof(a1)/sizeof(int); printf("len = %d\n",len); return 0; }
一维数组的越界问题
#include <stdio.h> int main(int argc, const char * argv[]) { char a[2]={'h','i'}; printf("a[0] = %c\n",a[0]); printf("a[1] = %c\n",a[1]); a[2]='s'; printf("a[2] = %c\n",a[2]); return 0; }
应用:找最大值
#include <stdio.h> int main () { int a[10]; for ( int i=0;i<10;i++) { printf ("请输入数组的第%d个数\n",i+1); scanf ("%d",&a[i]); } int max=a[0]; for (int i=1;i<10;i++) { if(a[i]>max) max=a[i]; } printf ("%d\n",a[i]); return 0; }
七 、数组和函数参数
inta[4]={1,2,3,4};
a[0] a[1] a[2] a[3]=12;
数组可以作为函数的参数使用,进行数据传送。
数组用作函数参数有两种形式:
一种是把数组元素(下标变量)作为实参使用;
一种是把数组名作为函数的形参和实参使
1、数组元素作函数实参
数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相 同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。
#include <stdio.h> int sum(int x,int y){ return x+y; } void printNum(int x){ if (x>0) { printf("%d\t",x); }else{ printf("0\t"); } } int main(int argc, const char * argv[]) { int a[5]={1,-2,-3,-4,5}; for(int i=0;i<5;i++){ printNum(a[i]); } return 0; }
#include <stdio.h> void change(int arr[2]){ printf("arr = %p\n",arr); arr[0]=18; } void test1(){ int a[2]={1,2}; printf("a = %p\n",a); change(a); printf("a[0] = %d\n",a[0]); } float avg(float score[5]){ float sum = 0.0f; for (int i=0; i<5; i++) { sum += score[i]; } return sum/5; } int main(int argc, const char * argv[]) { float f1[5]={59.9,58.72,60.11,56.33,81.66}; float av = avg(f1); printf("%.2f\n",av); return 0; }
2、数组名作为函数参数
用数组名作函数参数与用数组元素作实参有几点不同
1)用数组元素作函数参数不要求形参也必须是数组元素,但是用数组名作函数参数时,则要求形 参和相对应的实参都必须是类型相同的数组
2)在C语言中,数组名除作为变量的标识符之外,数组名还代表了该数组在内存中的起始地址, 因此,当数组名作函数参数时,实参与形参之间不是”值传递”,而是”地址传递”,实参数组名将 该数组的起始地址传递给形参数组,两个数组共享一段内存单元,编译系统不再为形参数组分配 存储单元。
3)在变量作函数参数时,所进行的值传送是单向的。即只能从实参传向形参,不能从形参传回实参。形参的初值和实参相同,而形参的值发生改变后,实参并不变化,两者的终值是不同的。
数组传递的时候,数组长度会丢失。所以传送数组名的同时也要传递长度!
#include <stdio.h> void print_arr(int arr[]){ for (int i=0; i<10; i++) { printf("%d\t",arr[i]); } } void print_arr2(char arr[]){ int len = sizeof(arr); printf("\nlen = %d\n",len); } int main(int argc, const char * argv[]) { int a[10]={1,2,3,434,5,6,7,7,8,9}; print_arr(a); char ch[3]={'a','b','c'}; print_arr2(ch); return 0; }
利用冒泡法实现排序功能
#include <stdio.h> void maoPao(int arr[],int len){ int temp; for(int i=0;i<len-1;i++){ for (int j=0; j<len-1-i; j++) { if (arr[j]>arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } int main(int argc, const char * argv[]) { int a[10]={1,200,23,45,12,34,19,4,388,63}; for (int i=0; i<10; i++) { printf("%d\t",a[i]); } printf("\n"); maoPao(a, 10); for (int i=0; i<10; i++) { printf("%d\t",a[i]); } int a1=3; a1 = a1+3; return 0; }
利用双重for循环控制实现数组的排序
其中
if (arr[j]>arr[j+1])
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
)
就是冒泡排序的核心思想,将两个变量的值进行交换,实现排序的功能。
学习心得:
通过本章知识点的学习,掌握了数组的基本概念,了解了数组的定义,存储方式,地址,遍历,初始化,重要的两点数组元素最为函数参数和数组名作为函数参数,前者是值传递,后者是地址的传递,比较重要的一个应用就是用冒泡法对数组元素进行排序,利用for的双重循环来实现。
相关文章推荐
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言内存对齐实例详解
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- 探讨C语言的那些小秘密之断言
- C语言实现BMP转换JPG的方法
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- C语言查找数组里数字重复次数的方法
- C语言泛型编程实例教程
- C语言中使用lex统计文本文件字符数
- 在C语言中转换时间的基本方法介绍
- C语言进制转换代码分享
- 基于C语言fflush()函数的使用详解
- 对比分析C语言中的gcvt()和ecvt()以及fcvt()函数