C/C++入门005-C语言数组

简介: C/C++入门005-C语言数组

参考:https://blog.csdn.net/weixin_44617968/article/details/117656810


C语言数组


数组的基本概念及定义


数组定义

数组,从字面上看,就是一组具有相同类型的数据,在C语言中,数组属于构造数据类型。


数组中的几个名词

int 为类型标识

arr 为变量名称

[10] 表示数组大小

{1,2,3} 表示初始化

如果初始化长度和定义时长度不一致,后面的默认为0


案例代码:

 //    int arr[10];
    int arr[5] = {1,2,3}; // 定义并初始化数组
    for(int i =0; i<5;i++)
    {
        printf("%d \n",arr[i]); //输出下标对应的数组
    }
    for(int i =0; i<5;i++)
    {
        printf("%d \n",&arr[i]);
    }
        for(int i =0; i<5;i++)
    {
        printf("%p \n",&arr[i]);// 输出内存地址
    }

输出为:

a06d58679464d1192c87f59d9b44df1a_ed07fb6f2db0497abc8c8bd9d04e0dca.png


数组长度计算方法

因为数组在内存中占用的字节数取决于其存储的数据类型和数据的个数


数组所占用存储空间 = 一个元素所占用存储空间 * 元素个数(数组长度)

所以计算数组长度可以使用如下方法

数组的长度 = 数组占用的总字节数 / 数组元素占用的字节数


案例代码:


int ages[4] = {19, 22, 33, 13};
int length =  sizeof(ages)/sizeof(int);
printf("length = %d", length);

输出结果: 4


二维数组的含义

二维数组包含行列,先行后列

    int m = 5;
    int n = 6;
    int arr[5][6];
    for(int i =0 ; i <m; i++)
    {
        for (int j =0;j<n;j++)
        {
            printf("%d-%d\t",i,j);
            arr[i][j] = 1;
        }
        printf("\n");
    }
    for(int i = 0 ;i <5;i++)
    {
        printf("%d",arr[i][2]);
    }

输出为:

7b163908976dc54bb80bf8c9a6f7a748_2f0b88ce8bb6492189406a405f7a9942.png


二维数组的定义

    int arr1[5][6];
    int arr2[2][3] = {
      {1,2,3},
      {3,2,1}
    };
    int arr3[2][3] = {{1,2,3},{3,2,1}};
    //int arr4[][3]; //D:\cplusproject\数组\main.c|15|error: array size missing in 'arr4'|
    //int arr5[2][];//D:\cplusproject\数组\main.c|16|error: array type has incomplete element type 'int[]'|
    int arr6[][3]={1,2,3,4,5,6,7}; //3行3列 按照行去赋值
    int nums = sizeof(arr6)/sizeof(int); //nums表示有多少个元素
    int rows = nums/3; //rows表示有多少行
    printf("当前的二维数组有 %d 行 %d 个元素\n",rows,nums);
    for(int i = 0;i<rows;i++)
    {
        for(int j = 0;j <3 ;j++)
        {
            printf("%d \t",arr6[i][j]);
        }
        printf("\n");
    }

输出为:

25d4779cb433b6e8d9960c36d7a59902_503713b3410f4799be9fd7c80ad3364f.png


字符数组

char c[] ={'I',' ','a','m','\0','h','a','p','p','y'};   // c[0]--c[9]   ----c[10]  但是这里没有 \0 ,就可能会导致乱码
printf("%d \n",sizeof(c)/sizeof(char));
for(int i = 0;i<(sizeof(c)/sizeof(char))+1;i++)
{
    printf("%c \t \n",c[i]);
}
    return 0;
}

输出为:

1f4ba98761deea7ea482ac016761bdbc_18e29ed1939c42f388d3b3928695d0cd.png


字符函数

参考:C语言字符函数


无字符串长度限制的字符串函数
            1. strlen 计算字符串长度
            2. strcpy 字符串拷贝
            3. strcat 字符串追加
            4. strcmp 字符串比较
有字符串长度限制的字符串函数
            1. strncpy 字符串拷贝
            2. strncat 字符串追加
            3. strncmp 字符串比较
            4. strstr 在字符串中查找另一字符串
            5. strtok 切割字符串
            6. strerror 解析错误码
    perror 解析错误码,打印信息
字符操作函数
        1. `isdigit` 判断是否是数字字符
        2. islower 判断是否是小写字符
字符转换函
        tolower 字符转小写
        toupper 字符转大写

1. strlen 计算字符串长度

strlen 函数的参数


size_t strlen ( const char * str );

strlne 是计算字符 ‘\0’ 之前所有字符的的个数,不包括 \0

strlen 的函数返回值是 unsigned int 类型,无符号整形

strlen 的参数指向的字符串的结尾必须包涵 \0,字符串是以 \0作为结束标志

strlen 的使用方法


2. strcpy 字符串拷贝

strcpy 函数的参数


char* strcpy(char * destination, const char * source );

strcpy 字符串拷贝的源字符串必须以 \0 为结束标志

strcpy 会将源字符串中的 ‘\0’ 拷贝到目标空间中

拷贝的目标空间必须足够大,拷贝后能够存放字符串

strcpy 拷贝的字符串必须是可改变的,不能是常量字符串

strcpy 函数的使用

strcpy 里的第一个参数是拷贝的目标空间,第二个参数是拷贝的内容


3. strcat 字符串追加

strcat 函数的参数


char * strcat ( char * destination, const char * source );

strcat 字符串追加,是在字符串 A 后面在追加一个字符串 B

strcat 的源字符串必须以 \0 为结束标志

strcat 的被追加的空间必须能够存放的下追加的字符串

strcat 的源字符串必须是可改变的,不能是常量字符串

strcat 函数的使用


strcat(arr, arr2);
//strcat 函数追加会把 arr2 的所有字符串拷贝到arr1里,包括\0

arr2拷贝时会把arr1 里的\0 覆盖,所以 strcat 函数不能 字符串A 追加 字符串A


4. strcmp 字符串比较

strcmp 函数的参数


int strcmp ( const char * str1, const char * str2 );

strcmp函数的判断标准规定:

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字


strcmp 是比较每个字符串的第一个字符, 如果相等,

则继续比较下一对字符,直到字符不相等或到达终止空字符


有字符串长度限制的字符串函数


1. strncpy 字符串拷贝

strncpy 函数的参数


char * strncpy ( char * destination, const char * source, size_t num );

strncpy 和 strcpy 函数的使用方法都差不多,只是多了一个参数 size_t num

多出来的参数是来限制字符串拷贝的长度,增加了安全性

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加\0,直到num个


strncat 字符串追加

strncat 函数参数

char * strncat ( char * destination, const char * source, size_t num );

和 strcat 函数使用的方法和规则都差不多,只是多了一个参数 size_t num

num 这个参数代表需要追加几个字符串

strncat 函数使用


3. strncmp 字符串比较

strncmp 函数参数

int strncmp ( const char * str1, const char * str2, size_t num );

规则和 strcmp 同上

多出来的一个参数是用来要比较字符串的个数

strncmp 函数使用

比较3个字符串的大小


4. strstr 在字符串中查找另一字符串

strstr 函数参数


char * strstr ( const char *str1, const char * str2);

作用:在A 字符串中查找是否包含 B字符串

如果 A 中包含 B ,则返回 B 在 A 中首次出现的的地址。

否则返回空指针!

如果找到,返回的是字符串的地址,所以要用指针变量来接收


5. strtok 切割字符串

strtok 函数参数

char * strtok ( char * str, const char * sep );

第一个参数是一个字符串,它包含了0个或者多个字符

第二个参数是分割字符串,对第一个参数的字符串扫描,碰到了分割字符串中的任意一个

就把那个字符标记成 ‘\0’ ,然后返回分割字符串之前的地址,并且保存它在字符串中的位置

strtok函数第二次查找的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记

如果字符串中不存在更多的分割字符,则返回 NULL 指针。

strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改


6. strerror 解析错误码

strerror 函数参数


char * strerror ( int errnum );


在使用库函数的时候,调用库函数失败时,都会设置错误码

C语言中有一个全局变量叫 errno,只要调用库函数发生错误,就会把错误码放到errno里

strerror 会把错误码翻译成对应的错误信息

使用必须包涵头文件 <errno.h>

srerror的使用

返回的都是对应的错误信息


perror 解析错误码,打印信息

perror 函数参数


void perror(const char* str);


perror 的头文件是 <stdio.h>

perror 和 strerror 作用都是一样的,不过strerror 没有打印

perror 是把错误码转换成错误信息,在打印


字符操作函数

函数名 如果参数符合下列条件就返回真(非0的数字)

iscntrl 任何控制字符

isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’

isdigit 十进制数字 0~9

sxdigit 十六进制数字,包括所有十进制数字,小写字母a ~ f,大写字母A ~ F

islower 小写字母a~z

isupper 大写字母A~Z

isalpha 字母 a ~ z 或大写字符 A - Z

salnum 字母或者数字,az,AZ,0~9

ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)

isgraph 任何图形字符

isprint 任何可打印字符,包括图形字符和空白字符

以上函数的头文件:<ctype.h>

函数使用示范:

相关文章
|
26天前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
139 12
|
6月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
166 15
|
3月前
|
存储 安全 编译器
c++入门
c++作为面向对象的语言与c的简单区别:c语言作为面向过程的语言还是跟c++有很大的区别的,比如说一个简单的五子棋的实现对于c语言面向过程的设计思路是首先分析解决这个问题的步骤:(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。但对于c++就不一样了,在下五子棋的例子中,用面向对象的方法来解决的话,首先将整个五子棋游戏分为三个对象:(1)黑白双方,这两方的行为是一样的。(2)棋盘系统,负责绘制画面。
44 0
|
6月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
108 8
|
7月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
6月前
|
存储 分布式计算 编译器
C++入门基础2
本内容主要讲解C++中的引用、inline函数和nullptr。引用是变量的别名,与原变量共享内存,定义时需初始化且不可更改指向对象,适用于传参和返回值以提高效率;const引用可增强代码灵活性。Inline函数通过展开提高效率,但是否展开由编译器决定,不建议分离声明与定义。Nullptr用于指针赋空,取代C语言中的NULL。最后鼓励持续学习,精进技能,提升竞争力。
|
8月前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
125 5
|
11月前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
98 0
|
7月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。