文章目录

  • 一、 数组
    • 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()
      • 5.2.4 strcat()
      • 5.2.5 自己实现strcpy函数的功能
  • 六、指针
  • 6.1 指针的用途
    • 6.2 指针的概念
    • 6.3 指针变量的运算
      • 6.3.1 算术运算符
      • 6.3.2 关系运算符
      • 6.3.3 赋值运算
      • 6.2.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 0int t = a[j];a[j] = a[j+1];a[j+1] = t;
#endifa[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;
}

5.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;
}

5.2.5 自己实现strcpy函数的功能

#include <stdio.h>char *my_strcpy(char *s1,char *s2)
{if(NULL == s1 || NULL == s2){return NULL;}int i = 0;while(s2[i] != '\0'){s1[i] = s2[i];i++;}s1[i] = '\0';return s1;
}int main()
{char s1[] = "hello world";char s2[] = "world";char *result = my_strcpy(s1,s2); for(int i = 0; i < sizeof(s1)/sizeof(s1[0]); i++){printf("[%c] %d\n",result[i],result[i]);}return 0;
}

六、指针

6.1 指针的用途

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

6.2 指针的概念

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

在不影响理解的情况,有时对地址,指针,指针变量不区分,通称指针
&:取地址符
*:
1.定义时,如果前面是一种类型,表示这是一条定义语句,定义一个指针变量,pa是一个指针,指向整数a
2.使用时,*pa = 100;*表示取值的意思,取指针pa指向的内存的值
pa = 地址

#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;
}

6.3 指针变量的运算

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

6.3.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;
}

6.3.2 关系运算符

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

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

6.3.3 赋值运算

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

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

#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功能

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

2.实现atoi函数的功能
char str[] = '5891";
int num;

“5891” ----->5891
3. 输入一个字符串,输出字符串中有多少个空格
4. 输入两个字符串,判断一个字符串是否为另一个的子串
s1 = hellloworld s2 = oworl

苏嵌实训——day4相关推荐

  1. 【苏嵌实训-嵌入式 linux C 第 1天】

    | 项目名称 [苏嵌实训-嵌入式 linux C 第 1天] 今日进度以及任务 了解未来就业形势.学习Linux系统开发环境,熟悉编译环境和命令. 任务完成情况 通过在微信公众号及百度搜索完成 本日开 ...

  2. 苏嵌实训-嵌入式Linux C 第一天

    项目名称 苏嵌实训-嵌入式Linux C 第一天 今日进度以及任务 嵌入式开发概述及嵌入式LinuxC项目演示 今日开发中出现的问题汇总 1.嵌入式底层开发为什么选择C语言? 2.什么是实时性?硬实时 ...

  3. 苏嵌实训——day2

    文章目录 一.C语言简单讲解 1.1 代码注释 1.2 中英文切换 1.3 代码讲解 gcc编译出现问题的解决方式 二. 计算机的数据表示 数值型数据 非数值型数据 三.词法符号 3.1 关键词 3. ...

  4. 苏嵌实训——day7

    文章目录 一 Makefile简介 1.1什么是Makefile? 1.2什么是make? 1.3为什么使用? 1.4.优越性 二.makefile 2.1 makfile编译规则 2.2 Makef ...

  5. 苏嵌实训——day19

    文章目录 一.数据库 1.1 在ubuntu中安装数据库 1.2 数据库的操作 1.2.1 数据库命令的分类 1.2.2 常用的系统命令 1.2.3 数据中的常用的语句 1.3 sqlite数据库中常 ...

  6. 苏嵌实训——day9

    文章目录 一 单链表 1.1 概念 1.2 单链表的操作 1.2.1 定义结点结构体 1.2.2 创建一个空的单链表 1.2.3 头插法插入数据 1.2.4 遍历单链表 1.2.5 尾插法插入数据 1 ...

  7. 苏嵌实训——day18

    文章目录 一 wirkeshark 抓包工具 1.1 软件介绍 1.2 软件安装 1.3 wireshark工具的使用 1.4 TCP三次握手和四次挥手 二 TCP循环服务器 2.1 IO多路复用 2 ...

  8. 苏嵌实训——day11

    文章目录 一.队列 1.1 队列的概念 1.2 链式队列 1.2.1 linkqueue.h 1.2.2 linkqueue.c 1.3 顺序队列(循环队列) 1.3.1 sequeue.h 1.3. ...

  9. 苏嵌实训——day1

    文章目录 一.概述 二.Linux 三.linux的系统的层次 四.linux目录结构 五.命令行提示符的介绍 六.linux的基本命令 6.1 ls命令 6.2 chmod命令 6.3 cd 命令 ...

最新文章

  1. cmd运行Java中文乱码,无法加载主类Error: Could not find or load main class
  2. python utf8_肿么在Python里使用UTF-8编码
  3. boost::mpl::greater_equal相关的测试程序
  4. 机器学习中有关数学的一些推荐书籍
  5. QQ在屏幕边缘自动隐藏不能正常显示
  6. Ubuntu下用eclipse调试caffe code
  7. BugkuCTF-Crypto题affine
  8. 360浏览器怎么保存网页账号密码
  9. 百度地图——判断用户是否在配送范围内解决方案
  10. 无法卸载 Mac 上的磁盘时该怎么办?
  11. 网络爬虫+数据可视化
  12. 使用idea进行svn分支管理-初稿
  13. 反射之动态拼接sql字符串
  14. 微博千万级规模高性能高并发的网络架构设计
  15. 龙芯源码编译mysql_使用源码包在龙芯2F上安装mysql
  16. “狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
  17. 智能车辆纵向速度跟踪与控制方法研究
  18. 什么是JTAG和SWD接口协议,和各类仿真器
  19. Jmetal Problem和Problem Set的变量范围
  20. Android使用MediaCodec硬解码播放H264格式视频文件

热门文章

  1. 无线路由器升级升级不成功,请检查您是否已经开启tftp服务器.,路由器升级不成功怎么办?...
  2. 国内应用宝广告主信息抓取
  3. 数据结构课设_网页形式的景区导游(使用说明)
  4. 分立器件综合参数测试仪
  5. java全景图片生成_[Java教程]使用Javascript来创建一个响应式的超酷360度全景图片查看幻灯效果...
  6. 苹果手机屏幕尺寸_5G iPhone12新鲜出炉!屏幕尺寸最大的苹果手机诞生!网友吐槽:没有充电器!太坑了!...
  7. freescale MC9S12G128单片机概述
  8. Vue注册界面精美模板分享
  9. 机电系统计算机考试题,微机电系统习题及参考答案.doc
  10. H3C(UIS R390X G2)安装ESXI