标准c基础知识三
数组是把一组相同类型的数据放到一起,便于管理;在内存中一定是连续摆放,;每个元素分配一个下标(从0开始)
#include <stdio.h>
int main()
{
int a[10];//定义时,方括号内是元素个数,要求非负整数字面量//目前这样的话,里面都是垃圾数据,最好要进行初始化
int i;
for (i=0;i<10;i++){
printf("%d",a[i]);//a[i];使用时,方括号内是下标;(0-元素个数-1)
}
printf("\n");
int num[4]={30,16,22,18};//数组初始化用{}大括号括起来;数量在这里是4,数据不能多可以少;少的部分全部用数值0(注意是数值0,假设是char数组,在这里用"\0"来填充)来填充;
for (i=0;i<4;i++){
printf("%d",num[i]);
printf("\n");
}
int b[5]={11};
for(i=0;i<5;i++){
printf("%d",b[i]);
printf("\n");
}
char c[10]={'c','s','d','1','0','0','7'};//数组中有多余的元素则放不下
for(i=0;i<10;i++){
printf("[%c]%d",c[i],c[i]);
printf("\n");
}
return 0;
//a数组赋值
//a=123;X;错误数据类型不匹配
//a={10,20,30,40};X,错误,赋值不能用{}
//数组可以初始化不可以赋值;但可以针对每个数组元素进行赋值
//数组是一个集合,可以初始化时赋值不可以后期单独赋值;但可针对每个元素赋值
a[1]=10,a[2]=20,a[3]=30,a[4]=40;
printf("请输入5个整数:");
for(i=5;i<10;i++){
scanf("%d",&a[i]);//一定要记得取地址&,要不然会段错误
}
for(i=0;i<10;i++){
printf("%d",a[i]);
printf("\n");
}
}
数组在内存中是连续存放的,只要知道第一个元素的地址,也就知道了元素的地址;
可以理解为:“数组名是第一个元素的地址,下标是偏移量(与第一个元素距离)”
#include <stdio.h>
int main()
{
int a[5]={11,22,33,44,55};
printf("a=%p\n",a); //%p:address
int i;
for (i=0;i<5;i++){
printf("&a[%d]=%p\n",i,&a[i]);//依次输出每个元素的地址;
}
*a+=100;//意思是将第一个元素增加100 //通过*访问地址来取变量
printf("%d\n",a[0]);
for(i=0;i<5;i++){
printf("a+%d=%p\n",i,a+i);//在这里要理解a+i的变化;更换数组类型为int,short int观察;;;a+i==&a[i];两者等价;a[i]==>*(a+i)
}
}
数组越界
vi outrange.c
#include <stdio.h>
int main()
{
int x=123;
int a[5]={11,22,33,44,55};
int y=456;
int i;
for (i=0;i<5;i++)//如果把这里变更为for(i=-2;i<8;i++) 则前面出现了2个垃圾数据,后面也会有3个垃圾数据
{
printf("%d ",a[i]);
}
printf("\n");
printf("x=%d,y=%d\n",x,y);
for (i=-2;i<8;i++)
{
a[i]=0;
}
printf("x=%d,y=%d\n",x,y);
return 0;
}
编译器并不保证变量的存放顺序按照变量的定义顺序来存放
用数组的时候下标切勿越界;//越界访问数据可能访问到无法预知的数据
//越界存放数据可能会破坏其他变量的值
//越界存放数据甚至可能导致程序崩溃
C语言里面用的字符串,abcdefghijkl,放在内存里面怎么区分呢?是abcdefghijkl,还是abcdef ghijkl
实际上在内存中存放不是连续的而是abcdef\0在结束位置有个\0来进行相隔
char[],可以用来放字符串
#include <stdio.h>
int main()
{
char a[4]={'a','b','c','d'};//a是一个字符数组,不是字符串,
printf("%s\n",a);//输出不一定是字符串,如果没有\0就不是字符串,可能在abcd之后有乱码输出;
char s[8]={'h','e','l','l','o','\0','w','o'};
printf("%s\n",s);//次次输出为hello
printf("%s\n",s+2);//输出为llo 理解:s为第一个元素的地址,+2
printf("%s\n",s+6);//输出wo后面可能会有乱码出现
char str[800];
printf("请输入一个字符串:");
scanf("%s",&str);//碰到空格字符结束 gets(str);可以读取一行碰到换行符结束,但现在基本上已经抛弃2392454762
printf("%s\n",str);
printf("请输入一行文字:\n");
scanf("%*[^\n]%*c")
return 0;
}
{
char c;
do
scanf("%c",&c);
while(c!='\n');
}
<====>scanf("%c",&str[0]);
printf(str);printf("\n");//printf输入内容中有格式占位符时就会出问题
vi string.c
#include <stdio.h>
int main()
{
char a[100]={'h','e','l','l'};
//char a[100]="hello,world";//与上面等价
printf("%d\n",sizeof("hello world!"));//输出13个字符,其中12个有效字符,1个\n字符
printf("%c\n","cool007"[3]);//输出为l
printf("%s\n","cool007"+3);//输出为l007
return 0;
}
理解数组名本身是不占用存储空间的。作为数值的时候只是代表数组的第一个元素的地址。
vi arrayname.c
#include <stdio.h>
int main()
{
int a[5];
double d[3];
char s[9];
printf("%d,%d,%d\n",sizeof(a),sizeof(d),sizeof(s));//最后输出为20,24,9
//怎么来的呢?
//int为32位,即每个元素4个字节;a数组有5个元素,则为20个字节,同理理解数组d和s。
return 0;
}
数组第一个元素的地址(*a);数组开始的地址(&a)//其物理地址是一样的,但含义不一样
a[1]=====>(*&a)
字符串的操作:把某个字符串放到某个地方
#include <stdio.h>
#include <string.h>
int main()
{
char a[100]="hello,world";
puts(a);
strcpy(a,"good afternoon!");//作用是复制字符串,把某个字符串复制到某个地方去
puts(a);
strcat(a,"dear friends!");//在一个字符串的末尾再追加一个字符串;要确保目的地有足够的空间来存放追加的内容
puts(a);
printf("%d,%d\n",sizeof(a),strlen(a));//计算a数组中一个字符串的长度;字符数组才能用;计算结果不包括反斜杠0
//strchr(a,‘f’);//在一个字符串中找一个字符;代表的是找到一个地址;没找到代表的是找到一个空地址
printf("%s\n",strchr(a,'f'));//从f开始到结尾
//printf("s\n",strchr(a,'k'));//字符串中无K,输出为空地址输出为段错误
printf("%s\n",strrchr(a,'f'));//从右往左找
puts(strstr(a,"ear"));//从a里面寻找一个字串
//字符串的比较
char b[6]="hello";
if (b=="hello")
printf("相等\n");
else
printf("不相等\n")
printf("%p,%p\n",b,"hello");
//b本身是一个数组;hello本身也是一个字符数组;虽然内容相同,但是其地址不相同
//如果想比较两个数组的内容是否相等,则用strcmp(b,"hello");如果两个字符串相等,带回来的数值为0,否则,第一个大,则为正;第一个小为负
//实际上是比较的ascii码
//字符串常量一般存储在只读存储空间里,程序只有读权限
//"hello"[0]='H';//编译错误:给只读位置赋值
return 0;
}
字符串总是在一个字符数组中,必须有一个\0结束;这是对的
一个字符数组就是一个字符串,这是不一定的。(必须有\0结束才行)
多个一维数组组合在一起组合成一个二维数组如
int a[10]
int b[10]
int c[10]
int d[10]
int e[10]
int x[5];//x的类型为int[5]
int x[5][10];//5个int[10]的一维数组
#include <stdio.h>
int main()
{
int a[3][5]={
{1,2},
{3};
{4,5}
};
int i,j;
for (i=0;i<3;i++)
{
printf("%p\n",a[i]);//显示
for (j=0;j<5;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
vi structure.c
//结构是C语言中定义新类型的方法
#include <stdio.h>
#include <string.h> //后面使用了strcpy函数
typedef enum gender{MALE,FEMALE} gender;
//typdef enum gender gg;
typedef struct person{
//
char name[20];
int age;
double income;
enum gender s;
}person; //切记这里有个;号
typedef char A[20];//给char[20]起别名
int main()
{
A str="good";//str的类型是char[20]
puts(str);
person a;
person b={"sxl",MALE,100,8005};
printf("%s是一位%d的%s,月薪%g\n",b.name,b.age,b.s=MALE?"帅哥":"美女",b.income);
peson c={age:18,s:FEMALE,name:"老姐",income:9876.5};
printf("%s是一位%d的%s,月薪%g\n",c.name,c.age,c.s=MALE?"帅哥":"美女",c.income);
person d=c;//内容相同,但是是两个独立的实体;只是复制了一下而已
printf("&c=%p,&d=%p\n",&c,&d);
a=b;
a.age=20;
strcpy(a.name,"哥");//不能用a.name=...
printf("%s是一位%d的%s,月薪%g\n",a.name,a.age,a.s=MALE?"帅哥":"美女",a.income);
printf("--------\n");
person p[5]={
a,
b,
c,
d,
{"帅",MALE,6,0}
};
int i;
for (i=0;i<5;i++){
printf("%s是一位%d的%s,月薪%g\n",p[i].name,p[i].age,p[i].s=MALE?"帅哥":"美女",p[i].income);
}
printf("请输入姓名、性别(M/F)、年龄、收入:\n");
char s;
scanf("%s %c%d%lf",&a.name,&s,&s.age,&a.income);
a.s=(s=='M'||s=='m')?MALE:FEMALE;
}