函数iii数组作为函数参数,作用域及存储类别(11)

昨天学习了一维整型数组作为函数参数,今天来看一下一维字符型数组作为函数参数应该怎么用,以及二维数组和标识符作用域及存储类别的知识;

一、一维字符型数组

参考一维整型数组做函数参数:
形参  数组形式 + 数组长度 
实参  数组名   + 数组长度 

一维字符型数组做函数参数
1.一维字符型数组 --- 用来存放字符串 

因为处理的是字符串数据,字符串操作的 依据,主要看结束标志 '\0'
而不是 数组长度,所以不需要数组长度;只传地址即可;
注意:
   一维字符型数组做函数参数
   形参  数组形式
   实参  数组名

了解了传参形式,练习下面的题目,熟练运用即可;

 练习:
    gets();
     char *gets(char *s)   
    void Gets(char s[])
    {
        从键盘获得字符串, 放到s指定的数组空间中 
        最后 要保证是个字符串 ('\0')
    }

void Gets(char s[])
{
	int i = 0;
	do
	{
		scanf("%c",&s[i]);
	}while(s[i++] != '\n');
	s[i-1] = '\0';
}

练习:
    strlen

size_t strlen(const char *s)    
//size_t  //long int 

int Strlen(char s[])
{
    统计 '\0'前面字符的个数 
}

#include<stdio.h>

int Strlen(char s[])
{
	int i = 0;
	while(s[i] != '\0')
	{
		++i;
	}
	return i;
}

int main(void)
{
	char s[100];
	gets(s);
	int len = Strlen(s);
	printf("%d\n",len);

	return 0;
}

练习:
   strcpy 
   char *strcpy(char *dest, const char *src);
 
   void Strcpy(char dest[],char src[])
   {
      //将src中字符串 复制 到dest 
    }   

#include<stdio.h>

void Strcpy(char dest[],char src[])
{
	int i = 0;
	do
	{
		dest[i] = src[i];
	}
	while(src[i++] != '\0');
}

int main(void)
{
	char a[100];
	char b[100];

	gets(a);

	Strcpy(b,a);

	puts(b);

	return 0;
}

练习:
    strcat 
    char *strcat(char *dest, const char *src);
    
    void Strcat(char dest[],char src[])
    {
       //1.定位到 dest的'\0'位置
       //2.从 '\0'位置开始拷贝 
       //3.dest的最后 '\0'
    }

#include<stdio.h>

void Strcat(char dest[],char src[])
{
	int i = 0;
	int j = 0;
	while(dest[i] != '\0')
	{
		++i;
	}
	while(src[j] != '\0')
	{
		dest[i] = src[j];
		++j;
		++i;
	}
	dest[i] = '\0';
}

int main(void)
{
	char a[100];
	char b[100];

	gets(a);
	gets(b);

	Strcat(a,b);

	puts(a);


	return 0;
}

练习:
    strcmp 

    int strcmp(const char *s1, const char *s2);
     
     int Strcmp(char s1[],char s2[])
     {
             比较结果 ,最后停的位置上的两个字符的 差值 
     }

#include<stdio.h>

int Strcmp(char s1[],char s2[])
{
	int i = 0;
	for(i = 0;i >= 0;++i)
	{
		if(s1[i]!=s2[i] || s1[i]=='\0' || s2[i]=='\0')
			break;
	}
	return s1[i]-s2[i];
	

}

int main(void)
{
	char a[100];
	char b[100];

	gets(a);
	gets(b);

	printf("%d\n",Strcmp(a,b));


	return 0;
}

二、二维数组做函数参数

总结:
    形参   --- 二维数组形式 + 行数    //本质 一维数组 + 长度
    实参   --- 数组名       + 行数    //

int sum(int a[][4],int row)或int sum(int (*a)[4],int row)

调用sum = sum(a,len);

形参里面行数可以省略列数不能省

练习:
    实现一个函数,求二维数组元素的和 
    
练习:
    找出二维数组中主对角上最大值 
    
    1  2  3  4 
    5  6  7  8
    9  10 11 12
    13 14 15 16

我这里写到了一起

#include<stdio.h>

int printArray(int (*a)[4],int len)
{
	int i = 0;
	int j = 0;
	int max = a[0][0];
	int temp;

	for(i = 0;i < len;++i)
	{
		if(max < a[i][i])
		{
			temp = max;
			max = a[i][i];
			a[i][i] = temp;
		}
	}
	for(i = 0;i < len;++i)
	{
		if(max < a[i][len-1-i])
		{
			temp = max;
			max = a[i][len-1-i];
			a[i][len-1-i] = temp;
		}
	}

	return max;
}
#if 0
int printArray(int (*a)[4],int len)
{
	int i = 0;
	int j = 0;
	int sum = 0;

	for(i = 0;i < len;++i)
	{
		for(j = 0;j < 4;++j)
		{
			sum = sum + a[i][j];
		}
	}
	return sum;
}
#endif

int main(void)
{
	int a[4][4] = {18,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	int len = sizeof(a)/sizeof(a[0]);
	int max = 0;
	max = printArray(a,len);
	printf("max = %d\n",max);

	return 0;
}

三、二维字符数组

   做函数参数:
   与二维整型数组 使用方式相同 
    形参   --- 二维数组形式 + 行数    //本质 一维数组 + 长度
    实参   --- 数组名       + 行数    //
   
   注意:
      1.不要和一维字符型数组传参搞混 
一维字符型数组,主要用来存放 字符串数据 
而字符串数据有结束标志('\0'),故,传参时,不需要传长度 
      2.二维字符型数组,用来存储多个字符串

要操作时,往往都是操作多个字符串,而多个字符串没有所谓结束的标志。
看的是数组长度(行数)

练习:
    实现一个输入多个字符串函数 
      inputStr()

#include<stdio.h>

void Gets(char s[])
{
	int i = 0;
	do
	{
		scanf("%c",&s[i]);
	}while(s[i++] != '\n');
	s[i-1] = '\0';
}

void inputStr(char s[][100],int len)
{
	int i = 0;
	for(i = 0;i < len;++i)
	{
		Gets(s[i]);
	}
}

int main(void)
{
	char s[5][100];
	int len = sizeof(s)/sizeof(s[0]);
	inputStr(s,len);

	int i = 0;
	for(i = 0;i < len;++i)
	{
		puts(s[i]);
	}
	return 0;
}

练习:
    排序    //插入排序

#include<stdio.h>
#include<string.h>

void charu(char s[][100],int len)
{
	int i = 0;
	int j = 0;
	char t[100];
	for(i=1;i<len;++i)
	{
		strcpy(t,s[i]);
		j = i;
		while(j>0 && strcmp(t,s[j-1])<0)
		{
			strcpy(s[j],s[j-1]);
			--j;
		}
		strcpy(s[j],t);
	}
}



int main(void)
{
	char s[5][100];
	int len = sizeof(s)/sizeof(s[0]);

	int i = 0;
	for(i = 0;i < len;++i)
	{
		gets(s[i]);
	}

	charu(s,len);

	for(i = 0;i < len;++i)
	{
		puts(s[i]);
	}
	return 0;
}

练习:
  查找 
  要找的字符串

#include<stdio.h>
#include<string.h>

void charu(char s[][100],int len)
{
	int i = 0;
	int j = 0;
	char t[100];
	for(i=1;i<len;++i)
	{
		strcpy(t,s[i]);
		j = i;
		while(j>0 && strcmp(t,s[j-1])<0)
		{
			strcpy(s[j],s[j-1]);
			--j;
		}
		strcpy(s[j],t);
	}
}

int chazhao(char s[][100],int len,char t[])
{
	int mid;
	int begin = 0;
	int end = len;
	int y = 0;
	while(end >= begin)
	{
		mid = (begin + end)/2;
		if(strcmp(s[mid],t)>0)
		{
			end = mid -1;
		}else if(strcmp(s[mid],t)<0)
		{
			begin = mid + 1;
		}else
		{
			y = 1;
			break;
		}
	}
	return y;
}


int main(void)
{
	char s[5][100];
	int len = sizeof(s)/sizeof(s[0]);

	int i = 0;
	for(i = 0;i < len;++i)
	{
		gets(s[i]);
	}

	charu(s,len);

	printf("-------------\n");

	for(i = 0;i < len;++i)
	{
		puts(s[i]);
	}

	printf("-------------\n");
	char t[100];
	gets(t);
	int temp;
	temp = chazhao(s,len,t);
	if(temp == 1)
	{
		printf("yes\n");
	}
	else
	{
		printf("no\n");
	}

	return 0;
}

总结:

   1.一维整型数组 做函数参数
   形参 --- 数组形式 + 数组长度 
   实参 --- 数组名   + 数组长度    
   2.一维字符型数组 做函数参数
   形参 --- 数组形式  
   实参 --- 数组名   
   原型: 一维字符型数组 主要用来存储字符串数据 
   3.二维整型数组 做函数参数
   形参 --- 数组形式 + 行数 //本质 就是一维数组的长度 
   实参 --- 数组名   + 行数 
   4.二维字符型数组 做函数参数
   形参 --- 数组形式 + 行数 //本质 就是一维数组的长度 
   实参 --- 数组名   + 行数 

四、标识符 的 作用域 与 可见性问题:

作用域
      名字 作用的访问 
可见性 
      程序运行到某一个位置 哪些名字可以被使用(被看见)

作用域:
   局部作用域 
        { 
        }  //花括号范围内 就叫局部作用域 
        
        在局部作用域 定义的变量 --- 局部变量 
        在全局作用域 定义的变量 --- 全局变量 
   全局作用域 
       不在 任何一个 {} 范围之内

标识符的可见性的规则:
1.先定义,后使用 
2.同一作用域中,不能有同名标识符
3.在不同的作用域,同名标识符,相互之间没有影响 
4.如果是不同的作用域,但是作用域之间存在嵌套关系,
 则,
 内层的作用域的同名标识符,会屏蔽外层的作用域的同名标识符。
 (就近原则)

C语言的程序5个区


堆                       [数据区]
字符串常量区 
全局区(静态区)
--------------------------------------
代码区                   [代码区]

局部变量
   特点:
       局部变量 空间 一般都开栈上 
       如果不初始化,局部变量中的值是随机值(垃圾值)
全局变量
   特点:
       全局变量 空间  全局区
       如果不初始化,默认初始化为0

时间角度
   生命周期

   int a; //什么a的空间被开辟,什么时候a的空间被销毁 

局部变量的生命周期 
      从程序运行到定义处开始存在,到程序运行到 它作用范围结束 时 销毁
   全局变量(静态变量)的生命周期
      从程序开始运行时就存在了,直到整个程序运行结束时,销毁 
      注意:
          全局变量和静态变量,不能用"变量"进行初始化

五、存储类别的关键字:

auto

表示它是一个自动变量 (局部变量)  ---  自动申请 自动释放 

static

static 修饰局部变量  此时 会被放在 全局区(静态区)
此时 局部变量的生命周期被延长 
注意:
1.static 修饰局部变量 --只会被初始化一次 
2.static 修饰的变量 -- 具有继承性
3.static 修饰的变量 -- 只能用常量初始化 (不能用变量初始化)                

register

寄存器  
表示,把变量 存储 寄存器中 
        for (i = 0; i < 1亿; ++i)
        {
                    
        } //建议性 
                 //register 修饰的变量 ,不能 做 & //(取地址)

extern

外部的  ---表示你的变量 是存在外部的   //多文件编程 
不在当前文件中 
只能 声明 全局变量 
                

static 修饰全局变量 
表示限定全局变量的作用域位本文件,别的文件不能通过extern来声明使用 
用途: 保护私有数据 
防止被引用 
                
修饰函数 //声明函数 在别处的定义的 
static 修饰函数作用和修饰全局变量作用相同
限定作用域为本文件,别的文件不能通过extern来声明使用 

static  
变量 
        局部变量 
                表示将局部变量存放到静态区。
                延长声明周期。
                存在静态区的变量
                a.不能用变量初始化 
                b.只会被初始化一次 
                c.反复使用该变量时,值具有继承性。
        全局变量   
                限定作用域为本文件,别的文件不能通过extern来声明使用 
函数     
        限定作用域为本文件,别的文件不能通过extern来声明使用
           

 [存储类别] 类型 变量名; 

                

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值