C语言之数组



一、 数组的基本概念
一个int类型的变量能保存一个人的年龄,如果想保存整个班的年龄呢?
1.什么是数组
数组,从字面上看,就是一组数据的意思,没错,数组就是用来存储一组数据的
2.数组的特点
只能存放一种类型的数据,比如int类型的数组、float类型的数组
里面存放的数据称为“元素”


二、 数组的定义
1.定义
声明数组的类型
声明数组的元素个数(需要多少存储空间)
2.格式
元素类型 数组名[元素个数];
比如:int ages[3];
3.简单使用
简单初始化:int ages[5] = {19, 19, 20, 21, 25};
元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始
数组元素的访问:a[i]
4.初始化
初始化方式
int a[3] = {10, 9, 6};
int a[3] = {10,9};
int a[] = {11, 7, 6};
int a[4] = {[1]=11,[0] = 7};


三、注意点

a代表数组首元素的地址,不是整个数组的地址
&a表示整个数组的地址 &a a代表的数据类型不一样 (两者的步长不一样)
&a+1:加上整个数组的大小
a+1: 加上一个数组元素的大小


&a 数组类型: int[10]
a 数组首元素的类型
int a[10] = {1,2}; //其他初始化为0


a1代表数组首元素的地址(不是整个数组的地址),a1 -> 常量指针变量
1变量-->2指针变量--》 3常量指针变量 (常量指针)


结论:不能被随便的改变常量指针变量的值(不能随便的改变指针的指向)



为什么它是一个const?  
答:在定义a1[5]的时候,编译器分配内存,为了能顺利的回收内存,为了有机会让编译器拿到原始内存首地址。
编译器就把a1做成const量。
不能深入的理解c指针各种现象,是产生bug的根源
int a1[5] = {1,3,4,55, 6};
char *p = &a1;
a1 = 0x11;   //错误



四、数组指针的两种表示法


第一种:

		int _tmain(int argc, _TCHAR* argv[])
		{
			//我声明了一个数组类型 (固定大小内存块的别名)
			typedef int(myarr)[5];
		
			int arr[5];
		
			//定义一个指向数组类型的指针变量
			myarr * parr;
			parr = &arr;
		
			for (int i = 0; i < 5; i++)
			{
				(*parr)[i] = i;
			}
			for (int i = 0; i < 5; i++)
			{
				cout << arr[i] << "  ";
			}
			cout << endl;
			system("pause");
			return 0;
		}

第二种:

		void main()
		{
			//声明一个数组指针类型,是个指针,里面存放了数组的首地址
			typedef int(*myarr2)[5];
			int arr[5];
			myarr2 m_arr = &arr;
			
			int(*myarr3)[5] = &arr;
		
			for (int i = 0; i < 5; i++)
			{
				(*myarr3)[i] = i;
			}
			for (int i = 0; i < 5; i++)
			{
				cout << arr[i] << "  ";
			}
			cout << endl;
		
			system("pause");
		}


五、二维数组的操作


	#include "stdafx.h"
	#include <iostream>
	#include <string>
	using namespace std;
	
	
	void main()
	{
		int (*myarr)[5];
		//1 arr数组首元素的地址
		//2 arr是一个常量指针 
		//3 arr是一个数组指针
		int arr[3][5];
		int a[5] = { 1, 2, 3, 4, 5};
		myarr = &a;
		int temp = 0;
		printf("myarray:%d   myarray+1:%d", myarr, myarr+1);
		printf("\n&a   :%d   &a+1      :%d \n", &a, &a+1);
	
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 5; j++)
			{
				arr[i][j] = temp++;
				cout << arr[i][j] << "   ";
			}
		}
		cout << endl;
		myarr = arr;
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 5; j++)
			{
				myarr[i][j] = temp++;
				cout << myarr[i][j] << "   ";
			}
		}
		for (i=0; i<3; i++)
		{
			for (j=0; j<5; j++)
			{
				myarray[i][j] = tmp++;
				//第i行第j列赋值
				*(*(myarray+i)+j ) = tmp++;
			}
		}
		cout << endl;
		system("pause");

六、二维数组的三种内存模型(含:指针数组)


指针数组

		char *   p1[] = {"123", "456", "789"};
表示数组中,只能存储char *类型的指针值。


传统方式定义一个二维数组:

		char p2[3][4]  = {"123", "456", "789"};



手工分配二维数组的内存空间

char **p3 = (char **)malloc(3 * sizeof(char *)); 

二维数组的应用:


求关键字在表中的位置:

	//一个入口 多个出口
	int searcheKeyTable(const char* table[], const int size, const char* key, int *pos)
	{
		int rv = 0;
		int i = 0;
		int inum = 0;
		if (table==NULL || key==NULL || pos==NULL)
		{
			rv = -1;
			printf("func searcheKeyTable:%d", rv);
			return rv;
		}
		inum = (sizeof(table)/sizeof(*table));
	
		for(i=0; i<size; i++)
		{
			if( strcmp(key, table[i]) == 0 )
			{
				*pos = i;
				//break;
				return rv;	
			}
		}
	
		//没有找到返回-1
		if (i == size)
		{
			*pos = -1;
		}
		return rv;
	}


做菜单:

	int main()
	{
		int inum = 0;
		int pos = 0;
		int a[10];
		int i = 0;
		char*   c_keyword[] = {
			"while", 
			"case",
			"static",
			"do"
		};
	
		{
			int a[10];
			sizeof(a);
		}
	
		for(i=0; c_keyword[i]!=NULL; i++)
		{
			printf("%s\n", c_keyword[i]);
		}
	
		inum = (sizeof(c_keyword)/sizeof(*c_keyword));
		searcheKeyTable( c_keyword, DIM(c_keyword),"do", &pos);
		searcheKeyTable( c_keyword, inum,"do", &pos);
		printf("pos:%d\n", pos);
		//searcheKeyTable(NULL, DIM(c_keyword),"do", &pos);
		//printf("pos:%d\n", pos);
		searcheKeyTable( c_keyword, DIM(c_keyword), "static", &pos);
		printf("pos:%d\n", pos);
	
		getchar();
		return ;
	}
	
	//main函数是操作系统调用的函数
	//在程序执行的时候可以向main函数传递参数
	
	/*
	argc 命令行参数
	argv 命令行参数数组
	env  函数变量数组
	
	int main();
	int main(int argc);
	int main(int argc, char *argv[])
	*/
	
	
	//主函数参数
	int main66(int argc, char* argv[], char* env[])
	{
		int i = 0;
		//main02_1();
	
		printf("******************* Begin argv *******************\n");
		for(i=0; i<argc; i++)
		{
			printf("%s\n", argv[i]);
		}
	
	
		printf("******************* End argv *******************\n");
	
		printf("\n");
		printf("\n");
		printf("\n");
	
		printf("******************* Begin env *******************\n");
	
		for(i=0; env[i]!=NULL; i++)
		{
			printf("%s\n", env[i]);
		}
	
		printf("******************* End env*******************\n");
	
		getchar();
	}
	
	//
	int main53()
	{
		int pos = 0;
		int a[10];
		int i = 0;
		//指针数组当函数参数的时候,指针数组会退化为指针 需要把数组的个数传给被调用函数
		char*   c_keyword[] = {
			"while", 
			"case",
			"static",
			"do", //常量字符串的首地址是不是一个32位的数
			0 //填写一个零是不是应该
		};
	
		//[] * 区别是 []只不过是编译器帮我们做了一个*p操作而已。
		for (i=0; c_keyword[i]!=NULL;i++)
		{
			printf("%s \n", c_keyword[i]);
		}
	}






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值