一、 数组
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 0 int num = 10; int b[num]; b[2] = 5; int n =3; b[n] = 888; printf("%d %d\n",b[2],b[n]); #endif printf("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}; //局部初始化,没有赋值的元素自动初始化为0 int 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 int t = a[j]; a[j] = a[j+1]; a[j+1] = t; #endif 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 原型:size_t strlen(const char *s); 功能:获取一个字符串的长度 参数:s:要获取长度的字符串 直接传入一个字符串,或者字符数组名都可以 返回值:字符串的长度
#include <stdio.h> #include <string.h> int main(int argc, const char *argv[]) { //strlen函数获取字符串的长度 //获取的长度是这个字符串中第一\0位置之前的长度,不包括\0 char 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会一直从首地址的位置找\0 char 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 原型: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 原型: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复制给了s2 strcpy(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; }