Day4 C语言基础语法学习-3

  • 一 数组
    • 1.1 数组的概念
    • 1.2 一维数组
      • 1.2.1 一维数组的定义
    • 1.2.2 一维数组的性质
    • 1.3 一维数组的初始化和遍历
    • 1.4 冒泡排序法
  • 二、二维数组
  • 2.1 二维数组的定义和性质
  • 2.2 二维数组的初始化和遍历
  • 三、字符数组和字符串
    • 3.1 字符串逆序
    • 3.2 插入数据
  • 四 字符串函数
    • 4.1 为什么要使用字符串函数
    • 4.2 常用字符串函数
      • 4.2.1 strlen()
      • 4.2.2 strcmp()
      • 4.2.3 strcpy()
      • 4.2.4 strcat()
      • 4.2.5 自己实现strcpy函数的功能
  • 五、指针概念
    • 5.1 指针的用途
    • 5.2 指针的概念
    • 5.2指针变量的运算
      • 5.2.1 算术运算符
      • 5.2.2 关系运算符
      • 5.2.3 赋值运算
      • 5.2.4 练习:输入一个字符串,将字符串的元素翻转
  • 六、指针和一维数组
    • 练习1:通过指针自己实现strlen函数的功能
    • 练习2: 通过指针实现strcpy函数的功能
  • 作业:
    • 1.通过指针实现strcat功能
    • 2.实现atoi函数的功能
    • 3. 输入一个字符串,输出字符串中有多少个空格
    • 4. 输入两个字符串,判断一个字符串是否为另一个的子串

一 数组

1.1 数组的概念

数组:
保存一组相同类型的数据
不管是几维数组,都是开辟一段连续的内存空间
数组是一种构造数据类型(数组,结构体,共用体)

1.2 一维数组

1.2.1 一维数组的定义

<存储类型> <数据类型> <数组名> [数组下标]

存储类型:auto,register,static,extern
数据类型:基本数据类型:int,char,float…等
数组名:是一个标识符,满足标识符的命名规则
数组下标:确定数组张元素的个数

例如:

int a[10];

含义:定义一个名为a的数组,一共10个元素,每个元素都是int类型。

1.2.2 一维数组的性质

#include <stdio.h>int main(int argc, const char *argv[])
{int a[4];a[0] = 222;a[1] = 333;a[2] = 444;a[3] = 555;printf("%d %d %d\n",a[0],a[1],a[2]);//数组在定义和使用的时候,数组下表尽量不要使用变量//防止后期变量改变会影响对数组的操作,一般数组下标都是常量或者常量表单大师,宏定义本身也是一个常量表达式,所以可以当做数组下标使用#if 0int num = 10;int b[num];b[2] = 5;int n =3;b[n] = 888;printf("%d %d\n",b[2],b[n]);#endifprintf("sizeof(a) = %ld %ld\n",sizeof(a),sizeof(int)*4);printf("%p\n",&a[0]);printf("%p\n",&a[0]+1);printf("%p\n",a);printf("%p\n",a+1);printf("%p\n",&a);printf("%p\n",&a+1);a++;  //数组名是常指针,不能修改return 0;
}

1.3 一维数组的初始化和遍历

1.全部初始化
2.局部初始化
3.全部初始化不指定数组下标

#include <stdio.h>int main(int argc, const char *argv[])
{//如果在函数内部定义一个数组没有初始`在这里插入代码片`化,那么每一个元素都是随机值//int a[5];//a = {1,2,3,4,5};  //错误写法//全部初始化//int a[5] = {1,2,3,4,5};//int a[5] = {0};  //全部初始化为0//int a[5] = {};  //有的编译器不支持此种写法//int a[5] = {1,2,3};  //局部初始化,没有赋值的元素自动初始化为0int a[] = {1,2,3,4,5,6,7};  //不指定数组下标,系统会根据初始化的数据的个数设置数组下标printf("sizeof(a) = %ld\n",sizeof(a));/*一维数组的遍历*/int i;for(i = 0 ; i < sizeof(a)/sizeof(a[0]);i++){printf("%d ",a[i]);//printf("a[%d] = %d\n",i,a[i]);}putchar(10);return 0;
}

1.4 冒泡排序法

#include <stdio.h>int main(int argc, const char *argv[])
{int a[10] = {0};printf("请输入10个数字:\n");int i,j;int length = sizeof(a)/sizeof(a[0]);for(i = 0 ; i < length;i++){scanf("%d",&a[i]);}for(i = 0 ; i < length - 1;i++){for(j = 0 ; j < length - 1 - i;j++){if(a[j] < a[j+1]){#if 0//数据交换,方式1int t = a[j];a[j] = a[j+1];a[j+1] = t;#endif//数据交换,方式2 a[j] = a[j] + a[j + 1];a[j + 1] = a[j] - a[j + 1];a[j] = a[j] - a[j + 1];}}}for(i = 0 ; i < length;i++){printf("%d ",a[i]);}putchar(10);return 0;
}

二、二维数组

2.1 二维数组的定义和性质

书写方式:
存储类型 数据类型 数组名 [行数][列数];
例如:

int arr[3][4];

#include <stdio.h>int main(int argc, const char *argv[])
{int a[2][3] = {{1,2,3},{4,5,6}};//int a[2][3] = {{1},{4,5}};//int a[][3] = {{1,2,3},{4,5,6}};//int a[][3] = {1,2,3,4,5,6,7,8};//int a[2][3] = {0};int i,j;for(i = 0;i < 3;i++){for(j =0 ; j < 3;j++){printf("a[%d][%d] = %d\n",i,j,a[i][j]);}}printf("%p\n",&a[0][0]);printf("%p\n",&a[0]);printf("%p\n",a);printf("%p\n",&a);printf("%p\n",&a[0][0] + 1);printf("%p\n",&a[0] + 1);printf("%p\n",a + 1);printf("%p\n",&a + 1);return 0;
}

2.2 二维数组的初始化和遍历

#include <stdio.h>int main(int argc, const char *argv[])
{//int a[3][4];//int a[2][3] = {{4,5,6},{7,8,9}};//全部初始化//int a[2][3] = {1,2,3,4};   //按行存储,没有设置的自动补0//int a[2][3] = {{1},{2}};//int a[][3] = {{10,20},{30}};//int a[2][] = {1,2,3,4,5};  //错误写法int i,j;//外层循环控制行数//内层循环控制列数for(i = 0 ; i < 2;i++){for(j = 0 ; j < 3;j++){printf("%-5d",a[i][j]);}putchar(10);}return 0;
}

三、字符数组和字符串

字符数组:数组里面保存的每一个元素都是字符
字符串本质也是一个字符数组

#include <stdio.h>int main(int argc, const char *argv[])
{char ch1[] = {'h','e','l','l','o'};printf("sizeof(ch1) = %ld\n",sizeof(ch1));//字符数组的遍历int i;for(i = 0; i < sizeof(ch1)/sizeof(ch1[0]);i++){printf("%c ",ch1[i]);}putchar(10);char ch2[] = "world";printf("sizeof(ch2) = %ld\n",sizeof(ch2));printf("ch2 = %s\n",ch2);char ch3[] = {'h','e','l','l','o','\0'};printf("ch3 = %s\n",ch3);char ch4[] = "hello\0world";printf("sizeof(ch4) = %ld\n",sizeof(ch4));for(i = 0 ; i < sizeof(ch4)/sizeof(ch4[0]);i++){printf("[%c] %d\n",ch4[i],ch4[i]);}puts("---------------------------------------");char str[4][32] = {"hello","nihao beijing","hello kitty","welcome to nanjing"};int j;for(i = 0 ; i < 4;i++){for(j = 0 ; j < 32;j++){printf("%c",str[i][j]);}putchar(10);}return 0;
}

3.1 字符串逆序

#include <stdio.h>int main(int argc, const char *argv[])
{char str[32] = {0};printf("请输入一个字符串: ");scanf("%s",str);int i = 0,length = 0;while(str[i] != '\0'){length++;i++;}int x = 0, y = length -1;for(i = 0 ; i < length /2 ;i++){char t = str[x];str[x] = str[y];str[y] = t;x++;y--;}printf("%s\n",str);return 0;
}

3.2 插入数据

输入一个字符串,位置,插入的元素

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{char str[32] = {0};int num,i;char ch;printf("请输入字符串,位置,插入的元素:\n");scanf("%s%d %c",str,&num,&ch);int length = strlen(str);for(i =0 ; i < length - num +1;i++){str[length - i] = str[length -i - 1];}str[num - 1] = ch;printf("%s\n",str);return 0;
}

四 字符串函数

4.1 为什么要使用字符串函数

一般字符串都是保存在一个数组里面,但是数组定义好之后,是不能整体操作的,所以我们需要借助一下字符串相关操作的函数来对字符串进行操作

#include <stdio.h>
int main(int argc, const char *argv[])
{char s1[] = "hello world";char s2[] = "hello world";if(s1 == s2){printf("s1 = s2\n");}else{printf("s1 != s2\n");}//数组如果没有初始化,数组下标必须写//char str[];return 0;
}

4.2 常用字符串函数

4.2.1 strlen()

头文件:#include <string.h>
原型:size_t strlen(const char *s);
功能:获取一个字符串的长度
参数:s:要获取长度的字符串
直接传入一个字符串,或者字符数组名都可以
返回值:字符串的长度

#include <stdio.h>
#include <string.h>int main(int argc, const char *argv[])
{//strlen函数获取字符串的长度//获取的长度是这个字符串中第一\0位置之前的长度,不包括\0char s1[] = "hello world";printf("strlen(s1) =%ld\n",strlen(s1));printf("sizeof(s1) =%ld\n",sizeof(s1));char s2[] = "hello wor\0ld";printf("strlen(s2) =%ld\n",strlen(s2));printf("sizeof(s2) =%ld\n",sizeof(s2));//以下这个不是一个字符串,没有\0,所以不能用strlen来获取字符串长度,strlen会一直从首地址的位置找\0char s3[] = {'h','e','l','l','o'};printf("strlen(s3) =%ld\n",strlen(s3));printf("sizeof(s3) =%ld\n",sizeof(s3));char s4[32] = "hello world";printf("strlen(s4) =%ld\n",strlen(s4));printf("sizeof(s4) =%ld\n",sizeof(s4));return 0;
}

4.2.2 strcmp()

头文件:#include <string.h>
原型:int strcmp(const char *s1, const char *s2);
功能: 比较两个字符串的大小
参数:s1,s2两个字符串
返回值:
0: s1 = s2
<0: s1 < s2
>0: s1 > s2
int strncmp(const char *s1, const char *s2, size_t n);
用于比较两个字符串前n个字节是否一样

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{//strcmp比较的是\0之前的内容,跟字符串所在内存空间没有关系//char s1[32] = "hello w\0orld";//char s2[] = "hello w\0orld";char s1[] = "h";char s2[] = "hello abcdefgwhi";int ret = strcmp(s1,s2);if(ret == 0){printf("s1 = s2\n");}else if(ret > 0){printf("s1 > s2\n");}else{printf("s1 < s2\n");}int k = strncmp(s1,s2,2);if(k == 0){printf("s1 = s2\n");}else if(k > 0){printf("s1 > s2\n");}else{printf("s1 < s2\n");}return 0;
}

4.2.3 strcpy()

头文件:#include <string.h>
原型:char *strcpy(char *dest, const char *src);
功能: 将src字符串赋值到dest字符串中
参数:
dest:目的字符串
src:源字符串
返回值:
返回目的字符串的首地址

char *strncpy(char *dest, const char *src, size_t n);

#include <stdio.h>#include <string.h>
int main(int argc, const char *argv[])
{char s1[32];strcpy(s1,"hello world");printf("s1 = %s\n",s1);char s2[] = "hello world";char s3[32] = "abcdefg";//strcpy将 s3中的第一个\0复制给了s2strcpy(s2,s3);printf("sizeof(s2) = %ld\n",sizeof(s2));printf("s2 = %s\n",s2);int i;for(i = 0 ; i < sizeof(s2)/sizeof(s2[0]);i++){printf("[%c] %d\n",s2[i],s2[i]);}puts("------------------------");char buf1[32] = "hello world";char buf2[32] = "abcdefghijklmnopqrsst";//strcpy(buf1,buf2);//是将第二个参数的前n个字节复制给第一个参数strncpy(buf1,buf2,7);printf("buf1 = %s\n",buf1);return 0;
}

4.2.4 strcat()

头文件:#include <string.h>
原型:char *strcat(char *dest, const char *src);
功能: 将src追加到dest的后面
参数:
dest:目的字符串
src:源字符串
返回值:
追加后字符串的首地址

char *strncat(char *dest, const char *src, size_t n);

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{char s1[32] ="hello wo\0rldadadjajdalsdkjaskdj";  //hello woabcdefg\0char s2[32] ="abcdefg\0higk";strcat(s1,s2);printf("s1 = %s\n",s1);return 0;
}

4.2.5 自己实现strcpy函数的功能

#include <stdio.h>
int main(int argc, const char *argv[])
{char s1[32] = "welcome to nanjing";char s2[32] = "hello world";int i = 0;while(s2[i] != '\0'){s1[i] = s2[i];i++;}s1[i] = s2[i];printf("s1 = %s\n",s1);return 0;
}

五、指针概念

5.1 指针的用途

使用程序简洁,紧凑,高效
有效地表示复杂的数据结构
动态分配内存
得到多于一个函数的返回值

5.2 指针的概念

当程序中定义一个变量之后,程序就会为这个变量在内存中开辟内存空间,我们内存中每一个字节的空间都有一个编号,将这个编号称之为地址,地址也叫做指针

在不影响理解的情况,有时对地址,指针,指针变量不区分,通称指针

#include <stdio.h>int main(int argc, const char *argv[])
{//int a = 1;//int *pa = &a;printf("int* = %ld\n",sizeof(int *));printf("char* = %ld\n",sizeof(char *));printf("double* = %ld\n",sizeof(double *));printf("float* = %ld\n",sizeof(float *));printf("long* = %ld\n",sizeof(long *));int a = 1;char ch = 'a';//int *pc = &ch;  //类型不兼容char *pch = &ch;//ch = 'x';*pch = 'x';  //等价于ch = 'x'printf("ch = %c\n",ch);printf("ch = %c\n",*pch);int *pa = &a;printf("%p\n",pch);printf("%p\n",pa);printf("%p\n",pch + 1);  //不同类型的指针,步长不一样printf("%p\n",pa + 1);return 0;
}

5.2指针变量的运算

指针运算是以指针变量所存放的地址量作为运算量而进行运算的。
因此,指针运算的实质就是地址的运算。
指针运算的种类是有限的,它只能进行算术运算,关系运算和赋值运算。

5.2.1 算术运算符

+: px + n 指针向地址大的方向移动n个数据
-: px - n 指针向地址小的方向移动n个数据
++: px++ 指针向地址大的方向移动1个数据
–: px-- 指针向地址小的方向移动1个数据

指针变量加减,表示指针变量向地址大或小的方向移动N个操作空间,两个指针变量相减,表示两个地址之间有多少个操作空间(多少个元素)

【注意】
两个指针做运算,必须是同类型的,类型不同没有任何意义。
一个指针变量加减有意义,乘除没有意义
后置++优先级高于前置++
后置++结合律从左往右
前置++和*优先级相同,结合律从右往左

#include <stdio.h>int main(int argc, const char *argv[])
{int arr[6] = {1,3,5,8,9,10};int *p1 = arr;printf("*p1 = %d\n",*p1);p1++;int *p2 = p1++;printf("*p1 = %d,*p2 = %d\n",*p1,*p2);printf("p1 - p2 = %ld\n",p1 - p2);int y = *p1;  //取值printf("y = %d\n",y);y = ++*p1;printf("y = %d\n",y);y = (*p1)++;printf("y = %d\n",y);y = *p1++;   //赋值完成后,指针px加1printf("y = %d\n",y);printf("*p1 = %d\n",*p1);/*y = ++*p1++;   //赋值完成后,指针px加1printf("y = %d\n",y);printf("*p1 = %d\n",*p1);*/return 0;
}

5.2.2 关系运算符

>     px > py
<
>=
<=
!=
==

两个指针变量可以通过关系运算符来判断保存地址的大小;
两指针之间的关系运算符表示他们指向的地址位置之间的关系,指向地址大的指针大于指向地址小的指针;
具有不同数据类型的指针之间的关系运算没有意义,指向不同数据区域的数据两个指针之间,关系运算符也没有意义;
指针与一般整数变量之间的关系运算也没有意义,但是可以和零进行等于或者不等于的关系运算,判断指针是否为空,一般与NULL。

5.2.3 赋值运算

指针变量直接可以直接赋值,但是不能将一个整数赋值给指针变量,因为没有开辟空间;
指针赋值运算是通过赋值运算符向指针变量送一个地址值。

5.2.4 练习:输入一个字符串,将字符串的元素翻转

要求:定义两个指针,分别保存起始位置和末尾位置的字符,然后通过交换的方式实现。

hello world

dlrow olleh

答案:

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{char str[32] = {0};gets(str);printf("反转之前的字符串:%s\n",str);char *p = NULL,*q = NULL;char tmp;p = &str[0];q = &str[strlen(str) - 1];
#if 0while(p < q){tmp = *p;*p = *q;*q = tmp;p++;q--;}
#endiffor(;p < q;p++,q--){tmp = *p;*p = *q;*q = tmp;}printf("反转之后的字符串:%s\n",str);return 0;
}

六、指针和一维数组

#include <stdio.h>
#include <string.h>int main(int argc, const char *argv[])
{int a[5] = {1,2,3,4,5};int *p = a;int i;for(i = 0 ; i < 5;i++){//printf("%d ",a[i]);printf("%d ",*(p+i));}putchar(10);char *s = "helloworld";char str[32] ="hello nanjing";s = str;//printf("%s\n",s);for(i = 0 ; i < 10;i++){printf("%c",s[i]);}putchar(10);return 0;
}

练习1:通过指针自己实现strlen函数的功能

#include <stdio.h>int main(int argc, const char *argv[])
{char buf[32] = {0};printf("请输入一个字符串:\n");gets(buf);char *p = buf;int i;while(*p != '\0'){p++;i++;}printf("strlen(buf) = %d\n",i);return 0;
}

练习2: 通过指针实现strcpy函数的功能

#include <stdio.h>int main(int argc, const char *argv[])
{char s1[] = "helloworld!";char s2[] = "abcdefghijk";char *p = NULL,*q = NULL;p = s1;q = s2;while(*q != '\0'){*p = *q;p++;q++;}*p = *q;printf("s1 = %s\n",s1);return 0;
}

作业:

1.通过指针实现strcat功能

2.实现atoi函数的功能

char str[] = '5891";
int num;

“5891” ----->5891

3. 输入一个字符串,输出字符串中有多少个空格

4. 输入两个字符串,判断一个字符串是否为另一个的子串

s1 = hellloworld s2 = oworl

【Day4 C语言基础语法学习-3】相关推荐

  1. 【Day3 C语言基础语法学习-2】

    Day3 C语言基础语法学习-2 一.输入输出函数 1.1 getchar()/putcgar() 1.1.1getchar() 1.1.2 putchar 1.2 gets()/puts() 1.2 ...

  2. Go语言 基础语法学习 (未完待更......

    文章目录 一 Go语言结构 1 Go Hello world实例 2 执行Go程序 二 Go语言基础语法 1 Go标记 2 行分隔符 3 注释 4 标识符 5 一些关键字 6 Go语言的空格 7 格式 ...

  3. Go语言基础语法讲解与学习

    Go语言基础语法讲解与学习 1 Go语言基础知识介绍 ​ 介绍Go语言之前,我们先了解一下有哪些开源项目是Go语言开发的,其中就包括 Docker.Go-Ethereum.Thrraform 和 Ku ...

  4. 【C++学习之路】第二章——C++基础语法学习(1)之黑客攻击系统

    2 C++基础语法学习(1)之黑客攻击系统 遵循原则:从实战中学习知识 法律声明:本系统仅能攻击自己搭建的网站,作为学习使用,不会触犯法律 time:2020.01.20 author:姜海天 IDE ...

  5. Go基础语法学习总结

    Go基础语法学习总结 一.基础语法 1.常见数据类型 数据类型包括有:布尔类型.字符串类型.数字类型(整型.浮点型.复数等).派生类型(数组类型.slice 切片类型.map 集合类型.struct ...

  6. GO 语言基础语法一 (快速入门 Go 语言)

    Go语言基础语法 一. golang 标识符,关键字,命名规则 二. golang 变量 三. golang 常量 四. golang 数据类型 五. golang 布尔类型 六. golang 数字 ...

  7. 【Go编程语言】 Go语言基础语法

    Go语言基础语法 文章目录 Go语言基础语法 一.注释 1.单行注释 2.多行注释 二.变量 1.变量的定义 2.变量的初始化 3.理解变量(内存地址) 4.变量交换 5.匿名变量 6.变量的作用域 ...

  8. Oracle PL/SQL基础语法学习13:比较运算符

    系列文章目录 Oracle PL/SQL基础语法学习12:短路求值 Oracle PL/SQL基础语法学习13:比较运算符 Oracle PL/SQL基础语法学习14:BOOLEAN表达式 文章目录 ...

  9. 一起学Go吧! Go语言基础语法篇二

    文章目录 前言 Go 语言指针 Go语言结构体 Go语言切片(Slice) Go 语言范围(Range) Go 语言Map(集合) Go 语言类型转换 Go 语言接口 Go 错误处理 Go并发 通道( ...

最新文章

  1. 手摇计算机教程视频,使用手摇计算机的照片
  2. php的filter input,记一个php://filter和php://input的CTF题
  3. 【组合数学】递推方程 ( 递推方程示例 1 | 列出递推方程 )
  4. linux添加x权限,Linux 7 的 rc.local 文件需要 添加 +x 权限才会自动执行
  5. 百练4148:生理周期
  6. 电脑pin重置_如果忘记了如何重置Windows PIN
  7. CentOS 安装go client调用Kubernetes API
  8. scrot截图ubuntu
  9. nginx 配置路由
  10. win10 动态磁盘 linux,win10 动态磁盘 无效,win10动态磁盘不能识别
  11. 没有期刊申请清华博士_没有论文,也可申请麻省理工学院博士及奖学金
  12. freesurfer对结构核磁共振成像分割输出结果介绍
  13. 论文解读9——TabNet: Attentive Interpretable Tabular Learning
  14. 录播系统的服务器有哪些,录播系统
  15. 如何应对stata do文件打开乱码问题
  16. 高薪程序员面试题精讲系列96之分库分表了解吗?你项目中用到过吗?怎么用的?
  17. 联邦学习——用data-free知识蒸馏处理Non-IID
  18. 致远项目管理SPM系统之合同控制概述
  19. php 心电图,用canvas画心电图的示例代码
  20. Linux驱动学习之:WDT(watchdog)驱动

热门文章

  1. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 17: ordinal not in range(128)
  2. 外贸老业务员是怎么用LinkedIn开发客户的?
  3. ECharts 使用series.lineStyle.type设置虚线(两种)
  4. 硬改无人直播系统-使用小技巧
  5. JDBC连接Mysql(附完整代码)
  6. NBT:可重复交互式的微生物组分析平台QIIME 2(2021.2发布)
  7. 数字图像基础——图像通道、空间域表示、图像二值化
  8. 声音特性介绍——声谱图、音色、音调
  9. 一个IT大学生来深圳2年半的经历感受
  10. 软考系统集成项目管理工程师复习加预习冲刺更新中