一、数组
1.定义
数组是一个类型的聚合,是相同类型的聚合,数组的下标永远从0开始。
2.注意
数组初始化只有一次机会,在定义时初始化,如何输入不同类型的数据会发生截取,但不会报错。
int arr[5];数组名只能出现赋值的右边,代表首元素的首地址,不能出现在左边
3.常见问题
(1)数组什么时候确定大小
在编译阶段确定大小
(2)数组存放在哪个位置
数组存放在栈中
(3)什么时候给数组分配内存
运行的时候
(4)数组越界的原理
若大于数组定义的大小,会碰到哨兵位(哨兵位都是int类型,有两个,每个变量都有哨兵位)
(5)数组最多分配多大内存
与栈的大小有关,1M-2M之间。
(6)用sizeof求数组的字节数
sizeof(arr)表示整个数组的字节数
求数组长度的公式:int len =sizeof(arr)/sizeof(arr[0])
4.数组与指针
(1)有两种情况数组名表示整个数组
1.sizeof(arr)代表整个数组的字节大小
2.&arr +1;代表最后一个数组元素的后面
(2)访问数组中的元素
1.通过数组的下标
2.指针int*p=arr *(p+3)=arr【3】
(3)字符数组
1.char crr[5] ''中的为字符
2.若没有充满数组会补上\0
如:char crr[5]=‘abcd’ 默认会加上\0
3.数组的整体赋值只有一次机会,即在初始化的时候,arr[5]=arr4是错误的(字符串存储在ready only data 段,只可以读,不可以修改,详见Linux进程空间图)
(4)字符串数组
注意`
char ch1 = 0x00;//0
char ch3 = 0;//0
char ch4 = '\0';//0
char ch2 = '0';//48`
char* str=“yamguang”;字符串,默认有\0;
2.注意%s打印字符串,遇到\0停止
strlen 计算字符串的长度,遇到\0停止,不包括\0
#include<stdio.h>
int main()
{
char crr[5] = {'a','b','c','d','e'};//字符数组,不会添加\0,所以会出错
char crr2[5] = "abcd";//字符数组 默认会加\0
char crr3[] = "abcdef";//字符数组 默认会加\0
char crr4[10] = "abcdef";
printf("%s\n",crr);//%s遇到\0停止,所以第一个会出错,没有\0
printf("%s\n",crr2);
printf("%s\n",crr3);
printf("%s\n",crr4);
return 0;
}
(5)指针
1.int p,为野指针,·····
2.指针大小都为4个字节
3.int p=Null和p=Null的区别
①定义一个变量p,其指向的内存里保存的是int类型的数据,定义变量时把p的值赋值为0x00000000,这个过程叫初始化,是在编译的时候进行的。
②int * p; * p=Null;定义一个指针变量,保存int类型的数据,p本身的值不确定,现在p保存的有可能是一个非法的地址。第二行给 p赋值为Null,会报错。改为int i=10; int * p=&i; * p=Null; p指向的内存由原来的10 变为了0,而p本身的值即内存地址没有变。
4.int*p=null;0号地址 不能访问0号地址
(5)例题
//记住
strlen 计算字符串的长度,遇到\0停止,不包括\0*
#include<stdio.h>
#include<string.h>
int main()
{
char str[100] = "abcdef";
char *str2 = "abcdef";
char str3[] = "abcdef";
char str4[100] = "abcdef\0xyz";//strlen 计算字符串的长度,遇到\0停止,不包括\0*\0之后不计算
char *str5 = "abcdef\0xyz";
char str6[] = "abcdef\0xyz";
char str7[] = "abcdef\n\0";
char *str8 = "abcdef\n\0";
printf("%d,%d\n",sizeof(str),strlen(str));//100 6
printf("%d,%d\n",sizeof(str2),strlen(str2));//4 6
printf("%d,%d\n",sizeof(str3),strlen(str3));//7 6
printf("%d,%d\n",sizeof(str4),strlen(str4));//100 6
printf("%d,%d\n",sizeof(str5),strlen(str5));//4 6
printf("%d,%d\n",sizeof(str6),strlen(str6));//11 6
printf("%d,%d\n",sizeof(str7),strlen(str7));//9 7
printf("%d,%d\n",sizeof(str8),strlen(str8));//4 7
//printf("%d,%d\n",sizeof(str3),strlen(str3));
return 0;
}
二、 练习题
//3.输入两个正数m和n,求其最大公约数和最公倍数
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int GgreatestCommonDivisor(int m,int n)//求两个数的最大公约数,用辗转相除法
{ int divisor;//定义除数
int dividend;//定义被除数
int res=m%n;//定义余数
if(m>0&&n>0&&m>n)
{
dividend =m;//把m的值赋给被除数
divisor =n;//把n的值赋给除数
res=dividend %divisor ;
while(res!=0)
{
dividend = divisor ;//把除数的值赋给被除数
divisor =res;//把余数的值赋给除数
res=dividend %divisor ;//求余数
}
printf("这两个数的最大公约数为:%d\n",divisor );
printf("这两个数的最小公倍数是:%d\n",m*n/divisor);
}
else
{
printf("请输入两个正数:\n");
}
return 0;
}
5.求sn=a+aa+aaa+…+aaa…aa之值,其中a是一个数字,n表示a的位数,例如,2+22+222+2222+22222(此时n为5)n由键盘输入
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int Summation(int a,int n)
{
int i;
double sn=0;
double b=0;
b=a;//把a的值赋给b
for(i=1;i<=n;i++)
{
sn+=b;//求和
b=b*10+a;//表示出aaaa的形式,在原来的基础上扩大十倍再加a
}
printf("sn=%f\n",sn);
return 0;
}
8.输出所有的 水仙花数,水仙花数是指一个三位数,其各位数字立方和等于该数的本身,例如,153是一个水仙花数,因为153=13+53+3^3
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int fun1(int n)
{
int a=0;
int b=0;
int c=0;
int y=0;
int i;
int j=0;
for (i=100;i<n;i++)
{
a=i%10;//求a的值,低位例如,153%10为3,即a为3
j=i/10;//把a去掉,153/10为15
b=j%10;//求b的值,15%10为5,即b为5,
//j=i/10;//去掉b,15/10为 1
c=j/10;//求c的值
y=a*a*a+b*b*b+c*c*c;
if(i==y)
{
printf("%d\n",i);
}
//return 0;
}
return 0;
}
9.一个数恰好等于它的因子之和,这个数即成为完数,例如,6的因子是1,2,3而6=1+2+3,因此6是完数,编程做出1000之内的完数,按下面格式输出其因子:6 its factors 1,2,3
void PefectNumber(int n)
{
int i=0;
int j=0;
int k=0;
for(i=1;i<n;i++)
{
int sum=0;
for(j=1;j<i;j++)
{
if(i%j==0)
{
sum+=j;
}
}
if(sum==i)
{
printf("%d its factors are \n",i);
}
}
}
10.有一个分数数列,2/1,3/2,5/3,8/5,13/8,21/13,求出这个数列的前二十项之和。
int Sum(int n)
{
float a=2;
float sn=0;
float b=1;
float i;
for(i=1;i<=n;i++)
{
float tmp;
sn+=(a/b);
tmp=a;
a=a+b;
b=tmp;
}
printf("sn==%f\n",sn);
return 0;
}
例如,若 a 所指数组中的数据最初排列为:1,3,6,5,2,7,8,9,删除偶数后,a 所指数组中的数据为:1,3,5,7,9,返回值为 5。
int Fun(int *arr,int len)
{
int j = 0;//放奇数的下标
for(int i = 0;i < len;i++)
{
if(arr[i] % 2 != 0) //奇数
{
arr[j] = arr[i];
j++;
}
}
//Show(arr,j);
return j;
}
猴子吃桃问题。猴子第一天摘了若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的吃掉一半,又多吃了一个。
以后每天早上都吃了前一天的剩下的一半零一个,到第十天早上想再吃的时候,就只剩下一个桃子了,求第一天总共摘了多少桃子。
int NumberOfPeacheas(int n)//吃桃子的天数
{
int peach=0;//桃子的个数
int rest=1;//第十天剩余桃子的个数
int day;
for(day=n-1;day>0;day--)
{
rest=(rest+1)*2;
peach=rest;
}
printf("第一天摘桃子数:%d\n",peach);
return 0;
}
一个球从100m的高度自由下落,每次落地后反跳回原来高度的一半,再下落 ,再反弹。求它在第十次落地时,共经过多少米,第十次反弹多高
int High(int h,int n)//h代表高度,n代表次数
{
int i;
int sum=h;
int tmp=0;
for ( i=1;i<=n;i++)//i=3时,代表第三次落地时共经过的路程,代表第二次弹起的高度
{
tmp=h/2;
h=tmp;
sum=sum+2*h;
}
printf("%d\n",i);
printf("%d\n",h);
printf("%d\n",sum);
return sum;
}
***求连续子数组的最大和?
{10,-1,9,-100,-10} //18 ===> 打印出开始和结束的下标
int MaxNum2(int *arr,int len)
{
assert(arr != NULL && len > 0);
int max = 0x80000000;
int sum = 0;
for(int i = 0; i < len;i++)
{
//sum = 0;
if(sum <= 0)
{
sum = arr[i];//10
}
else
{
sum += arr[i];//9 18 -82
}
if(sum > max)
{
max = sum;//10 18
}
}
return max;
}
将斐波那契数列写入数组
void Fabonacio(int *arr,int len)
{
assert(arr != NULL && len > 0);
arr[0] = 1;
arr[1] = 1;
for(int i = 2;i < len;i++)
{
arr[i] = arr[i-1]+arr[i-2];
}
}