一维数组:
格式: 数组类型 数组名 [长度]
int a[10]; 长度位10,里面最多包含10个元素
注意: C语言不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。
一维数组的赋值:
int a[10]={0,1,2,3,4,5,6,7,8,9};全部赋值
int a[10]={0,1,2,3,4};
定义a数组有10个元素,但花括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。
int a[10]={0,0,0,0,0,0,0,0,0,0}; 或int a[10]={0};
例如:int a[5]={1,2,3,4,5}; 也可以写成 int a[]={1,2,3,4,5};
注意 int a[5]不存在a[5]这个元素,元素下标从a[0]到a[5];
一维数组的地址:
int a[10]的大小:一个int 类型元素4个字节,10个就是40个字节
地址分配:
如:int a[5]
连续地址分配 0x100 0x104 0x108 0x10c 0x110,地址值对应:a[0],a[1],a[2],a[3],a[4].每4个字节移动到一个元素。
注意:大端字节序:高字节存放低地址,低字节存放高地址。
小端字节序: 低字节存放高地址,高字节存放低地址。
一维数组地址表示:
#include <stdio.h>
int main()
{
int i;
int a[5]={1,2,3,4,0};
for(i=0; i<sizeof(a)/sizeof(a[0]) ; i++) //sizeof(a)/sizeof(a[0])计算数组长度
{
printf("%d ",a[i]);
}
printf("\n");
printf("%p\n",&a[0]);//数组首元素地址,单位4字节
printf("%p\n",a);//数组名,同时也是数组首元素地址 单位4个字节
printf("%p\n",&a);一维数组的地址,单位20个字节,
printf("*********\n");
printf("%p\n",&a[0]+1);
printf("%p\n",a+1);
printf("%p\n",&a+1);
}
运行结果:
0xbfa4c1ac
0xbfa4c1ac
0xbfa4c1ac
*********
0xbfa4c1b0//加4个字节
0xbfa4c1b0//加4个字节
0xbfa4c1c0//加20个字节14H=20
二维数组:
格式:数组类型 数组名 [行号][列号]
排列顺序:
二维数组赋值:
#include <stdio.h>
int main()
{
int i ,j;
// int a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};//自动按上图顺序排列没有的元素自动补0
// int a[4][3]={(1,2,3),(4,5,6),(7,8,9),(10,11,12)};//分组排列
// int a[4][3]={1,2};//没有的补0
int a[][3]={1,2,3,4,5,6,7,8,9,10,11,12};//列号不能省略
for(i=0;i<4;i++)//先排行,在排列打印二维数组
{
for(j=0;j<3;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}
其中:
&a[0][0]首元素地址,单位4字节
a[0]首行首元素地址 单位4字节
&a[0]首行地址 单位12字节
a首行地址 12字节
&a数组的地址,单位48字节
题目:判断那些不是a[1][1]
#include <stdio.h>
int main()
{
int i,j;
int a[3][4]={1,2,3,4,5};
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
printf("%d",a[i][j]) ;
}
printf("\n");
}
printf("%d\n",*(a[1]+1));//第1行首元素地址+1取值=a[1][1]
printf("%d\n",*(&a[1][1]));第一行第一个元素地址=a[1][1]
printf("%d\n",(*(a+1))[1]);//其中a[i]=*(a+i)所以等于a[1][1]
printf("%d\n",*(a[0]+5));//第0行首元素地址往后加5位取值a[1][1]
}
冒泡排序:
原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |
第一趟排序(外循环)
第一次两两比较6 > 2交换(内循环)
交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |
第二次两两比较,6 > 4交换
交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |
第三次两两比较,6 > 1交换
交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |
第四次两两比较,6 > 5交换
交换前状态| 2 | 4 | 1 | 6 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第五次两两比较,6 < 9不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9|
这样6和9就没有必要比
第二趟排序(外循环)
第一次两两比较2 < 4不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第二次两两比较,4 > 1交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第四次两两比较,5 < 6不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
这样5和6就没有必要比
第三趟排序(外循环)
第一次两两比较2 > 1交换
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第二次两两比较,2 < 4不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
这样4和5就没有必要比
第四趟排序(外循环)无交换
第五趟排序(外循环)无交换
总共比了5次,内部总共比了5,4,3,2,1次
#include <stdio.h>
int main()
{
int a[10]={0};
int i,j,tmp;
int length=sizeof(a) / sizeof(a[0]);
printf("please input ten number;\n");
for(i=0;i<length;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<length-1;i++)//外循环数组元素数-1
{
for(j=0;j<length-i-1;j++)每次内循环次数为数组元素数-1-i,每次比上次少1
{
if(a[j+1]>a[j])
{
tmp=a[j+1];
a[j+1]=a[j];
a[j]=tmp;
}
}
}
for(i=0;i<length;i++)
{
printf("%d",a[i]);
}
printf("\n");
return 0;
}
字符数组:
格式:
char a[10]={'a','b','c','d'}
字符数组输出printf(“%s\n”,a);
程序
#include <stdio.h>
#include <string.h>
int main()
{
int i;
char str[10]={'h','l','l','o'};//赋值方式1
char ptr[11]="helloword";//赋值方式2
char a[11]={0};
for(i=0;i<4;i++)
{
printf("%c",str[i]);//%c输出字符数组
}
printf("\n");
printf("%s\n",ptr);
printf("please input\n");
scanf("%s",a);//%s输入字符数组
printf("%s\n",a);//%s输出字符数组
strcmp和strncmp函数
#include <stdio.h>
int main()
{
char str[20]="hello";
char ptr[20]="world";
if(strcmp(str,ptr)==0)//比较2个数组的长度大小=0相等
{
printf("%s = %s\n",str,ptr);
}
else if(strcmp(str,ptr)<0)//<0 str<ptr
{
printf("%s <%s\n",str,ptr);
}
else
{
printf("%s > %s\n",str,ptr);
}
if(strncmp(str,ptr,1)>0)
{
printf("%c >%c\n",str[1],ptr[1]);
}
if(strncmp(str,ptr,1)<0)//只比较1位按照ascii码比较字符大小
{
printf("%c<%c\n",str[1],ptr[1]);
}
}
strcat函数
#include <stdio.h>
#include <string.h>
int main()
{
char str[20]="hello";
char ptr[20]="world";
strcat(str,ptr);
printf("%s\n",str);
}
将ptr内容连接到str数组后面打印helloWord
strcpy函数和strncpy函数
字符串复制函数
#include <stdio.h>
#include <string.h>
int main()
{
char str[20]="helloworld";
char ptr[20]="world";
char a[20]={0};
// strcpy(str,ptr);//将ptr连着\0一起拷贝打印输出为world
// printf("%s\n",str);
strncpy(str,ptr ,3);将ptr的前3个字符覆盖str前3个字符没有\0所以为worloworld
printf("%s\n",str);
strcpy(a,"hello");//将hello覆盖a数组中的内容
printf("%s\n",a);
}
注意:(1)字符数组1必须定义得足够大,以便容纳被复制的字符串。字符数组1的长度不应小于字符串2的长度。
(2)复制时连同字符串后面的′\0′一起复制到字符数组1中。
(3)可以用strncpy函数将字符串2中前面若干个字符复制到字符数组1中去。 例如:strncpy(str1,str2,2);作用是将str2中前面 2个字符复制到str1中去。
strlen
strlen函数 其一般形式为: strlen (字符数组) strlen是测试字符串长度的函数。函数的值为字符串中的实际长度(不包括′\0′在内)。
函数调用
返回值
函数void print()没有返回值,子函数运算的结果可以通过返回值返回到主函数中。主函数需要一个变量接受返回值。
形参
1.int app (intx,int y)子函数具有函数类型 ,函数名,形参。
2.形参个数与实参对应(主函数给子函数的变量参数)
3.形参与实参变量类型对应(地址对应地址,int对应int)
名字可以不一致
任何函数遇到 return 函数调用结束,不执行return下面的函数
任何函数exit(1)结束整个程序
函数调用过程:
1.通过函数名找到函数入口地址(函数名就是入口地址)
2给形参分配空间
3传递参数(把实参传给形参)分为值传递和地址传递
4执行函数体
5return
6释放栈空间
例:
#include <stdio.h>
void print(int x);
int add(int x, int y);子函数在主函数后面要加声明(声明不分配空间,定义分配空间)
int main()
{
int a =2;
int b =3;
int ret;
ret=add(a,b);//函数调用将a和b传给add,ret接受返回值
print(ret);//传递ret的值给print函数
}
void print(int x)
{
printf("hello\n");
printf("%d\n",x);
}
int add (int x,int y)//x和y接受ab的值
{
int result;
result=x+y;
return result;返回x+y的值
printf("hello\n");
}
例子2:封装冒泡排序
#include <stdio.h>
void paixu(int a[],int length);
void in(int a[],int length);
void print (int a[], int length);
int main()
{
int a[10]={0};
int i,j,tmp;
int length=sizeof(a) / sizeof(a[0]);
in(a,length);
paixu(a,length);
print(a,length);
return 0;
}
void in(int a[] ,int length)//传递数组的地址,length不能在调用内使用,这样计算的是地址长度不是数组长度
{
int i;
printf("please input ten number;\n");
for(i=0;i<length;i++)
{
scanf("%d",&a[i]);
}
}
void paixu(int a[],int length)
{
int i,j,tmp;
for(i=0;i<length-1;i++)
{
for(j=0;j<length-i-1;j++)
{
if(a[j+1]>a[j])
{
tmp=a[j+1];
a[j+1]=a[j];
a[j]=tmp;
}
}
}
}
void print (int a[],int length)
{
int i;
for(i=0;i<length;i++)
{
printf("%d",a[i]);
}
printf("\n");
}
extern static register修饰
register int a 将变量 a定义在寄存器中,&a地址会报错,&访问的是内存空间
extern声明外部变量,声明的变量必须是全部变量
1.c
#include <stdio.h>
int num =3;
int main()
{
print();
return 0;
}
2.c
#include <stdio.h>
extern int num;
static void print()//修饰变量或者函数改变他的作用域只能当前文件使用
{
printf("%d",num);
}
gcc 1.c 2.c -o extern