第五天————数组,指针

数组
整形数组:输入输出均需要通过循环来完成
字符数组:本质就是一个字符串:通过整体去操作:gets,puts, scanf,printf

字符串处理相关的函数:
-----》注意:针对字符串来说

strlen:
strcpy:
strncpy:
strcat:
strncat:
strcmp:
strncmp:
memset:

strlen:
头文件:
#include <string.h>
函数原型:
size_t strlen(const char *s);
功能:求一个字符串的长度(注意:该长度不包含’\0’,有效字符的长度)
参数:所求的字符串的首地址,即数组名
返回值:代表该字符串中的字符个数

strcpy:
#include <string.h>

   char *strcpy(char *dest, const char *src);
   功能:实现两个字符串之间的拷贝
   参数: 
         参数1:目的字符串
		 参数2:源字符串
	            注意:将源字符串拷贝到目的字符串中去
   返回值:
          拷贝成功之后的字符串的首地址

注意: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:源字符串
   返回值:连接成功之后的字符串的首地址
    

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

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

比较规则:
将两个字符串中的字符进行一对一对比较,如果不相等,则直接进行相减得出结果,不再进行比较。
如果相等:则有两种情况:
第一种:相等同时都等于’\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)行数:代表一维数组的个数
     列数:代表每一个一维数组的长度

先练习二维数组的输入输出!

二维字符数组:含有多个(行数决定)字符串的一维数组,所包含的每一个字符串的长度均是由列标来决定。

思考:
定义一个可以存放三个字符串的数组。
----》char str[3][20] = {“haha”,“xixi”,“gaga”};
char str[3][20] = {{“haha”},{“xixi”},{“gaga”}};

思考:如何完成二维字符数组的输入和输出?
通过循环---》一个循环搞定

指针:
在这里插入图片描述

地址:内存单元的一个编号(是以十六进制的数字组合的)
注意:编号是一个常量(不能自加以及自减)

指针:因为一个编号对应一个固定的字节空间,有这种指向关系存在,所以
把地址也形象的称为指针。

指针就是地址,地址就是指针

思考:
将一个普通数值存储起来称为普通变量
要是将一个地址存储起来就应该称为地址变量(地址==指针),所以称为指针变量

指针变量:专门用来存储地址的一类变量

如何定义一个指针变量?
----》
存储类型 数据类型 变量名;
注意:这里的
号是一个标识符,表示定义的变量是一个指针变量,而不是普通变量。

分析:
     存储类型:指针变量自身的存储位置
	 数据类型:指针变量所指向的类型
	 数据类型 *:指针自身的类型

指针的分类:
指针常量:内存单元的编号 (不能自加以及自减)) &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个字节


空指针:
值为0的指针,被头文件<stdio.h>中被宏定义为NULL,
该空指针是不允许被访问的,一旦访问空指针则会引起段错误
野指针:
指向不明确的指针,访问野指针是非常可怕,应该杜绝野指针的出现----》可以通过初始化为NULL即可

作业:
(0)实现二维整形数组的求和

#include <stdio.h>
int main(int argc, const char *argv[])
{
	printf("请输入二维数组的行数和列数\n");
	int M,N;
	scanf("%d%d",&M,&N);
	int arr[M][N];
	int i,j,sum=0;
	printf("请输入%d个元素的值:\n",M*N);
	for(i=0;i<M;i++)
	{
		for(j=0;j<N;j++)
		{
			scanf("%d",&arr[i][j]);
		}
	}
	printf("元素列表:\n");
	for(i=0;i<M;i++)
	{
		for(j=0;j<N;j++)
		{
			printf("%d ",arr[i][j]);
			sum=sum+arr[i][j];
		}
		putchar('\n');
	}
	printf("二维数组元素的和为%d\n",sum);
	return 0;
}

(1)自己实现strcpy,strcat,strcmp的功能
strcat.c

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

strcmp.c

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;
}
 strcpy.c
#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;
}

(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值