数组的基本定义:数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
一维数组
数组在内存中是连续的下面是 int a[5] 的内存示意图.
一维数组的创建与初始化
int array[5];
注: 数组的操作符为 [ ] 而非 ( ) 或 { } , 在创建数组时, 如果没有对数组初始化, 则 [ ] 内必须要有一个常量。
注:数组的第一个元素的下标为0;
未初始化的数组, 被调用时会输出一串垃圾值(随机值),可以先对其初始化
一般对数组初始化可以用以下方法实现:
(1)在定义数组时对数组元素赋以初值。如:
int array[5] = {1, 2, 3, 4, 5};
初始化后数组内的值为,
array[0] = 1
array[1] = 2
array[3] = 4
array[4] = 5
(2)初始化时可以只对一部分元素赋初值,未赋值的元素自动赋值为 '\0'。如:
int array[5] = {1, 2};
初始化后数组内的值为,
array[0] = 1
array[1] = 2
array[3] = 0
array[4] = 0
如果想使一个数组的元素值全部为0,可以用下面的方法:
int array[5] = {0};
(3)在对全部数组元素赋初值时,可以不指定数组长度。
int array[] = {1, 2, 3, 4, 5};
对于未在定义时指定长度的数组,可以使用 sizeof(array)/sizeof(array[0]) 来计算该数组长度;
一维数组的地址
符号‘&’ 表示取地址
&array[0] 表示数组首元素地址,单位是一个int长度,4 Byte
array 表示数组名,亦&array[0] ,单位是一个int长度, 4 Byte
&array 表示数组的地址,单位是一个数组, 20 Byte
int array[5] = {1, 2, 3, 4, 5};
printf("%p\n", &array[0]);
printf("%p\n", array);
printf("%p\n", &array);
printf("******************************")
printf("%p\n", &array[0] + 1);
printf("%p\n", array + 1);
printf("%p\n", &array + 1);
/****运行结果****/
0x100
0x100
0x100
******************************
0x104
0x104
0x114
二维数组
二维数组的每个元素内都是一个一维数组,在内存中是一行排列。
二维数组需要一个嵌套的循环来遍历,如下
int a[3][2];
for(i = 0; i < 3; i++)
{
for(j = 0; j < 2; j++)
{
printf("%d", a[i][j]);
}
printf("\n");
}
二维数组的创建与初始化
二维数组的初始化有以下几种方式
int a[3][2] = {1, 2, 3, 4, 5, 6};
int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
int a[3][2] = {1, 2};
int a[3][2] = {{1},{2, 3},{4}};
int a[][] = {1, 2, 3, 4, 5, 6};
int a[3][2] = {0};
二维数组的地址
&a[0][0] 表示首元素地址,单位4字节
a[0] 表示首行元素地址,单位4字节
&a[0] 表示首行地址,单位8字节
a 表示首行地址,单位8字节
&a 表示数组地址,单位24字节
printf("%p\n", &a[0][0]);
printf("%p\n", a[0]);
printf("%p\n", &a[0];
printf("%p\n", a);
printf("%p\n", &a);
printf("******************");
printf("%p\n", &a[0][0] + 1);
printf("%p\n", a[0] + 1);
printf("%p\n", &a[0] + 1);
printf("%p\n", a + 1);
printf("%p\n", &a + 1);
/* 运行结果 */
0x100
0x100
0x100
0x100
0x100
***********************
0x104
0x104
0x108
0x108
0x118
字符串
字符串的定义通常使用数组,如下
char str[20] = "hello";
char ptr[20] = "world";
字符串的赋值有三种方法,如下
(1)在定义时赋值
char str[20] = "hello";
(2)逐个字符赋值
char str[20];
str[0] = 'h';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';
(3) 利用strcpy进行赋值
char str[20];
strcpy(str,"hello");
(4)利用指针进行赋初值
char *p = "hello";
char *q;
q = "word";
利用指针像上面这样赋初值的时候有个问题,就是在赋完值后不能再作任何更改
p = "china";
q[1] = 'c';
上面的这两种改值操作都会报错。因为动态指针在使用前都要分配内存。下面是正确使用方法
#define MAX_STR_SIZE 11
char* pszSrc = "Hello world";
char* pszDst = (char*)malloc( sizeof(char) * ( MAX_STR_SIZE + 1 ) );
memset( pszStr,0,MAX_STR_SIZE + 1 );
strcpy( pszStr, pszSrc );
字符串函数
在使用字符串函数之前要先加上头文件 string.h
#include <string.h>
strcat,字符串连接函数
strcat(str, ptr); //把ptr连接到str后面
printf("%s", str);
/***运行结果***/
helloworld
styncat,指定n个字符字符串连接函数
strncat(str, ptr,3); //指定ptr中的3个字符连接到str后面
printf("%s", str);
/***运行结果***/
hellowor
strcpy,字符串拷贝函数
strcpy(str, ptr); //把ptr里的字符串拷贝到str里
printf("%s", str);
/***运行结果***/
world
需要注意的是,strcpy会把字符'\0'一起拷贝过去,这就相当于先把str清空了再把ptr里的字符串复制上去。
strcpy在字符串赋值中经常用到。
strncpy,指定n个字符字符串拷贝函数
strncpy(str, ptr,3); //指定ptr中的3个字符拷贝到str里
printf("%s", str);
/***运行结果***/
worlo
strcmp,字符串比较函数
if(strcmp(str, ptr) == 0)
printf("%s = %s\n", str, ptr);
else(strcmp(str, ptr) > 0)
printf("%s > %s\n", str, ptr);
else(strcmp(str, ptr) < 0)
printf("%s < %s\n", str, ptr);
strcmp作用方式是,从左到右逐个比较两个字符串里的字符(按ASCII码值大小),直到出现不同的字符或遇到 '\0' 为止。
当str>ptr时,返回正数,
当str=ptr时,返回 0,
当str<ptr时,返回负数。
例如: hello 与 hellb 比较 ,strcmp("hello",''hellb"), 返回正数
world 与 worlk比较 , strcmp("world","worlk"), 返回负数
hello 与 hello 比较 ,strcmp("hello",''hello"), 返回 0
strncmp,指定比较n个字符
strncmp(str, ptr, 1) 只比较str 和ptr 里的第一个字符
比如 strncmp("hello",''world", 1) 只比较 'h' 和 'w' 的大小,结果返回负数
函数
函数定义
函数是一组一起执行一个任务的语句。
一个c程序中只能有一个主函数 main()。
一个c程序中可以包含多个子函数与库函数。
c语言中函数定义的一般形式如下:
返回值类型 函数名( 形参类型形参表 )
{
函数体
}
需要注意的是,
(1)形参个数要和实参个数对应
(2)形参类型要和实参类型对应
(3)形参名字和实参名字可以不对应
函数里面一旦遇到return,函数调用立马结束。
与return类似,在任何函数中遇到exit(), 整个程序终止。
函数调用过程
(1)通过函数名找到函数的入口地址(函数名就是地址)
(2)给形参分配空间
(3)传值(把实参传给形参)(值传递,地址传递)
(4)执行函数体
(5)返回
(6)释放空间(释放的是栈空间)