标准c基础知识三

12年前


 数组是把一组相同类型的数据放到一起,便于管理;在内存中一定是连续摆放,;每个元素分配一个下标(从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;
  
  
 }