吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4415|回复: 19
收起左侧

[C&C++ 转载] 【C语言 数组】老师让自己总结的数组内容部分,分享出来希望有用!

  [复制链接]
君莫笑WXH 发表于 2017-3-16 18:07
本帖最后由 君莫笑WXH 于 2017-3-16 18:22 编辑

数组:字面理解:指数据,就是小组由数据组成的小组,就叫数组
数组可以这样理解,你建造(定义)了一栋工科楼(数组)叫做“务成楼”,整栋楼有100个房间用来存储数据,你把每一个房间从0-99编号(在C语言中就写为 int WuChengLou[100] ;)
提醒:在C语言学习中不要迷信书、考题、老师、网络回帖;要迷信CPU、编译器、调试器、运行结果!
例如:
图片1.png
int类型占用2个字节是16位机的时代,现在都是32位机,64位机,所以,不可死记硬背课本或者课件上内容!
以我电脑为例!运行如下代码:常用数据类型对应字节数可用如sizeofchar),sizeof(char*)等得出
#include <stdio.h>
#include <stdlib.h>
int main()
{   
     printf("%d\n",sizeof(char));   
     printf("%d\n",sizeof(int));
}
图片2.png 图片3.png
此时,int类型占用4个字节,cahr类型占用1个字节


一.数组的初始化  
1>静态数组、动态数组初始化
static int b[5] = {1, 2, 3, 4, 5};             
静态存储的数组如果没有初始化,所有元素自动赋0
static int b[5];          
动态存储的数组如果没有初始化,所有元素为随机值auto int c[5]; 等价与  int c[5];  


2>针对部分元素的初始化
static int b[5] = {1, 2, 3};
b[0] = 1, b[1] = 2, b[2] = 3, b[3] = 0, b[4] = 0         
auto int fib[20] = {0, 1};
fib[0] = 0, fib[1] = 1, 其余元素不确定 如果对全部元素都赋初值,可以省略数组长度int a[ 10 ] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}  


二.对数组元素进行交换
其本质就是一个数据存入替换的过程
temp = a[index]; //将需要交换的其中一个数据存入“介质”中   
a[index] = a[k]; //将另一个数据替换上一个数据   
a[k] = temp;//将之前取出放入介质中的数据存入第二个数据


数组有几个特点一定要注意,看到数组就要想到:
1、  数组里面的数据类型是相同的,小组里面的成员肯定要一样的啊,俗话说物以类聚,人以群分,计算机里面也是这样啊
我们顺便看下数据的基本类型:int float double char
这些是基本类型,所以它们可以存在以下类数组:int a[10], float f[10], doule d[10], char str[10]; 它们每一个都有10个元素,每一个元素的类型都是其前面声明的类型


2、其实数组在内存中是连续分配的,如下图:
图片4.png
定义了一int型数组a,它有7个元素,分别是5,2,0,1,3,1,4它们在内存里面是连续存放的,每个元素占用4个字节。
仔细看上面的图,每一个字符都有一个地址,它们的跨度是4(字节)数组的每个元素都可以通过下标来访问,下标(比如常用index来表示其下标)其实就是他在数组中的位置,也就是他的号。
10个人过来,报数,1,2,3.....,只不过,C语言里数组的下标是从0开始的在计算机里面能访问的最小单位就是字节了,也就是地址只能找到以字节为单位,不能再精确了。
数组名a和变量名道理上是一样的,在编译时就和数组的首地址绑定上了,a就是数组的首地址,变量名和数组名其实都是方便人们记忆而取的代号,它在代码反汇编后,其实不存在变量名的

我们再来看一个字符型数组


图片5.png
定义了一char型数组a,它有6个元素,分别是'W', 'X', 'H', 'W', 'X', 'H'它们在内存里面是连续存放的,每个元素占用一个字节。强烈谴责那些将'A' 当成"A"的人,前者是单个字符,后者是字符串。
鄙视那些,问“字符和字符串有什么区别?”的人,不知道字符和字符串的区别,那你吃过羊肉串吗?
单个羊肉块A能叫串吗,多个羊肉块串A起来才叫串,所以字符是单个,字符串可以是多个字符组成的数组(最后有一个结束符号 \0
需要注意的是字符和字符串的输入与输出格式:
例输入:abcdefgh   
接下来两种输入

while((str = getchar( )) != '\n')      
     i++;
str = '\0';  




scanf(%s,str);   //注意此处‘ &

思考这两种情况 ???


补充:为什么在scanf函数里,有的输入变量前面不用加“&”符号?
学习C的话,一定会接触到2个语句,scanf和printf。
这两个函数都是被定义在头文件stdio.h里的常用函数,在使用的时候需要加上#include<stdio.h>来保证可以成功调用到这2个函数。scanf是格式输入函数,它按照程序猿指定的格式,从键盘上把数据输入到指定的变量之中。
scanf的用法是
1. int a;//声明(待输入)变量a为int(Integer,整形)数据类型,系统会分配一段内存地址给a变量    
2. scanf("%d",&a);//从键盘以十进制的形式(%d,decimal system)格式扫描(scanf,formatted-scan)一个输入量,将之存储在变量a所在的地址(&a)
【%是格式的前缀,%d 十进制有符号整数%u 十进制无符号整数%f浮点数%s 字符串%c 单个字符%p 指针的值%e 指数形式的浮点数%x, %X 无符号以十六进制表示的整数
%0 无符号以八进制表示的整数 %g用来输出实数,它根据数值的大小,自动选%f格式或%e格式(选择输出时占宽度较小的一种),且不输出无意义的0
&是取址运算,&a即取a变量的内存地址。 其实整个scanf函数的核心就是定义扫描的数据为何种格式类型,将之存放在什么位置。
正如前文所说,scanf的目的是将格式化的数据存储到一个地址……“&"运算得到的结果是一个内存地址,我们就是将某个变量写到这个内存地址里去...
在scanf("%s",str)里的str不需要加“&”运算,究其本质则涉及指针的相关知识。定义str[10] 为 char数据类型,则str[10]是一个数组,str表示数组所在的内存段的头地址。
而scanf()函数所需要的地址,其实质就是一段数据所对应的内存段的起始地址,str已经是其数据所在的内存段的头地址,自然不需要“&”取值。当然,加上的话,也不会报错……


关于二维数组


定义格式:数组名[行下标] [列下标
] 图片6.png
a是个二维数组,它有3X4=12个字符元素,
而编译器将它认为是一个一维数组,它有三个元素,分别是a[0], a[1], a[2], 每一个元素是一个含有4个字符的数组       
通过上面的分析可以看出,数组有很多地方很相似,其实,编译器这哥们处理数组的时候就是将其看成指针来处理的,没有办法,编译器只认地址,变量名一直都是被编译器所不接受的。

二维数组的初始化



分行赋初值
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
static int b[4][3] = {{1,2,3},{ },{4,5}};
顺序赋初值        
int a[3][3] = {1,2,3,4,5,6,7,8,9};        
static int b[4][3] = {1,2,3,0,0,0,4,5};


二维数组的遍历


方法是使用一个嵌套循环,通过下标增减进行遍历
for(i = 0; i < n; i++)            
  for(j = 0; j < n; j++)
    a[j]=……;


矩阵
图片7.png


经典数组编程
1>自定义1个函数day_of_year(year, month, day),
计算并返回年        year、月month和日day对应的是该年的第几天。
day_of_year(2000, 3, 1)
返回61
day_of_year(1981, 3, 1)
返回60
分析:                 0    1     2     3 …… 11    12
闰年     0    31   28    31     30    31
闰年       0    31   29    31     30    31
函数部分代码
int day_of_year(int year, int month, int day)
{   
   int k, leap;                   
  int tab[2][13]={              
       {0, 31, 28, 31, 30,31,30,31,31,30,31, 30,31}// 注意该处的‘              
      {0, 31, 29, 31, 30,31,30,31,31,30,31, 30,31}             
};             
leap = (year%4==0&&year%100!=0) || year %400==0;             
for (k=1; k<month; k++)                  
     day = day + tab[leap][k];                  
return day;
}


2>输入一个以回车结束的字符串(少于80个字符),统计其中数字字符的个数。

代码实现:
#include <stdio.h>
int main(void)
{   
   int count, i;            
   char str[80];             
   printf(“Enter a string: ");           
   i = 0;            
   while((str = getchar( )) != '\n')               
   i++;
   str = '\0';  
   count = 0;            
   for(i = 0; str != '\0'; i++)              
   if(str <= '9' && str >= '0')                     
   count++;            
   printf("count = %d\n", count);            
   return 0;
}  

免费评分

参与人数 10吾爱币 +11 热心值 +9 收起 理由
圈瞳 + 1 + 1 用心讨论,共获提升!
CETD + 1 + 1 我很赞同!
ptshj + 1 + 1 用心讨论,共获提升!
yempty + 1 + 1 谢谢@Thanks!
xqlecnu + 1 + 1 我很赞同!
飘零若曦 + 1 用心讨论,共获提升!
czwuyang + 1 + 1 好教程。通俗易懂!谢谢分享!
wanghai123 + 1 + 1 我很赞同!
by_aka + 1 + 1 用心讨论,共获提升!
hejialong + 2 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

zzw0210 发表于 2017-3-22 19:11
好详细啊!
跟楼主探讨一下:“而scanf()函数所需要的地址,其实质就是一段数据所对应的内存段的起始地址,str已经是其数据所在的内存段的头地址,自然不需要“&”取值。当然,加上的话,也不会报错…… ”  str加上&,就不是原来的地址了吧?如果要用&取首地址,应该用&str[0]吧?
zcy99 发表于 2017-3-16 18:34
11053 发表于 2017-3-16 18:52
Mr.Licorne 发表于 2017-3-16 20:10
待老夫仔细观摩一下
LeiSir 发表于 2017-3-16 20:13
不错,都是基础的
阡陌光年 发表于 2017-3-16 20:13 来自手机
感谢分享
飘零若曦 发表于 2017-3-16 20:34
感谢分享,值得学习
xqlecnu 发表于 2017-3-16 20:48
楼主有心了 不错不错
opq_541 发表于 2017-3-16 21:07
数组啊,看楼主这么认真的总结,就想起上学时上的C语言的课程了……
xiaoliu123 发表于 2017-3-18 10:50
感谢楼主,昨天还看到了一个scanf 没有&的。感谢解决疑惑
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 19:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表