1,循环2,break,continue 3,数组(一维:整形 & 字符)4,冒泡排序5,字符串处理相关的函数---------------------------------------

本文详细讲解了数组(包括整形和字符)、字符串处理函数如strlen、strcpy、strcat、strcmp等的使用,以及二维数组、指针概念和基本操作。涵盖了字符串长度计算、字符串拷贝、连接、比较,以及二维数组的初始化、输入输出和指针的定义与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组:
整形数组:输入输出均需要通过循环来完成
字符数组:本质就是一个字符串:通过整体去操作:gets,puts,  scanf,printf

字符串处理相关的函数:

-----》注意:针对字符串来说

strlen:    //测有效字节
strcpy:
strncpy:
strcat:
strncat:
strcmp:
strncmp:


memset:
-------------------------------------------------
strlen: 
头文件:
  #include <string.h>
函数原型:
      size_t strlen(const char *s);
      功能:求一个字符串的长度(注意:该长度不包含'\0',有效字符的长度)
      参数:所求的字符串的首地址,即数组名
      返回值:代表该字符串中的字符个数

#include <stdio.h>
#include <string.h>
 
#define N 20
int main(int argc, const char *argv[])
{
    //利用库函数实现求一个字符串的长度
    //定义一个字符串:
    char str[N] = {'\0'};
    printf("请输入一个字符串:\n");
    gets(str);
    //scanf("%s",str);
    
    int length = strlen(str);
    printf("%d\n",length);
    printf("sizeof(str) = %d\n",sizeof(str));
    return 0;
}

      
strcpy:
       #include <string.h>

       char *strcpy(char *dest, const char *src);
       功能:实现两个字符串之间的拷贝
       参数: 
             参数1:目的字符串
             参数2:源字符串
                    注意:将源字符串拷贝到目的字符串中去
       返回值:
              拷贝成功之后的字符串的首地址     

#include <stdio.h>
#include <string.h>
 
#define M 10
#define N 20
 
int main(int argc, const char *argv[])
{
    //实现两个字符串的拷贝
    char str1[M] = {'\0'};
    char str2[N] = {'\0'};
 
    printf("请输入字符串:\n");
    gets(str1);
    gets(str2);
 
    //条件判断--》判断str1中能否放的下str2
    if(M < strlen(str2) + 1)
    {
        printf("str1 is so short!\n");
        return -1;//-1一般代表程序异常结束
    }
    printf("before: str1 = %s\n",str1);
    //strcpy(str1,str2);
    strcpy(str1,"wangjiajia");
    printf("after: str1 = %s\n",str1);
    return 0;//0代表程序程序正常退出
}
注意:strcpy是一个完全拷贝,会将'\0'也会拷贝过去


       char *strncpy(char *dest, const char *src, size_t n);
       功能:将源字符串中的前n个字符拷贝到目的字符串中去
       参数:
            参数1:目的字符串
            参数2:源字符串
            参数3:指定的需拷贝的字符个数
       返回值:拷贝成功之后的字符串的首地址
       
strcat: 
       #include <string.h>

       char *strcat(char *dest, const char *src);
       功能:实现两个字符串的连接
       参数: 
            参数1:目的字符串
            参数2:源字符串
       返回值:连接成功之后的字符串的首地址

#include <stdio.h>
#include <string.h>
 
#define M 10
#define N 20
int main(int argc, const char *argv[])
{
    //实现两个字符串的连接
    char str1[M] = {0};
    char str2[N] = {'\0'};
 
    printf("请输入两个字符串:\n");
    scanf("%s",str1);
    scanf("%s",str2);
 
    //判断--->判断str1中是否存放的下str1 + str2的内容
    if( M < strlen(str1) + strlen(str2) + 1)
    {
        printf("str1 is so short!\n");
        return -1;
    }
    printf("连接之前: str1  = %s\n",str1);
 
    strcat(str1,str2);
    printf("连接之后: str1 = %s\n",str1);
    return 0;
}
       char *strncat(char *dest, const char *src, size_t n);
       
strcmp:
 #include <string.h>

       int strcmp(const char *s1, const char *s2);
       功能: 实现字符串之间的比较
       参数: 
              参数1:字符串1
              参数2:字符串2
              
       返回值: 
              代表两个字符串大小的问题
              
              当返回值大于0:代表s1大于s2
              当返回值小于0,代表s1小于s2
              当返回值等于0,代表s1等于s2

#include <stdio.h>
#include <string.h>
 
int main(int argc, const char *argv[])
{
    //实现两个字符串之间的比较
    char str1[10] = {'\0'};
    char str2[20] = {0};
 
 
    gets(str1);
    gets(str2);
 
    int count;
    printf("请输入需要比较的字符的个数:\n");
    scanf("%d",&count);
 
    int ret;
    ret = strncmp(str1,str2,count);
    if(ret > 0)
    {
        printf("str1 > str2!\n");
    }
    else if(ret < 0)
    {
        printf("str1 < str2!\n");
    }
    else
    {
        printf("str1 == str2!\n");
    }
    return 0;
}

比较规则:
         将两个字符串中的字符进行一对一对比较,如果不相等,则直接进行相减得出结果,不再进行比较。
         如果相等:则有两种情况:
                                第一种:相等同时都等于'\0',证明两个字符串相等
                                第二种:相等同时不等于'\0',需要判断下一对字符
         以此类推(按照ASCII码值进行得出大小的关系)。                                

       int strncmp(const char *s1, const char *s2, size_t n);
       功能:比较两个字符串中指定的前N个字符的关系。
---------------------------------------------------------------------------------------

二维数组:
数组的特点:
(1)数据类型相同
(2)内存连续


一维整形的定义格式?
存储类型  数据类型  数组名[元素个数];
二维整形:
定义格式:
 存储类型 数据类型 数组名[行标][列标];
 分析:
      存储类型: 
               二维数组中每个元素的存储类型
      数据类型:
               二维数组中每个元素的类型
      数组民:见名知义
      行标:代表当前二维的行数
      列标:代表当前二维的列数
      
 
 思考:
      定义一个2行3列的整形数组
      
      int arr[2][3];
      
      1 2 3
      4 5 6
     
      
如何访问二维数组中的每一个元素
----》通过 数组名[行标][列标]


总结:
    (1)对于二维数组的初始化:
                     满初始化:int arr[2][3] = {1,2,3,4,5,6};
                               int arr[2][3] = {{1,2,3},{4,5,6}};
                     部分初始化:
                               int arr[2][3] = {1,2,3}; --->剩余补0
                               int arr[2][3] = {{1},{2,3}};--->剩余补0
                               
    (2)对于二维数组的行列能否省略?
          ----》行可以被省略,但是列标不能被省略。
    (3)行数:代表一维数组的个数
         列数:代表每一个一维数组的长度
---------------------------------------------------------         
先练习二维数组的输入输出!

#include <stdio.h>
 
#define M 3
#define N 4
int main(int argc, const char *argv[])
{
    //定义一个3行4列的二维整形数组
    int arr[M][N] = {{1,2,3},{5},{9,10}};
    int i,j;
 
    //输入
    for(i=0;i<M;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
 
    //输出--->循环完成
    for(i=0;i<M;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%d ",arr[i][j]);
        }
        putchar('\n');
    }
    return 0;
}
---------------------------------------------------------
二维字符数组:含有多个(行数决定)字符串的一维数组,所包含的每一个字符串的长度均是由列标来决定。

思考: 
    定义一个可以存放三个字符串的数组。
    ----》char str[3][20] = {"haha","xixi","gaga"};
          char str[3][20] = {{"haha"},{"xixi"},{"gaga"}};
          
          
    思考:如何完成二维字符数组的输入和输出?
    通过循环---》一个循环搞定

#include <stdio.h>
 
#define M 5
#define N 20
int main(int argc, const char *argv[])
{
    //完成二维字符数组的输入和输出
    char str[M][N] = {{'\0'}};
    printf("please get two string:\n");
    int i;
    for(i=0;i<M;i++)
    {
        gets(str[i]);
    }
 
    printf("输出为:\n");
    for(i=0;i<M;i++)
    {
        puts(str[i]);
    }
    return 0;
}
------------------------------------------------------------------------------------------------


指针:

地址:内存单元的一个编号(是以十六进制的数字组合的)
      注意:编号是一个常量(不能自加以及自减)
      
指针:因为一个编号对应一个固定的字节空间,有这种指向关系存在,所以
      把地址也形象的称为指针。
      
    指针就是地址,地址就是指针

思考: 
将一个普通数值存储起来称为普通变量
要是将一个地址存储起来就应该称为地址变量(地址==指针),所以称为指针变量

指针变量:专门用来存储地址的一类变量

如何定义一个指针变量?
----》
    存储类型  数据类型 *变量名;
    注意:这里的*号是一个标识符,表示定义的变量是一个指针变量,而不是普通变量。
    
    分析:
         存储类型:指针变量自身的存储位置
         数据类型:指针变量所指向的类型
         数据类型 *:指针自身的类型
                  
指针的分类:
         指针常量:内存单元的编号  (不能自加以及自减))   &a++  &a-- (error)
         指针变量:用来存储地址的一类变量 (可以自加以及自减) p++ p-- (OK)
但是:我们平常所说的指针一般指的是指针变量。

注意: 
     (1)在给指针变量赋值时一定要类型匹配
     int a = 10;
     char chr = 'i';
     int *p = &chr; (error)
     int *p = &a;  (OK )
     (2)不能给常量区赋值: 
      int a = 90;
      int b = 78;
      int *p = &a;
      int *q = &b;
      &a = &b; (error)
      p = q;(OK)
      
思考: 
如果: 
int a = 10;
char chr = 'k';
char *q = &chr;
int *p = &a;
试问:*p以及*q 一次性可以访问的空间为多大?---->依赖于所指向的类型
*p: 4个字节
*q: 1个字节 


注意: 指针在32OS下占几个字节----》永远为4个字节

#include <stdio.h>
 
int main(int argc, const char *argv[])
{
    int a = 10;
    int b = 90;
    a = b;
    printf("a = %d\n",a);
 
 
    printf("sizeof(int *) = %d\n",sizeof(int *));
    printf("sizeof(int **) = %d\n",sizeof(int **));
    printf("sizeof(char *) = %d\n",sizeof(char *));
    printf("sizeof(double ***) = %d\n",sizeof(double ***));
    //a = 90;
    //定义一个指针变量,指向a的空间
    //int *p = &a;
    //*p = 100;
    //printf("a = %d\n",a);
    return 0;
}
---------------------------------------------------------------------------

空指针:
       值为0的指针,被头文件<stdio.h>中被宏定义为NULL,
       该空指针是不允许被访问的,一旦访问空指针则会引起段错误
野指针:
       指向不明确的指针,访问野指针是非常可怕,应该杜绝野指针的出现----》可以通过初始化为NULL即可

#include <stdio.h>
 
int main(int argc, const char *argv[])
{
    int a = 90;
    int *p;
    printf("p = %p\n",p);
    //*p = 180;
    return 0;
}

作业:
(0)实现二维整形数组的求和

#include<stdio.h>
 
#define M 2
#define N 3
 
int main(int argc, const char *argv[])
{
    //实现二维整形数组的求和
    //初始化数组
    int arr[M][N] = {0};
    int i,j;
    int sum = 0;
 
    printf("请输入所有求和的数:\n");
 
    //for循环实现整数的输入
    for(i = 0;i < M;i++)
    {
        for(j = 0;j < N;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
   
    //for循环实现整数的求和输出
    for(i = 0;i < M;i++)
    {
        for(j = 0;j < N;j++)
        {
            sum += arr[i][j];
        }
    }
    printf("整数数组求和结果为:%d\n",sum);
    return 0;
}

(1)自己实现strcpy,strcat,strcmp的功能     

#include <stdio.h>
 
 
#define M 10
#define N 20
int main(int argc, const char *argv[])
{
    //手动实现strcpy的功能
    char str1[M] = {'\0'};
    char str2[N] = {'\0'};
 
    printf("请输入:\n");
    gets(str1);
    gets(str2);
    int i = 0;
 
    //求str2的长度?
    int len_str2 = 0;
    for(;str2[i];i++)
    {
        len_str2++;
    }
    //判断
    if(M < (len_str2 + 1))
    {
        printf("str1 is so short!\n");
        return -1;
    }
    i = 0;
    //首先遍历str2
    /*
    while(str2[i])
    {
        str1[i] = str2[i];
        i++;
    }
    */
    for(;str2[i];i++)
    {
        str1[i] = str2[i];
    }
    //在str1的末尾添加'\0'
    str1[i] = '\0';
    
    printf("复制之后的str1 = %s\n",str1);
 
 
    return 0;
}
#include <stdio.h>
 
int main(int argc, const char *argv[])
{
    char str1[10] = {0};
    char str2[20] = {0};
 
    gets(str1);
    gets(str2);
 
    printf("连接之前: str1  = %s\n",str1);
 
    int len_str1 = 0,len_str2 = 0;
    int j = 0;
    //先求str1的长度
    while(str1[j])
    {
        len_str1++;
        j++;
    }
 
    int i = 0;
    //求str2的长度
    while(str2[i])
    {
        len_str2++;
        i++;
    }
 
    i = 0;
    //判断
    if(10 < (len_str1+len_str2+1))
    {
        printf("error!\n");
        return -1;
    }
    //实现连接的步骤--》
    //j--; //将j移动到str1字符串的第一个'\0'处
    //遍历str2字符串
    while(str2[i])
    {
        str1[j++] = str2[i++];
        //i++;
        //j++;
    }
    printf("连接之后: str1  = %s\n",str1);
    return 0;
}
#include <stdio.h>
 
int main(int argc, const char *argv[])
{
    //实现strcmp的功能
    char str1[20] = {'\0'};
    char str2[10] = {'\0'};
 
    gets(str1);
    gets(str2);
 
    int i = 0;
    for(;str1[i] == str2[i];i++)
    {
        if(str1[i] == '\0')
        {
            printf("str1 == str2!\n");
            return 0;
        }
    }
 
    int ret = str1[i]-str2[i];
    if(ret < 0)
    {
        printf("str1 < str2!\n");
    }
    else
    {
        printf("str1 > str2!\n");
    }
    return 0;
}
(2)实现杨辉三角的打印 

#include <stdio.h>
 
#define M 20
int main(int argc, const char *argv[])
{
    //实现杨辉三角的打印输出
    int arr[M][M] = {0};
 
    //首先实现杨辉三角的赋值
    int i,j;
    int line;
    printf("请输入需要打印的杨辉三角的行数:\n");
    scanf("%d",&line);
    for(i=0;i<line;i++)
    {
        for(j=0;j<=i;j++)
        {
            if(j == 0 || j == i)
            {
                arr[i][j] = 1;
            }
            else
            {
                arr[i][j] = arr[i-1][j-1]+arr[i-1][j];
            }
        }
    }
 
    //打印输出
    int k;
    for(i=0;i<line;i++)
    {
        //控制空格的个数
        for(k=0;k<line-1-i;k++)
        {
            printf(" ");
        }
        for(j=0;j<=i;j++)
        {
            printf("%d ",arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

(3)定义一个二维字符数组,实现5个字符串的排序(结合字符串处理函数实现)

#include <stdio.h>
#include <string.h>
 
#define M 5
#define N 20
int main(int argc, const char *argv[])
{
    //实现5个字符串的排序输出
    char str[M][N] = {{'\0'}};
 
    //完成输入
    int i,j;
    for(i=0;i<M;i++)
    {
        gets(str[i]);
    }
 
    //输出
    printf("排序之前:\n");
    for(i=0;i<M;i++)
    {
        puts(str[i]);
    }
 
    //冒泡
    //控制趟数
    for(i=0;i<M-1;i++)
    {
        //控制每一趟中需要比较的次数
        for(j=0;j<M-1-i;j++)
        {
            if(strcmp(str[j],str[j+1]) > 0)
            {
                char Temp[N] = {'\0'};
                strcpy(Temp,str[j]);
                strcpy(str[j],str[j+1]);
                strcpy(str[j+1],Temp);
            }
        }
    }
    //输出
    printf("排序之后:\n");
    for(i=0;i<M;i++)
    {
        puts(str[i]);
    }
 
 
    return 0;
}
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值