二维数组函数调用
输入设备-------cpu------输出设备
|
V
存储器
总线:
总线宽度:32位或64位
(1.数据总线2.控制总线3.地址总线)
练习:
定义一个二维整型数组,实现一个函数,
对二维数组元素求和
#include <stdio.h>
int Sum(int a[][4],int row) //数组求和函数
{
int sum=0;
int i=0;
int j=0;
for (i=0;i<row;++i)
{
for (j=0;j<4;++j)
{
sum+=a[i][j];
}
}
return sum;
}
int main(void)
{
int sun=0;
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int row = sizeof(a)/sizeof(a[0]);
int sum = Sum(a,row);
printf("sum=%d\n",sum);
return 0;
}
二维字符型数组做函数形参:
char s[3][10]= { "hello", "world" , "china" };
形式上:
void printStr(char s[][10] ,int row)//注意需要传行数,因为操作多个字符串
本质上:
void printStr(char (*s)[10] ,int row)
实参:
printStr(s,row); //数组名 行数
练习:
准备3个字符串
实现函数找出最大值
#include <stdio.h>
int printStr(char s[][10],int row) //二维字符数组求最大字符串的函数
{
int i=0;
char Max[10]=s[0][10];
for (i=1;i<row;++i)
{
while(s[i][10]!=0)
{
if(Max<s[i][10])
{
Max[10]=s[i][10];
}
}
}
return puts(Max);
}
int main (void)
{
char s[3][10]={"hello","wrold","spiol"};
printStr(s,3);
printf("Max=%s\n",printStr(s,3));
return 0;
}
准备3个字符串排序
#include <stdio.h>
void Paixu(char s[][10],int row) //利用冒泡法排序函数
{
int i=0;
int j=0;
for (i=0;i<row;++i)
{
for (j=i+1;j<row;++j)
{
if (s[j][10]>s[j+1][10])
{
char t[10];
strcpy(t,s[j]);
strcpy(s[j],s[j+1]);
strcpy(s[j+1],t);
}
}
}
}
int main (void)
{
char s[3][10]={"world","hello","apple"};
Paixu(s,3);
int i=0;
for (i=0;i<3;++i)
{
printf("%s\n",s[i]);
}
return 0;
}
标识符 作用域 可见性问题
作用域:
作用的范围
局部变量-------一定在某一个{}范围内
全局变量-------不在主函数和一个{}范围内
可见性:
程序运行到某个点 那些标识符可见
标识符的可见性的规则:
1.先定义,后使用
2.同一作用域中,不能有同名标识符
3.在不同的作用域,同名标识符,相互之间没有影响
4.如果是不同的作用域,
但是作用域之间存在嵌套关系,
则,
内层的作用域的同名标识符,会屏蔽外层的作用域的同名标识符。
(就近原则)
时间上去区分:
动态变量(局部变量-空间是开辟在栈上的--自动申请自动释放) (声明周期):
从定义的语句开始,到所在的作用域范围结束
eg:
栈上的 局部变量
静态变量 (全局变量)
从程序一开始运行,就存在,
直到程序结束时,销毁
eg:
全局变量
static 局部变量
注意:
全局变量(静态变量) --- 此时,
1.不能用变量进行初始化,只能常量初始化
2.静态区的变量 只会被初始化一次
3.值具有 继承性
auto int a; //这个是一个自动变量 --- 栈上开辟的变量
static int a; //静态区
//修饰的是 局部变量
register int a; //CPU 寄存器
//建议性
考点:
1.不能 对其修饰的变量& (取地址)因为寄存器不能通过地址直接访问。
2.不能对register变量进行初始化,也就是,在声明时不能赋初值。
3.编译器可能会忽略你的声明。
4.其实,现在的计算机处理器已经有极高的并行处理能力,内存访问的速度并不是很慢,有时可能并不需要register声明。
register int i; //给程序加速
for( i = 0; i < 100000000; ++i)
{
}
extern int a; //扩展 延伸
//表示 此时这个a 不是在当前文件中定义的 ,
//如果要用,请到别的文件中寻找
//多文件编程
//一般使用在多文件编程中:
//如果想在当前文件使用别的文件中的 全局变量 ,
//此时,可以使用
//extern int a; //做声明
//相当于,把别的文件中的变量作用域扩展到当前文件
//全局变量前面
static 修饰局部变量
//将局部变量 存储在了 全局区(静态区)
//将局部变量的生命周期延长
static 修饰全局变量
//表示 将全局变量 的作用域限定到本文件中
//别的文件中不能extern了
extern 可以放在函数声明中 --函数声明
//表示的意思 --将函数作用域扩展到当前文件
static 加在函数前面
// 此时效果与修饰全局变量效果一样
// 将函数作用域限定到本文件中
面试题:
1.你知道static吗?
指针
定义
访问内存地址 操控硬件
指针:
指针+基本数据据类
指针+数组
指针+函数
指针+指针
1.指针:就是地址-----就是内存的单元的编号
2.指针变量
语法:
基类型* 指针变量名;
基类型-------数据类型//基础数据类型 //数组类 //基类型表示指针变量 指向的目标的数据类型
* --------表示此时定义的白变量是一个指针类型的变量
指针变量名------标识符命名规则+见名知意
int *p;//表示定义了一个指针类型的变量
int *p = &a; //指针变量 p 指向 了 int型变量a
p变量的数据类型 int * //指针类型
&b --地址值 ---类型?
float
b有一块内存空间 -- 放的是float类型的数据
&b ---得到了一块 存放着 float类型数据的 空间的地址
指针访问变量
间接访问 通过地址访问到的
指针的运算
* 指针运算符
* 单目运算
运算数必须是指针类型的值(地址)
*p 过程
1.首先拿出p指针变量中的值(地址) 到内存中定位
2.从定位处开始,偏移出sizeof(基类型)大小的一块空间
3.把这块空间当做一个 基类型的 变量来看
想实现:
被调修改主调
1.想修改谁,就把谁的地址传过去
2.必须要做*运算(间接访问),实现修改
练习:
求两个数的和 --函数
int add(int a,int b)
{
return a + b; //只能带出一个结果
}
#include <stdio.h>
void Sum(int a,int b,int *sum) // 指针求和函数
{
*sum=*a + *b;
return ;
}
int main (void)
{
int a=2;
int b=3;
int sum=0;
Sum(&a,&b,&sum);
printf("sum=%d\n",sum);
return 0;
}
练习:
找出两个数中最大值 最小值
#include <stdio.h>
void compure(int a,int b,int *max,int *min) //比较函数
{
if (a>b)
{
*max=a;
*min=b;
}else
{
*max=b;
*min=a;
}
}
int main(void)
{
int a=0;
int b=0;
int max=0;
int min=0;
scanf("%d%d",&a,&b);
compure(a,b,&max,&min);
printf("MAX=%d\n",max);
printf("MIN=%d\n",min);
}
练习:
main函数中有两个数据
交换a b的值
#include <stdio.h>
void jiaohuan(int *a,int *b) //换位函数
{
int c=*a;
*a=*b;
*b=c;
}
int main(void)
{
int a=0;
int b=0;
printf("a=");
scanf("%d",&a);
printf("b=");
scanf("%d",&b);
jiaohuan(&a,&b);
printf("a=%d \nb=%d\n",a,b);
return 0;
指针 + 数组
一维整型数组
int a[5]; //a首元素的地址
//a[0] -- int型
//&a[0] -- int *
int *p = &a[0];
= a;
a[i] <=> *(a+i) //指针运算
练习:
找最大值 ,指针的方式访问
#include <stdio.h>
int Max(int *p,int len) // 擂台法求最大值函数
{
int i=0;
int t=*p;
for (i=1;i<len;++i)
{
if (*(p+i)>t)
{
t=*(p+i);
}
}
return t;
}
int main (void)
{
int a[10]={6,5,12,3,4,98,10};
int *p=a;
int q=Max(a,10);
printf("Max=%d\n",q);
return 0;
}
作业
1.通过指针,实现数组逆序
#include <stdio.h>
void Reverse_order(int *p,int len) //数组逆序函数
{
int i=0;
int j=0;
for (i=0;i<len/2;++i)
{
int t=0;
t=*(p+i);
*(p+i)=*(p+len-1-i);
*(p+len-1-i)=t;
}
}
int Input(int *p,int len) //输入数组元素函数
{
printf("Enter a number: \n");
int i=0;
for (i=0;i<len;++i)
{
scanf("%d",&*(p+i));
}
}
void Print (int *p,int len) //输出数组元素函数
{
int i=0;
while(i<len)
{
printf("%d ",*(p+i));
++i;
}
putchar('\n');
}
int main(void)
{
int n=0;
printf("Input number: \n"); //输入数组项数
scanf("%d",&n);
int a[n];
int *p=a;
Input(a,n);
Reverse_order(a,n);
Print(a,n);
return 0;
}
2.排序
#include <stdio.h>
void Array_sorting(int *p,int len) //用指针进行数组的插入排序函数
{
int i=0;
int j=0;
for (i=0;i<len;++i)
{
int t=*(p+i);
j=i;
while(j>0 && *(p+j-1 )>t)
{
*(p+j)=*(p+j-1);
--j;
}
*(p+j)=t;
}
}
int Input(int *p,int len) //输入数组元素函数
{
printf("Enter a number: \n");
int i=0;
for (i=0;i<len;++i)
{
scanf("%d",&*(p+i));
}
}
void Print (int *p,int len) //输出数组元素函数
{
int i=0;
while(i<len)
{
printf("%d ",*(p+i));
++i;
}
putchar('\n');
}
int main(void)
{
int n=0;
printf("Input number: \n"); //输入数组项数
scanf("%d",&n);
int a[n];
int *p=a;
Input(a,n);
Array_sorting(a,n);
Print(a,n);
return 0;
}