数组:
整形数组:输入输出均需要通过循环来完成
字符数组:本质就是一个字符串:通过整体去操作: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;
}