【Day4 C语言基础语法学习-3】
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】相关推荐
- 【Day3 C语言基础语法学习-2】
Day3 C语言基础语法学习-2 一.输入输出函数 1.1 getchar()/putcgar() 1.1.1getchar() 1.1.2 putchar 1.2 gets()/puts() 1.2 ...
- Go语言 基础语法学习 (未完待更......
文章目录 一 Go语言结构 1 Go Hello world实例 2 执行Go程序 二 Go语言基础语法 1 Go标记 2 行分隔符 3 注释 4 标识符 5 一些关键字 6 Go语言的空格 7 格式 ...
- Go语言基础语法讲解与学习
Go语言基础语法讲解与学习 1 Go语言基础知识介绍 介绍Go语言之前,我们先了解一下有哪些开源项目是Go语言开发的,其中就包括 Docker.Go-Ethereum.Thrraform 和 Ku ...
- 【C++学习之路】第二章——C++基础语法学习(1)之黑客攻击系统
2 C++基础语法学习(1)之黑客攻击系统 遵循原则:从实战中学习知识 法律声明:本系统仅能攻击自己搭建的网站,作为学习使用,不会触犯法律 time:2020.01.20 author:姜海天 IDE ...
- Go基础语法学习总结
Go基础语法学习总结 一.基础语法 1.常见数据类型 数据类型包括有:布尔类型.字符串类型.数字类型(整型.浮点型.复数等).派生类型(数组类型.slice 切片类型.map 集合类型.struct ...
- GO 语言基础语法一 (快速入门 Go 语言)
Go语言基础语法 一. golang 标识符,关键字,命名规则 二. golang 变量 三. golang 常量 四. golang 数据类型 五. golang 布尔类型 六. golang 数字 ...
- 【Go编程语言】 Go语言基础语法
Go语言基础语法 文章目录 Go语言基础语法 一.注释 1.单行注释 2.多行注释 二.变量 1.变量的定义 2.变量的初始化 3.理解变量(内存地址) 4.变量交换 5.匿名变量 6.变量的作用域 ...
- Oracle PL/SQL基础语法学习13:比较运算符
系列文章目录 Oracle PL/SQL基础语法学习12:短路求值 Oracle PL/SQL基础语法学习13:比较运算符 Oracle PL/SQL基础语法学习14:BOOLEAN表达式 文章目录 ...
- 一起学Go吧! Go语言基础语法篇二
文章目录 前言 Go 语言指针 Go语言结构体 Go语言切片(Slice) Go 语言范围(Range) Go 语言Map(集合) Go 语言类型转换 Go 语言接口 Go 错误处理 Go并发 通道( ...
最新文章
- 手摇计算机教程视频,使用手摇计算机的照片
- php的filter input,记一个php://filter和php://input的CTF题
- 【组合数学】递推方程 ( 递推方程示例 1 | 列出递推方程 )
- linux添加x权限,Linux 7 的 rc.local 文件需要 添加 +x 权限才会自动执行
- 百练4148:生理周期
- 电脑pin重置_如果忘记了如何重置Windows PIN
- CentOS 安装go client调用Kubernetes API
- scrot截图ubuntu
- nginx 配置路由
- win10 动态磁盘 linux,win10 动态磁盘 无效,win10动态磁盘不能识别
- 没有期刊申请清华博士_没有论文,也可申请麻省理工学院博士及奖学金
- freesurfer对结构核磁共振成像分割输出结果介绍
- 论文解读9——TabNet: Attentive Interpretable Tabular Learning
- 录播系统的服务器有哪些,录播系统
- 如何应对stata do文件打开乱码问题
- 高薪程序员面试题精讲系列96之分库分表了解吗?你项目中用到过吗?怎么用的?
- 联邦学习——用data-free知识蒸馏处理Non-IID
- 致远项目管理SPM系统之合同控制概述
- php 心电图,用canvas画心电图的示例代码
- Linux驱动学习之:WDT(watchdog)驱动
热门文章
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 17: ordinal not in range(128)
- 外贸老业务员是怎么用LinkedIn开发客户的?
- ECharts 使用series.lineStyle.type设置虚线(两种)
- 硬改无人直播系统-使用小技巧
- JDBC连接Mysql(附完整代码)
- NBT:可重复交互式的微生物组分析平台QIIME 2(2021.2发布)
- 数字图像基础——图像通道、空间域表示、图像二值化
- 声音特性介绍——声谱图、音色、音调
- 一个IT大学生来深圳2年半的经历感受
- 软考系统集成项目管理工程师复习加预习冲刺更新中