精华内容
下载资源
问答
  • PHP 的数组是一种很强大的数据类型,与此同时 PHP 内置了一系列与数组相关的函数可以很轻易的实现日常开发的功能。但是我发现好像很多小伙伴都忽略了内置函数的作用(比如我自己就编写过一些有关数组操作的代码然后...

    PHP 的数组是一种很强大的数据类型,与此同时 PHP 内置了一系列与数组相关的函数可以很轻易的实现日常开发的功能。但是我发现好像很多小伙伴都忽略了内置函数的作用(比如我自己就编写过一些有关数组操作的代码然后发现PHP自带了/(ㄒoㄒ)/~~),善用 PHP 内置函数能极大的提高开发效率和运行效率(内置函数都是用 C 写的效率比用 PHP 写的高很多),所以本文便总结了一些在常见场景中利用 PHP 内置函数的实现方法。此外如果想更深入的学习有关 PHP 数组函数最好还是去查 PHP 手册!点我看官方数组函数手册

    取指定键名

    对于某些关联数组,有时候我们只想取指定键名的那部分,比如数组为 ['id' => 1, 'name' => 'zane', 'password' => '123456'] 此时若只想取包含 id 和 name 的部分该怎么实现呢?下面直接贴代码。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    <?php

    $raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];

    // 自己用 PHP 实现

    function onlyKeys($raw, $keys) {

        $new = [];

        foreach ($raw as $key => $val) {

            if (in_array($key, $keys)) {

                $new[$key] = $val;

            }

        }

         

        return $new;

    }

    // 用 PHP 内置函数实现

    function newOnlyKeys($array, $keys) {

        return array_intersect_key($array, array_flip($keys));

    }

    var_dump(onlyKeys($raw, ['id', 'name']));

    // 结果 ['id' => 1, 'name' => 'zane']

    var_dump(newOnlyKeys($raw, ['id', 'name']));

    // 结果 ['id' => 1, 'name' => 'zane']

    很明显简洁很多有木有!不过 array_intersect_key 和 array_flip 是什么鬼?这里简单的介绍一下这两个函数的作用,首先是 array_flip 函数,这个函数的功能是「将数组的键和值对调」,也就是键名变成值,值变成键名。我们传递的 $keys 参数经过这个函数便从 [0 => 'id', 1 => 'name'] 转变为了 ['id' => 0, 'name' => 1]。这样做的目的是为了向 array_intersect_key 函数服务,array_intersect_key 函数的功能是「使用键名比较计算数组的交集」,也就是返回第一个参数数组中与其他参数数组相同键名的值。这样便实现了取指定键名的功能 ~(≧▽≦)/~啦!当然要详细了解这两个函数的功能还是要查 PHP 官方手册:array_flip array_intersect_key

    移除指定键名

    有了上一个例子做铺垫,这个就简单讲讲啦,道理是大同小异滴。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    <?php

    $raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];

    // 用 PHP 内置函数实现

    function removeKeys($array, $keys) {

        return array_diff_key($array, array_flip($keys));

    }

    // 移除 id 键

    var_dump(removeKeys($raw, ['id', 'password']));

    // 结果 ['name' => 'zane']

    和上一个例子相比本例只是将 array_intersect_key 函数改为 array_diff_key,嗯……相信大家能猜出来这个函数的功能「使用键名比较计算数组的差集」,刚好和 array_intersect_key 的功能相反而已。官方手册:array_diff_key

    数组去重

    这个相信大家都有这个需求,当然 PHP 也内置了 array_unique 函数供给大家使用,如下例:

    1

    2

    3

    4

    5

    <?php

    $input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];

    $result = array_unique($input);

    var_dump($result);

    // 结果 ['you are' => 666, 'i am' => 233]

    嘿,用这个函数就能解决大部分问题了,但是有时候你可能会觉得它不够快,原因如下:

    array_unique() 先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。

    因为这个函数会先将数组进行排序,所以速度可能在某些场景达不到预期的要求。

    现在我们可以祭出我们的黑科技 array_flip 函数,众所周知 PHP 里数组的键名是唯一的,所以在键名和值对调后重复的值便被忽略了。试想一下我们连续调用两次 array_flip 函数是不是就相当于实现了 array_unique 函数的功能呢?示例代码如下:

    1

    2

    3

    4

    5

    <?php

    $input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];

    $result = array_flip(array_flip($input));

    var_dump($result);

    // 结果 ['she is' => 666, 'he is' => 233]

    嗯哼?!结果和 array_unique 的不一样!为什么,我们可以从 PHP 官方手册得到答案:

    如果同一个值出现多次,则最后一个键名将作为它的值,其它键会被丢弃。

    总的来说就是 array_unique 保留第一个出现的键名,array_flip 保留最后一个出现的键名。

    注意:使用 array_flip 作为数组去重时数组的值必须能够作为键名(即为 string 类型或 integer 类型),否则这个值将被忽略。

    此外,若不需要保留键名我们可以直接这样使用 array_values(array_flip($input))

    0x04 重置索引

    当我们想要对一个索引并不连续的数组进行重置时,比如数组:[0 => 233, 99 => 666],对于这种数组我们只需要调用 array_values 函数即可实现。如下例:

    1

    2

    3

    4

    <?php

    $input = [0 => 233, 99 => 666];

    var_dump(array_values($input));

    // 结果 [0 => 233, 1 => 66]

    需要注意的是 array_values 函数并不止重置数字索引还会将字符串键名也同样删除并重置。那如何在保留字符串键名的同时重置数字索引呢?答案就是 array_slice 函数,代码示例如下:

    1

    2

    3

    4

    <?php

    $input = ['hello' => 'world', 0 => 233, 99 => 666];

    var_dump(array_slice($input, 0));

    // 结果 ['hello' => 'world', 0 => 233, 1 => 66]

    array_slice 函数的功能是取出数组的中的一段,但它默认会重新排序并重置数组的数字索引,所以可以利用它重置数组中的数字索引。

    清除空值

    嘿,有时候我们想清除某个数组中的空值比如:nullfalse00.0[]空数组''空字符串'0'字符串0 ,这时 array_filter 函数便能帮上大忙。代码如下:

    1

    2

    3

    4

    <?php

    $input = ['foo', false, -1, null, '', []];

    var_dump(array_filter($input));

    // 结果 [0 => 'foo', 2 => -1]

    为什么会出现这样的结果捏?array_filter 的作用其实是「用回调函数过滤数组中的单元」,它的第二个参数其实是个回调函数,向数组的每个成员都执行这个回调函数,若回调函数的返回值为 true 便保留这个成员,为 false 则忽略。这个函数还有一个特性就是:

    如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。

    等值为 false 就是转换为 bool 类型后值为 false 的意思,详细看文档:转换为布尔类型。

    注意:如果不填写 callback 函数,00.0'0'字符串0 这些可能有意义的值会被删除。所以如果清除的规则有所不同还需要自行编写 callback 函数。

    确认数组成员全部为真

    有时候我们希望确认数组中的的值全部为 true,比如:['read' => true, 'write' => true, 'execute' => true],这时我们需要用一个循环判定吗?NO,NO,NO……只需要用 array_product 函数便可以实现了。代码如下:

    1

    2

    3

    4

    5

    6

    7

    <?php

    $power = ['read' => true, 'write' => true, 'execute' => true];

    var_dump((bool)array_product($power));

    // 结果 true

    $power = ['read' => true, 'write' => true, 'execute' => false];

    var_dump((bool)array_product($power));

    // 结果 false

    为什么能实现这个功能呢? array_product 函数本来的功能是「计算数组中所有值的乘积」,在累乘数组中所有成员的时候会将成员的值转为数值类型。当传递的参数为一个 bool 成员所组成的数组时,众所周知 true 会被转为 1,false 会被转为 0。然后只要数组中出现一个 false 累乘的结果自然会变成 0,然后我们再将结果转为 bool 类型不就是 false 了嘛!

    注意:使用 array_product 函数将在计算过程中将数组成员转为数值类型进行计算,所以请确保你了解数组成员转为数值类型后的值,否则会产生意料之外的结果。比如:

    1

    2

    3

    4

    <?php

    $power = ['read' => true, 'write' => true, 'execute' => 'true'];

    var_dump((bool)array_product($power));

    // 结果 false

    上例是因为 'true' 在计算过程中被转为 0。要想详细了解请点击这里。

    获取指定键名之前 / 之后的数组

    如果我们只想要关联数组中指定键名值之前的部分该怎么办呢?又用一个循环?当然不用我们可以通过 array_keys、array_search 和 array_slice 组合使用便能够实现!下面贴代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    <?php

    $data = ['first' => 1, 'second' => 2, 'third' => 3];

    function beforeKey($array, $key) {

        $keys = array_keys($array);

          // $keys = [0 => 'first', 1 => 'second', 2 => 'third']

        $len = array_search($key, $keys);

        return array_slice($array, 0, $len);

    }

    var_dump(beforeKey($data, 'first'));

    // 结果 []

    var_dump(beforeKey($data, 'second'));

    // 结果 ['first' => 1]

    var_dump(beforeKey($data, 'third'));

    // 结果 ['first' => 1, 'second' => 2]

    思路解析,要实现这样的功能大部分同学都应该能想到 array_slice 函数,但这个函数取出部分数组是根据偏移量(可以理解为键名在数组中的顺序,从 0 开始)而不是根据键名的,而关联数组的键名却是是字符串或者是不按顺序的数字,此时要解决的问题便是「如何取到键名对应的偏移量?」,这是 array_keys 函数便帮了我们大忙,它的功能是「返回数组中部分的或所有的键名」默认返回全部键名,此外返回的键名数组是以数字索引的,也就是说返回的键名数组的索引就是偏移量!例子中的原数组变为: [0 => 'first', 1 => 'second', 2 => 'third'] 。然后我们通过 array_search 便可以获得指定键名的偏移量了,因为这个函数的功能是「在数组中搜索给定的值,如果成功则返回首个相应的键名」。有了偏移量我们直接调用 array_slice 函数便可以实现目的了。

    上面的例子懂了,那获取指定键名之后的数组也就轻而易举了,略微修改 array_slice 即可。直接贴代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    <?php

    $data = ['first' => 1, 'second' => 2, 'third' => 3];

    function afterKey($array, $key) {

        $keys = array_keys($array);

        $offset = array_search($key, $keys);

        return array_slice($array, $offset + 1);

    }

    var_dump(afterKey($data, 'first'));

    // 结果 ['second' => 2, 'third' => 3]

    var_dump(afterKey($data, 'second'));

    // 结果 ['third' => 3]

    var_dump(afterKey($data, 'third'));

    // 结果 []

    那如何获取指定值之前或之后的数组呢?嘿,记得 array_search 的作用吧,其实我们只需要这样调用 beforeKey($data, array_search($value, $data)) 不就实现了嘛!

    数组中重复次数最多的值

    敲黑板,划重点!据说这是一道面试题喔。假设有这样一个数组 [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8],请问如何获取数组中重复次数最多的值?关键就在于 array_count_values 函数。实例代码如下:

    1

    2

    3

    4

    5

    6

    7

    8

    <?php

    $data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];

    $cv = array_count_values($data);

    // $cv = [6 => 2, 11 => 4, 2 => 2, 4 => 3, 7 => 1, 8 => 1]

    arsort($cv);

    $max = key($cv);

    var_dump($max);

    // 结果 11

    array_count_values 函数的功能是「统计数组中所有的值」,就是将原数组中的值作为返回数组的键名,值出现的次数作为返回数组的值。这样我们便可以通过 arsort 函数对出现的次数进行降序排序并且保持索引关联。最后使用 key 获得当前单元(当前单元默认为数组第一个成员)的键名,此时的键名即是原数组的值重复次数最多的值。

    总结

    虽然 PHP 提供了很多和数组相关的函数,但使用起来还是不算太方便而且都是通过函数的调用方式而没有面向对象相关的实现,所以我最近在写一个开源的工具类项目 zane/utils,封装了一些常用的方法并且支持链式调用,其中的 Ary 类实现 「获取数组中重复次数最多的值」只需一行,如下所示:

    1

    2

    3

    4

    $data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];

    $max = Ary::new($data)->countValues()->maxKey();

    var_dump($max);

    // 结果 1

    转载于:https://www.cnblogs.com/liangzia/p/9930057.html

    展开全文
  • 前言:数组有很多的方法,都很简单方便,向push,pop等等,但是对于高阶函数在实际使用的很多,现在就来总结一下方法使用及场景首先,什么是高阶函数:高阶函数,就是函数可以传入另一个函数作为参数的函数。...

    前言:数组有很多的方法,都很简单方便,向push,pop等等,但是对于高阶函数在实际使用用的很多,现在就来总结一下方法使用及场景首先,什么是高阶函数:高阶函数,就是函数中可以传入另一个函数作为参数的函数。

     

    1.forEach

      forEach是对数组每个数据进行遍历,与for的差别是,for可以将遍历的数组的每一项修改,而forEach并不会改变原数组(如果是数组对象值的修改,forEach也修改到对象的值)

     简单的使用 - 数组中的某个数据为判断依据修改其他数据

      let arr = [  {name:1}, {name:2}, {name:3},{name:4}];  
            let num;       
            arr.forEach((item,index) => { 
                 if(item.name === 1){
                     num = 10          
                   }});
    
    

     

    2.filter

      filter筛选出满足条件的数组,满足条件 === 返回写的条件为true的每一项组成一个新的数组,并不会改变原数组简单的使用 - 筛选出数组中number大于8的数字

     let arr = [
     { name: 'a', number: 12 },
     { name: 'b', number: 8 },
     { name: 'c', number: 7 }, 
     { name: 's', number: 5 }]
    
     let arr1 = arr.filter((item, index) => { return item.number > 8 })
    
    

    这时的数组的每一项只有大于8的对象

    注意:filter.不管你的返回条件是什么,他都会返回满足条件的数组的某个整体元素,比如

       let arr = [    
             { name: 'c', id: 1 },      
             { name: 'c', id: 3 },       
             { name: 'c', id: 8 }        ]       
    
          let arr2 = [1, 5]       
          let a = arr.filter(item => arr2.includes(item.id))     
    
           console.log(a)
    
    

    这个时候返回的满足条件(数组中含有id为1,5)的整个对象 {name: 'c', id: 1 }

     

    3.map

      map遍历,返回处理过的数组的每一项组成一个新的数组(需要数组的每一项的时候一般都会用到map),通常应用于对数组的对象进行重新组合,或者需要向数组添加新数据,比如在react中使用map进行遍历

    简单的实例 1  - 将一个数组对象的数据进行重新组合

     let arr = [
              { name: 'a', age: 15, fav: "篮球" },
              { name: 'b', age: 15, fav: "足球" },
              { name: 'c', age: 15, fav: "乒乓球" }, 
              { name: 'd', age: 15, fav: "排球" },  
              { name: 'e', age: 15, fav: "羽毛球" }]; 
    
          let arr1 = arr.map((item, index) => { 
           return { pepleName: item.name, myFav: item.fav, index: index + 1 }})
    

      打印arr1 - 是数据重构之后的数组

    简单的实例 2 - 向数组添加新数据

     let arr = [ 
             { name: 'a', age: 15, fav: "篮球" },  
             { name: 'b', age: 15, fav: "足球" },  
             { name: 'c', age: 15, fav: "乒乓球" },  
             { name: 'd', age: 15, fav: "排球" },  
             { name: 'e', age: 15, fav: "羽毛球" }];
    
           let arr1 = arr.map((item, index) => {   
            return { ...item, index: index + 1 } })
    

    当然利用深拷贝结合map ,将返回语句替换一个,结果都是一样的

     return Object.assign(item,{index:index+1})

    打印-arr1

    简单实例 3 - 将数组利用索引对应起来

      let arr = [  
              { name: 'a', age: 15, fav: "篮球" }, 
              { name: 'b', age: 15, fav: "足球" },  
              { name: 'c', age: 15, fav: "乒乓球" },  
              { name: 'd', age: 15, fav: "排球" },  
              { name: 'e', age: 15, fav: "羽毛球" }];       
    
          let arr1 = [  
            { key: '1', val: 'sss' },   
            { key: '2', val: 'fsd' },   
            { key: '3', val: 'fds' }, 
            { key: '4', val: 'fewf' },  
            { key: '5', val: 'ewd' }]  
    
         let arr2 = arr.map((item, index) => {  
             return { ...arr1[index], ...item } }); 
    

    打印arr2 -

    注意:小坑 - map会返回undeifed

    例如:

      let arr = [   
             { name: 'c', id: 1 },  
             { name: 'c', id: 3 },  
             { name: 'c', id: 8 }    ]      
    
         let arr2 = [1, 5]        
    
        let a = arr.map((item) => {  
          if (arr2.includes(item.id)) {    
             return item.id  } })
    

    这个时候的a,会是[1,undefined,undefined],即便没有没有满足条件,他也会返回

     

    4.sort

      sort是将数组进行排序,主要是根据传入的函数进行排序,最简单的就是数字排序

      简单实例 - 1 - 数字排序

            let arr = [1, 5, 2, 8, 10, 53, 9, 4]      
            let arr2 = arr.sort((a, b) => { return a - b }) 
            let arr3 = arr.sort((a, b) => { return b - a })
    

    打印arr2,arr3 - 一个升序,一个降序

    简单白话解释 - 给sort方法传递一个比较函数,而这个函数决定了它的两个参数(a,b)在排好序的数组中的先后顺序:假设第一个参数应该在前,比较函数应该返回一个小于0的数值,反之,假设第一个参数应该在后,函数应该返回一个大于0的数值,并且,假设两个值相等,函数应该返回0。可以利用这个做复杂一点的排序

    简单案例 - 2  - 

          let arr = [  
              { name: 'a', score: 85 },  
              { name: 'b', score: 56 },   
              { name: 'c', score: 68 },    
              { name: 'd', score: 89 },   
              { name: 'e', score: 88 }]        
    
          let arr2 = arr.sort((a, b) => {    
            if (a.score > b.score) {       
               return 1  //第二参数在前面           
             } if (a.score < b.score) {     
               return -1  //第一个参数在前面,小的在前面     
            } else {       
               return 0   }})
    
    

     进行简写 - 

    let arr2 = arr.sort((a, b) => {          
            if (a.score === b.score) 
               { return a.score - b.score }       
               return a.score - b.score })
    

     

     

    下面是检测数组中的元素是否满足条件,最后需要boolean的一些高阶函数

     

    5.some

    some方法会检测,返回布尔值,不改变原数组。在执行中,有一个满足就返回true,不再继续执行

    简单案例 - 检查数组对象中是否含有某个值

      let arr = [ 
            { name: 'a', age: 15},  
            { name: 'c', age: 55}
            { name: 'v', age: 14},   
            { name: 'd', age: 18} ]   
    
         arr.some(item => item.name.includes('a'))
    
    

    检测数组,当检测到第一个对象有a,直接返回true

     

    6.every

      与some不同,它会去检测数组中的每一项是否满足条件,所有都满足才会返回true

      简单案例 - 检测数组中的所有对象是否满足条件

      let arr = [  
          { name: 'a', age: 15},   
          { name: 'c', age: 55},        
          { name: 'v', age: 14},         
          { name: 'd', age: 18} ]
    
       arr.every(item => item.age>10)
    
    

     

    7.reduce

    会对数组中的元素进行回调函数中的方法,经常都用于累加

    简单实例 - 数组的累加

        let arr = [1,5,8,2,10 ]       
    
        let a =  arr.reduce((total,num)=>{   
             return total+num        })  
    
        console.log(a)
    
    

     同理 - 可以累乘,将total理解为数组的第一个对象,num是第二个,然后对其进行操作,循环,第二次的total就是已经执行了函数的数据,num就是第三个值

     

    8.find

    找出数组中满足条件项,找到一项直接返回满足条件的项,不在进行往下寻找

    简单案例

           let arr = [   
             { name: 'a', age: 15},    
             { name: 'c', age: 55},
             { name: 'v', age: 14}, 
             { name: 'd', age: 18} ]      
    
            let a =  arr.find(item => item.age>10)     
            console.log(a)
    

    将打印数组中第一项

    展开全文
  • C语言 图解数组

    2018-10-12 21:10:31
    1.哪些问题会用到数组循环结构来引用数组里的元素。 接招看题019: 在循环中用scanf函数分别给数组的每一个元素赋值。 接招看题020: 接招看题021:把一个整数按大小的顺序插入到已排好序的数组中。为了把...

    牛刀小试:大叔不要闹哈哈
    十.字符串及其结束标志是什么?
    所谓字符串,是指若干有效字符的序列。C语言中的字符串,可以包括字母、数字、专用字符、转义字符等。
    C语言规定:以’\0’作为字符串结束标志(’\0’代表ASCII码为0的字符,表示一个"空操作",只起一个标志作用)。
    在这里插入图片描述
    在这里插入图片描述

    1.哪些问题会用到数组?
    用循环结构来引用数组里的元素。
    接招看题020:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    接招看题021:把一个整数按大小的顺序插入到已排好序的数组中。
    为了把一个数按大小插入到已排好序的数组中,我们应该首先要确定排序是从大到小还是从小到大。
    假设排序是从大到小进行的,那么可以把想要插入的数与数组中各数进行比较,当找到第一个比插入数小的元素i时,该元素之前即为插入位置。然后从数组最后一个元素开始到该元素为止,逐个后移一个单元。最后把插入数赋予元素i即可。如果被插入数比所有的元素的值都小,则插入到最后的位置。
    在这里插入图片描述
    一.1维数组的形式是什么?
    图解一维数组:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    文字描述:
    1维数组是只有1个下标的数组,定义形式如下:
    数据类型 数组名[常量表达式];
    (1)"数据类型"是指数组元素的数据类型。
    (2)数组名,与变量名一样,必须遵循标识符命名规则。
    (3)"常量表达式"必须用方括号括起来,指的是数组的元素个数(又称数组长度),它是一个整型值,其中可以包含常数和符号常量,但不能包含变量。
    图解:
    在这里插入图片描述
    注意:C语言中不允许动态定义数组。
    特别说明:在数组定义时,"常量表达式"外的方括号;以及元素引用时,“下标表达式"外的方括号,都是C语言语法规则所要求的,不是本书所约定的可选项的描述符号!
    (4) 组元素的下标,是元素相对于数组起始地址的偏移量,所以从0开始顺序编号。
    (5) 数组名中存放的是一个地址常量,它代表整个数组的首地址。同一数组中的所有元素,按其下标的顺序占用一段连续的存储单元。
    二.如何引用数组里的元素?
    引用数组中的任意一个元素的形式:

    数组名[下标表达式]
    1.“下标表达式"可以是任何非负整型数据,取值范围是0~(元素个数-1)。
    特别强调:在运行C语言程序过程中,系统并不自动检验数组元素的下标是否越界。因此在编写程序时,保证数组下标不越界是十分重要的。
    2.1个数组元素,实质上就是1个变量,它具有和相同类型单个变量一样的属性,可以对它进行赋值和参与各种运算。
    3.在C语言中,数组作为1个整体,不能参加数据运算,只能对单个的元素进行处理。
    图解:
    在这里插入图片描述
    在这里插入图片描述
    三.如何初始化一维数组的元素?
    初始化格式:
    数据类型 数组名[常量表达式]={初值表}
    (1)如果对数组的全部元素赋以初值,定义时可以不指定数组长度(系统根据初值个数自动确定)。如果被定义数组的长度,与初值个数不同,则数组长度不能省略。
    (2)“初值表"中的初值个数,可以少于元素个数,即允许只给部分元素赋初值。
    (3)根据存储类型的不同,数组有静态数组(static)和动态数组(auto)之分;根据定义的位置不同,数组有内部数组(在函数内部定义的数组)和外部数组(在函数外部定义的数组)之分。
    四.如何定义二维数组?
    二维数组的定义方式如下:
    数据类型 数组名[行常量表达式][列常量表达式][, 数组名2[行常量表达式2][列常量表达式2]……];
    1.数组元素在内存中的排列顺序为"按行存放",即先顺序存放第一行的元素,再存放第二行,以此类推。
    2. 设有一个mn的数组x,则第i行第j列的元素x[i][j]在数组中的位置为:in+j(注意:行号、列号均从0开始计数)。
    3.可以把2维数组看作是一种特殊的1维数组:它的元素又是一个1维数组。
    例如,对x[3][2],可以把x看作是一个1维数组,它有3个元素:x[0]、x[1]、x[2],每个元素又是一个包含2个元素的1维数组,如图6-4所示。即把x[0]、x[1]、x[2]看作是3个1维数组的名字。
    五.如何引用二维数组?
    引用2维数组元素的形式为:
    数组名[行下标表达式][列下标表达式]
    1.“行下标表达式"和"列下标表达式”,都应是整型表达式或符号常量
    2.“行下标表达式"和"列下标表达式"的值,都应在已定义数组大小的范围内。假设有数组x[3][4],则可用的行下标范围为02,列下标范围为03
    3.对基本数据类型的变量所能进行的操作,也都适合于相同数据类型的2维数组元素。
    六.如何初始化二维数组?
    图解:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    案例:
    在这里插入图片描述
    1.按行赋初值
    数据类型 数组名[行常量表达式][列常量表达式]={{第0行初值表},{第1行初值表},……,{最后1行初值表}};
    赋值规则:将"第0行初值表"中的数据,依次赋给第0行中各元素;将"第1行初值表"中的数据,依次赋给第1行各元素;以此类推。
    2.按2维数组在内存中的排列顺序给各元素赋初值
    数据类型 数组名[行常量表达式][列常量表达式]={初值表};
    赋值规则:按2维数组在内存中的排列顺序,将初值表中的数据,依次赋给各元素。
    如果对全部元素都赋初值,则"行数"可以省略。注意:只能省略"行数"。
    图解二维数组:
    在这里插入图片描述
    在这里插入图片描述
    七.什么是字符数组?
    1维字符数组,用于存储和处理1个字符串,其定义格式与1维数值数组一样。
    2维字符数组,用于同时存储和处理多个字符串,其定义格式与2维数值数组一样。
    图解:
    在这里插入图片描述
    八.如何初始化字符数组?
    字符数组的初始化,可以通过为每个数组元素指定初值字符来实现。
    在这里插入图片描述
    九.如何引用字符数组?
    图解:
    在这里插入图片描述
    少了结束符。嗯哼,你忽略了‘\0’没有?在这里插入图片描述
    问题在这里:
    在这里插入图片描述
    字符数组的逐个字符引用,与引用数值数组元素类似。
    (1)字符数组的输入
    除了可以通过初始化使字符数组各元素得到初值外,也可以使用getchar()或scanf()函数输入字符。
    例如:
    char str[10];
    ……for(i=0; i<10; i++)
    { scanf("%c", &str[i]);

    fflush(stdin); /清除键盘输入缓冲区/
    }
    ……
    (2)字符数组的输出
    字符数组的输出,可以用putchar()或printf()函数。
    例如:
    char str[10]=“c language”;
    ……for(i=0; i<10; i++) printf("%c", str[i]);
    printf(”\n”);
    ……注意:逐个字符输入、输出时,要指出元素的下标,而且使用”%c"格式符。另外,从键盘上输入字符时,无需输入字符的定界符──单引号;输出时,系统也不输出字符的定界符。
    十.字符串及其结束标志是什么?
    所谓字符串,是指若干有效字符的序列。C语言中的字符串,可以包括字母、数字、专用字符、转义字符等。
    C语言规定:以’\0’作为字符串结束标志(’\0’代表ASCII码为0的字符,表示一个"空操作”,只起一个标志作用)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    再强调一次:
    在这里插入图片描述
    在这里插入图片描述
    案例:

    因此可以对字符数组采用另一种方式进行操作了──字符数组的整体操作。
    注意:由于系统在存储字符串常量时,会在串尾自动加上1个结束标志,所以无需人为地再加1个。
    另外,由于结束标志也要在字符数组中占用一个元素的存储空间,因此在说明字符数组长度时,至少为字符串所需长度加1。
    深度理解:
    在这里插入图片描述
    十一.如何整体引用字符数组?
    (1)字符串的输入
    除了可以通过初始化使字符数组各元素得到初值外,也可以使用scanf()函数输入字符串。
    举例子:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    (2)字符串的输出
    printf()函数,不仅可以逐个输出字符数组元素,还可以整体输出存放在字符数组中的字符串。

    十二.八个与数组相关的函数
    在这里插入图片描述
    gets()函数
    (1)调用方式:gets(字符数组)
    (2)函数功能:从标准输入设备(stdin)──键盘上,读取1个字符串(可以包含空格),并将其存储到字符数组中去。
    (3)使用说明
    1)gets()读取的字符串,其长度没有限制,编程者要保证字符数组有足够大的空间,存放输入的字符串。
    2)该函数输入的字符串中允许包含空格,而scanf()函数不允许。


    puts()函数
    (1)调用方式:puts(字符数组)
    (2)函数功能:把字符数组中所存放的字符串,输出到标准输出设备中去,并用’\n’取代字符串的结束标志’\0’。所以用puts()函数输出字符串时,不要求另加换行符。
    (3)使用说明
    1)字符串中允许包含转义字符,输出时产生一个控制操作。
    2)该函数一次只能输出一个字符串,而printf()函数也能用来输出字符串,且一次能输出多个。


    在这里插入图片描述
    strcmp()函数
    (1)调用方式:strcmp(字符串1 ,字符串2)
    其中"字符串"可以是串常量,也可以是1维字符数组。
    (2)函数功能:比较两个字符串的大小。
    如果:字符串1=字符串2,函数返回值等于0;
    字符串1<字符串2,函数返回值负整数;
    字符串1>字符串2,函数返回值正整数。
    (3)使用说明
    1)如果一个字符串是另一个字符串从头开始的子串,则母串为大。
    2)不能使用关系运算符"=="来比较两个字符串,只能用strcmp() 函数来处理。
    strlen()函数
    (1)调用方式:strlen(字符串)
    (2)函数功能:求字符串(常量或字符数组)的实际长度(不包含结束标志)


    在这里插入图片描述
    strcpy()函数
    (1)调用方式:strcpy(字符数组, 字符串)
    其中"字符串"可以是串常量,也可以是字符数组。
    (2)函数功能:将"字符串"完整地复制到"字符数组"中,字符数组中原有内容被覆盖。
    (3)使用说明
    1)字符数组必须定义得足够大,以便容纳复制过来的字符串。复制时,连同结束标志’\0’一起复制。
    2)不能用赋值运算符"="将一个字符串直接赋值给一个字符数组,只能用strcpy()函数来处理。
    在这里插入图片描述


    strcat()函数
    (1)调用方式:strcat(字符数组, 字符串)
    (2)函数功能:把"字符串"连接到"字符数组"中的字符串尾端,并存储于"字符数组"中。"字符数组"中原来的结束标志,被"字符串"的第一个字符覆盖,而"字符串"在操作中未被修改。
    (3)使用说明
    1)由于没有边界检查,编程者要注意保证"字符数组"定义得足够大,以便容纳连接后的目标字符串;否则,会因长度不够而产生问题。
    2)连接前两个字符串都有结束标志’\0’,连接后"字符数组"中存储的字符串的结束标志’\0’被舍弃,只在目标串的最后保留一个’\0’。


    strlwr()函数
    (1)调用方式:strlwr(字符串)
    (2)函数功能:将字符串中的大写字母转换成小写,其它字符(包括小写字母和非字母字符)不转换。


    strupr()函数
    (1)调用方式:strupr(字符串)
    (2)函数功能:将字符串中小写字母转换成大写,其它字符(包括大写字母和非字母字符)不转换。


    冒泡法排序:
    在这里插入图片描述
    在这里插入图片描述

    明天会继续更新。2018-10-12.

    1. 如何定义十量级,百量级和千量级的变量个数?
    2. 如何使用这些变量?
    3. 如何给这数量级的变量赋初值?有哪些方法?详情见数组+逆向思维求解逆序问题的博客。
    展开全文
  • 学习完复杂的数据类型的设计思路和使用习惯,就开始面向对象的学习。 1.数组 ...下面C++实现一个试用数组的任务,并谈谈在使用中有哪些地方需要注意。 编程任务:定义一个数组容纳十个整数,...

    学习完复杂的数据类型的设计思路和使用习惯,就开始面向对象的学习。

    1.数组

    数组是许多程序设计语言的重要组成部分,尤其是在C语言程序里会经常碰到他们。

    数组的优点在于,一个数组可以把多个同类型的值存储在同一变量名下,需要被声明为一种特定的类型。type name[length].

    下面用C++实现一个试用数组的任务,并谈谈在使用中有哪些地方需要注意。

    编程任务:定义一个数组容纳十个整数,这些整数来自用户的输入,我们将这些值的累加和,平均值计算并输出

    #include<iostream>
    
    using namespace std;
    
    int main(){
    	int array[10];
    	float total=0;
    	cout<<"请输入10个整形数据:\n\n";
    	
    	for(int i=0;i<10;i++){
    		cout<<"请输入第"<<i+1<<"个数据:";
    		cin>>array[i];
    		
    		total += array[i];
    	}
    	cout<<"累加和是:"<<total;
    	cout<<"\n平均值是:"<<total/10;
    	return 0;
    } 

    可是很显然,这个程序很不成熟,通用性也不强,所以就要对他做进一步的改进。

    下面改进的代码

    1. 对数组的长度做了宏定义,或者也可以用静态变量(const unsigned short ITEM=5)。
    2. 再者就是对输入的数据做了一个检查,如果输入的数据不合法的话,就要进行异常处理。前面几个笔记里已经讲过cin>>array[i]如果调用成功的话返回值是1,否则是0.所以要充分利用这个特点,当其调用不成功的时候就要对它做异常处理---while语句块里的内容,但是在这里十分必要的一个语句是cin.clear(),这个函数可不是用来清除缓冲区的。
    3. cin.clear()默认参数为0,即无错误,正常操作.我们可以继续输入,用cin来读取。但是当我们输入英文字母'k'时,不是int型,它的状态标识改为fail,即错误,这时候cin就不能再正常读取了,我们也无法输入了。在这里用cout对用户输出信息,再用cin.clear让错误标识改回为0,让我们可以继续输入,再清空流数据继续输入(ignore).如果我们没有了cin.clear,则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且我们再也没办法输入,因为错误的表示关闭了cin,所以会进入死循环.
    #include<iostream>
    #define ITEM 5
    
    using namespace std;
    
    int main(){
    //	const unsigned short ITEM=5; 这句和开头的宏定义起的作用差不多一样 根据自己的喜好二选一
    	
    	int array[ITEM];
    	float total=0;
    	cout<<"请输入"<<ITEM<<"个整形数据:\n\n";
    	
    	for(int i=0;i<ITEM;i++){
    		cout<<"请输入第"<<i+1<<"个数据:";
    		
    		while(!(cin>>array[i])){//对输入数据做检查
    			
    			cout<<"请重新输入一个合法的值!\n";
    			cin.clear();//将错误的标识符重新改为0 否则就会陷入死循环 
    			cin.ignore(100,'\n');//清除缓冲区的内容 
    		};
    		
    		
    		total += array[i];
    	}
    	cout<<"累加和是:"<<total;
    	cout<<"\n平均值是:"<<total/ITEM;
    	return 0;
    } 

     在C语言里,字符被实际存储在一个字符数组里。在C++里我们可以用同样的方式来实现字符串的存储,但是我们一把不用,因为它提供了一个更好的std::string类型。

    编程任务:分别尝试用C和C++实现将用户输入的字符串打印出来

    //C语言
    
    #include<stdio.h>
    
    int main(){
    	const unsigned short LENGTH = 100;
    	char str[LENGTH];
    	gets(str);
    	puts(str);
    }
    

    下面用C++来实现,比较两次输入发现第一次输出只有I,第二次全部输出,说明cin>>str接收到空格的时候就以为要停止了。所以用getline()来获取一段字符串  。

    //C++错误示范
    #include<iostream>
    #include<string>
    int main(){
    	std::string str;
    	std::cout<<"请任意输入一段字符串:\n";
    	std::cin>>str;
    	std::cout<<str;
    	
    	return 0;
    } 
    
    //输入:I love C++!
    //输出:I
    //输入:IloveC++
    //输出:IloveC++
    
    

     getline():

    getline()的原型是istream& getline ( istream &is , string &str , char delim );其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\n',也就是回车换行符(遇到回车停止读入)。

    //C++正确示范
    #include<iostream>
    #include<string>
    int main(){
    	std::string str;
    	std::cout<<"请任意输入一段字符串:\n";
    	std::getline(std::cin,str);
    	
    	std::cout<<str<<"\n";
    	
    	return 0;
    } 
    
    //输入:I love C++!
    //输出:I love C++!
    

    关于getline()函数的进一步解释:

    //getline()函数,在C++premer中,标准string类型第二小节就是“用getline读取整行文本”。书上给的程//序如下:
    
    int main()
    {
        string line:
        while(getline(cin,line))
        cout<<line<<endl;
        return 0;
    }
    
    /*
    大家会发现运行时怎么也跳不出循环,甚至会发生各种莫名其妙的错误。这是为什么呢?在这里我给大家做一个详细的讲解。
    
    首先给大家介绍一下getline()函数(个人觉得百度百科给的果断不够详细)
    
    大家百度会发现getline()的原型是istream& getline ( istream &is , string &str , char delim );
    
    其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\n',也就是回车换行符(遇到回车停止读入)。给大家举个例子:
    */
    
    string line;
    cout<<"please cin a line:"
    getline(cin,line,'#');
    cout<<endl<<"The line you give is:"line;
    
    /*
    那么当我输入"You are the #best!" 的时候,输入流实际上只读入了"You are the ",#后面的并没有存放到line中(应该是在缓冲区里吧)。然后程序运行结果应该是这样的:
    */
    
    please cin a line:You are the #best!
    The line you give is:You are the 
    /*
    
    而且这里把终止符设为#,你输入的时候就算输入几个回车换行也没关系,输入流照样会读入,譬如*/
    please cin a line:You are the best!
    //这里输入了一个回车换行
    Thank you!
    # //终止读入
    
    The line you give is:You are the best!
    //换行照样读入并且输出
    Thank you!
    
    /*
    以上就是getline()函数一个小小的实例了。
    
    那么如果把getline()作为while的判断语句会怎么样呢?
    
    让我们一起来分析一下while(getline(cin,line))语句
    
    注意这里默认回车符停止读入,按Ctrl+Z或键入EOF回车即可退出循环。
    
    在这个语句中,首先getline从标准输入设备上读入字符,然后返回给输入流cin,注意了,是cin,所以while判断语句的真实判断对象是cin,也就是判断当前是否存在有效的输入流。在这种情况下,我想只要你的电脑不中毒不发神经你的输入流怎么会没有效?所以这种情况下不管你怎么输入都跳不出循环,因为你的输入流有效,跳不出循环。
    
    然而有些同学误以为while判断语句的判断对象是line(也就是line是否为空),然后想通过直接回车(即输入一个空的line)跳出循环,却发现怎么也跳不出循环。这是因为你的回车只会终止getline()函数的读入操作。getline()函数终止后又进行while()判断(即判断输入流是否有效,你的输入流当然有效,满足条件),所以又运行getline()函数,所以,就这样....
    */

    C++里关于string类的内建功能非常多,例如

    1. 提取子字符串:

      string常用截取字符串方法有很多,但是配合使用以下两种,基本都能满足要求:

      find(string strSub, npos);

      find_last_of(string strSub, npos);

      其中strSub是需要寻找的子字符串,npos为查找起始位置。找到返回子字符串首次出现的位置,否则返回-1。

    2. strmap(str1,str2):比较字符串1和字符串2是否想等。返回一个整数。(1)如果返回0则说明字符串1和字符串2相等(2)如果返回的数为正整数,则说明字符串1大于字符串2(3)如果返回的数为负整数,则说明字符串1小于字符串2

    3. strcat(str1,str2);

      将两个字符串连接起来。如a[3]={'a','b'};b[3]={'c','d'};cout<<strcat(a,b)<<endl;

       

       

    展开全文
  • Javascript中的参数内部是一个数组来表示的,函数接收到的始终都是这个数组,不关心这个数组中有哪些参数(数组中有无数据都可以)。因此,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数...
  • 文章来源文章来自:php自学中心链接:...方法一fsockopen打开一个网络连接,打开成功后会返回一个文件句柄,然后可以使用fread函数读取文件的内容,使用fwrite函数把文件写到本地(...
  • 文章目录案例说明1、最平凡:数组索引访问2、最伤脑:二次遍历-列表生成器3、最灵巧:活用函数sum()为什么sum()还可以这样玩?4、最省心:一步到位,Numpy.flatmap()注意, flatten()与 ravel()的区别 案例说明 分享...
  • 【单选题】设有函数调用语句“fun(x1,(x2,x3,x4));”其函数的形参和实参的个数分别为( )。【填空题】java 应用程序中有...这些力学特性通常用哪些指标来表示?【简答题】什么是岩体?【填空题】在函数定义或者声明前加...
  • 归并排序和树状数组可以用nlogn的算法做到求出逆序对.但这里着重讲树状数组的原理与求法. 树状数组最常用的方面就是用来求逆序对, 普通方法需要n^2的复杂度, 而树状数组只需要用nlogn的复杂度, 所以是很好的优化,...
  • 作者:李学凯在对 Java 代码进行优化的时候,想方设法的要提高整体的效率,使用 JProfiler 看代码的时间占比,然后,看看哪些部分是可以优化的,减少运行时间的。下面有这么几个方向。1、能使用构造函数一步到位的,...
  • Lambda表达式可以用哪些地方? lambda表达式可以用于具有目标类型的任何上下文。有目标类型的上下文是指: 1 变量声明,赋值和数组的初始化,其目标类型是被赋值的类型(或数组类型); 2 return语句,目标...
  • 队列可以用哪些地方? 一、队列是什么? 队列是一种数据结构,跟生活中的排队是一样的,符合先进先出,后进后出的原则 即:对一个数组做一些限制: 1、只允许在后面插入数据,只允许在前面删除数据 2、不允许在...
  • 即:对一个数组做一些限制: 1、只允许在后面插入数据,只允许在前面删除数据 2、不允许在后面删除数据,也不允许在前面插入数据,也不允许在中间随便插入和删除数据. 二、jQuery的队列函数:queue(); jQuery的...
  • 这次给大家带来封装一个可以获取元素文本内容的函数,封装一个可以获取元素文本内容函数的注意事项有哪些,下面就是实战案例,一起来看一下。A.1 逻辑步骤目标: 获取某元素的 所有同级+元素节点S1 获取某的父元素...
  • 因此可以被取地址:变量可寻址的结构体的字段可寻址的数组的元素任意切片的元素(无论是可寻址切片或不可寻址切片)指针解引用操作示例:Go中以下的值是不可寻址的:字符串的字节元素映射元素接口值的动态值(类型断言...
  • 全局变量,需要使用"::",局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数可以定义多个同名的局部变量,比如在两个循环...
  • 函数的参数

    2018-02-03 21:51:00
    函数接收到的始终是这个数组,而不关心数组中包含哪些参数和参数的个数。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。 arguments对象 这个对象只是和数组类似,并...
  • 函数接收到的始终是这个数组,而不关心数组中包含了哪些参数。 arguments访问参数数组函数的体内可以通过arguments这个对象来访问这个参数数组,来获取传递给数组的每一个参数。 arguments与数组类似(但不是...
  • 编程序,从键盘输入某个C++源程序文件名,而后通过getline依次读入该文件中的各行(假设每行都不...若二维字符数组A中的关键字是按“从小到大”的顺序存放的话,则还可以使用折半查找方法在A中进行“查找”以提高速度。
  • 函数可以不写参数,在体内arguments[ ]代替 arguments对象的值与参数的值双向同步 未传递值的命名参数,值为undefined 第一个特点: ECMAScript的参数在内部是一个数组表示的,函数接收到的是数组,而不关心...
  • JavaScript函数参数理解

    2019-04-09 10:21:02
    JavaScript函数参数理解 参见《JS高级程序设计》 ECMAScript函数不介意传递进来多少参数,也不在乎传进来的参数是什么...函数接收到的始终都是这个数组,而不关心数组中有哪些参数。在函数体内可以通过arguments...
  • 以前我一直用os.system()处理一些系统管理任务,因为我认为那是运行linux命令最简单的方式. 我们能从Python官方文档里读到应该用subprocess 模块来运行系统...我们可以用数组作为参数运行命令,也可以用字符串
  • javaScript中函数的参数

    2018-05-14 17:56:19
    函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话),在函数体内可以通过 arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数,arguments 对象只是与数组类似(它并不是 ...
  • 1.linux两个实用常用命令df -h:统计整体磁盘情况du -sh:看单独目录点情况2.Python流行的第三方库numpy:使用NumPy,就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和...
  • JavaScript中的函数传参

    2017-07-12 15:53:37
    但是在调用时未必一定要传递两个参数,可以传递一个,三个,甚至不传,因为传进来的参数都在内部是一个数组来表示,函数接收的始终是这个数组,而不关心数组中包含哪些参数。在函数体内可以通过arguments对象来...
  • js函数的参数

    2016-03-21 11:30:00
    js函数的参数: js是弱类型的编程语言,调用函数时既不在乎函数的参数,也不在意参数的类型即便你定义的函...函数接受到的永远是这个数组,而不关心数组中包含哪些参数(如果有参数的话)如果这个数组中不包含任何元素...
  • ECMAScript函数的参数与大多数...  原因是ECMAScript中的参数在内部是一个数组表示的,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数。如果这个数组中不包含任何元素,没有关系;如果包含多个元素,也
  • javascript函数”重载”

    2019-07-17 17:36:23
    问题:js函数是没有重载...函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过argum...
  • 3.4-函数参数

    2014-07-08 13:32:52
     javaScript函数不介意传递进来多少个参数,也就是说,即便你定义的函数形参只有两...函数接收到的始终都是这个类数组对象,而不关心数组中包括哪些参数。实际上,在函数体内可以通过arguments对象来访问这个参数...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 353
精华内容 141
关键字:

哪些函数可以用数组