昨天学习了一维整型数组作为函数参数,今天来看一下一维字符型数组作为函数参数应该怎么用,以及二维数组和标识符作用域及存储类别的知识;
一、一维字符型数组
参考一维整型数组做函数参数:
形参 数组形式 + 数组长度
实参 数组名 + 数组长度
一维字符型数组做函数参数
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来声明使用
[存储类别] 类型 变量名;