输入设备-----CPU-----输出设备
|
存储器
总线(1.数据总线 2.控制总线 3.地址总线)
32位、64位主要说的是 数据总线
总线的宽度
1、一维数组做函数形参
形式上: void printArray(int a[ ],int len)
实际是: void printArray(int *a,int len)
2、一维字符型数组做函数形参
形式上: void printStr(char s[ ])
实际是: void printStr(char *s)
3、二维数组做函数的形参
形式上:void printArray(int a[3][4],int row); // 数组形式,行数
实际是:void printArray(int (*)[4],int row); //
练习1:
定义一个二维整型数组,实现一个函数,对它进行求和
#include
int TwoArray(int a[][4],int row)
{
int i,j;
int sum = 0;
for (i = 0; i < row; ++i)
{
for (j = 0; j < 4; ++j)
{
sum += a[i][j];
}
}
return sum;
}
int main(void)
{
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 = TwoArray(a,row);
printf("sum = %d\n",sum);
return 0;
}
4、二维字符型数组做函数形参:
char s[3][10] = {"hello","world"}; // 批量处理多个字符串
形式上:void printStr(char s[ ][10],int row)// 注意需要传行数,因为操作多个字符串
本质上:void printStr(char (*s)[10],int row)
练习2:
准备3个字符串
实现函数 找出最大值
#include
#include
char String(char s[][10],int row)
{
int i,j;
char max[10];
strcpy(max,s[0]);
for (i = 0; i < row; ++i)
{
if (strcmp(s[i],max) > 0)
{
strcpy(max,s[i]);
j = i;
}
}
return j;
}
int main(void)
{
char s[3][10] = {"hello","world","china"};
char max[10];
int i = String(s,3);
puts(s[i]);
return 0;
}
练习3:
准备3个字符串
排序
#include
#include
void Sort(char s[][10],int row)
{
int i = 0;
int j;
char t[10];
for (i = 0; i < row-1; ++i)
{
for (j = i+1; j < row; ++j)
{
if (strcmp(s[i],s[j]) > 0)
{
strcpy(t,s[i]);
strcpy(s[i],s[j]);
strcpy(s[j],t);
}
}
}
}
char Output(char s[][10],int row)
{
int i = 0;
for (i = 0; i < row; ++i)
{
printf("%s ",s[i]);
}
putchar('\n');
}
int main(void)
{
char s[3][10] = {"hello","world","china"};
int row = sizeof(s)/sizeof(s[0]);
Sort(s,row);
Output(s,row);
return 0;
}
局部变量:一定在某一个{ } 范围内
全局变量:不在任何一个{ } 范围内
程序运行到某个点,哪些标识符可见
标识符的可见性的规则:
1.先定义,后使用
2.同一作用域中,不能有同名标识符
3.在不同的作用域,同名标识符,相互之间没有影响
4.如果是不同的作用域,但是作用域之间存在嵌套关系,
则,内层的作用域的同名标识符,会屏蔽外层的作用域的同名标识符。(就近原则)
分为动态变量和全局变量
声明周期: 从定义的语句开始,到所在的作用域范围结束
动态变量—局部变量-空间是开辟在栈上的--自动申请自动释放(如:栈上的局部变量)
静态变量—全局变量:从程序一开始运行,就存在,直到程序结束时,销毁
全局变量(静态变量) --- 此时,
1.不能用变量进行初始化,只能常量初始化
2.静态区的变量 只会被初始化一次
3.值具有 继承性
1. auto:auto int a; //这个是一个自动变量 --- 栈上开辟的变量
2. static int a; // 把a从局部变量修饰为全局变量(静态区)
(1) static 修饰局部变量
//将局部变量 存储在了 全局区(静态区)
//将局部变量的生命周期延长
(2) static 修饰全局变量
// 表示 将全局变量 的作用域限定到本文件中
// 别的文件中不能extern了
(3) extern 可以放在函数声明中 --函数声明
// 表示的意思 --将函数作用域扩展到当前文件
(4) static 加在函数前面
// 此时效果与修饰全局变量效果一样
// 将函数作用域限定到本文件中
3. register int a; //建议将a定义咋CPU 寄存器(不一定能定义进寄存器);不能取地址&
4. extern int a;
// 延伸,扩展
// 表示 此时这个a 不是在当前文件中定义的
// 如果要用,请到别的文件中寻找(同时编译别的文件)
// 一般使用在多文件编程中:
// 如果想在当前文件使用别的文件中的 ‘’全局变量 ‘’,此时可以使用
// 使用方法extern int a; 做声明;
// 相当于,把别的文件中的变量作用域扩展到当前文件
一、函数的思想 —— 拆
二、函数的语法
三、函数的嵌套调用——递归:主要掌握思想、实现递归两个要素:递推关系 和 结束条件
四、数组作为函数的形参
一维整型
一维字符型——不需要传长度
二维整型
二维字符型——需要传行数row
五、作用域和可行性
指针 + 基本数据类型
指针 + 数组
指针 + 函数
指针 + 函数
指针 + 指针
1、概念搞明白了,一写代码一做题就错一堆
2、简单的普通的题可以做对
3、学到数据结构会用到指针、如果能晕出来就差不多了
是一种数据类型
指针类型专门用来放指针(地址编号)这种数据的
1、指针 <---> 地址 <---> 内存单元的编号
2、指针变量
(1)语法:基类型* 指针变量名;
(2)基类型 --- 数据类型(基本数据类型、数组类型)
表示 指针变量 指向的目标的 数据类型
(3)* --- 表示此时定义的变量是一个指针类型的变量
*用来修饰指针变量名
(4)指针变量名 --- 标识符命名规则 + 见名知意
int *p; // 定义了一个指针类型的变量
p变量的数据类型 int* // 指针类型
int *p = &a ; // 指针变量p指向了int型变量a(p变量的数据类型:int *型)
注意:
1、指针变量的 大小 64位(8字节)32位(4字节)
2、指针类型 —— 存储的是 地址 这种特殊的数据
3、&b --地址值 ---类型?
float b:b有一块内存空间 -- 放的是float类型的数据;
&b ---得到了一块 存放着 float类型数据的 空间的地址
4、* 指针运算符:* 单目运算;运算数必须是指针类型的值(地址)
5、(重点)*p 过程:(*p 后接地址编号)
1.首先拿出 p 指针变量中的值(地址) 到内存中定位
2.从定位处开始,偏移出sizeof(基类型)大小的一块空间
3.把这块空间 当做一个 基类型的 变量来看
6、指针变量的给值:
int *p; // 野指针——随机值被当做了地址
// *p 整体来看就是一个基类型的变量
// 避免野指针——一般初始化NULL
被调修改主调
(1). 想修改谁,就把谁的地址传过去
(2). 必须要做*运算(间接访问),实现修改
求两个数的和 --函数
找出两个数中最大值 最小值
main函数中有两个数据 a=10,b=20;写个函数,交换a b的值
练习1,2,3程序:
#include
void add(int *a,int *b,int *sum)
{
*sum = *a + *b;
}
void cmp(int a,int b,int *max,int *min)
{
if (a > b)
{
*max = a;
*min = b;
}else
*max = b;
*min = a;
}
void swap(int *a,int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
int main(void)
{
int a,b,sum,max,min;
printf("Input two num:\n");
printf("a = ");
scanf("%d",&a);
printf("b = ");
scanf("%d",&b);
putchar('\n');
swap(&a,&b);
// cmp(a,b,&max,&min);
// printf("max = %d\nmin = %d\n",max,min);
printf("a = %d\nb = %d\n",a,b);
return 0;
}
1、算数运算
(1). &
(2). *
(3). p+1指向了下一个一基类型的数据(跳过了一个基类型)
(4). p++
2、关系运算
> >= < <= == !=
p > q p的地址值比q的地址值大
p - q:
前提:同一类型的指针
表示之间差了几个基类型
p + q: 指针不能做加法运算
3、指针 + 数组:
数组本身特点(连续性、单一性、有效性)
(1)int a[5] ;// a首元素的地址
// a[0] -- int型
// &a[0] -- int *
即:int *p = &a[0] = a;
(2)a[ i ] <=> *( a+i ) // 指针运算
(3)野指针 ---指向不明确 ,随机;NULL 表示 0号地址
4、通过指针访问到数组元素:
*(p + i)= a[ i ] = p[ i ] = *(a + i)
找最大值 ,指针的方式访问
#include
void Max(int *max,int *p,int len)
{
int t = *p;
int i;
for (i = 1; i < len; ++i)
{
if (*(p+i) > t)
{
t = *(p+i);
}
}
*max = t;
}
int main(void)
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int max;
Max(&max,a,10);
printf("max = %d\n",max);
}