嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY9
概述:
1,const修饰的指针
2,函数
3,函数的声明
4,指针作为参数传参
5,一维和二维数组的传参
笔记:
1,const修饰的指针
int a = 90;
a = 100;
printf(“a = %d\n”,a);//100
const int a = 90;
a = 100;
总结:
1,被const 修饰的变量的存储位置并不会迁移到常量区,原来在哪里,现在依然在哪里,只是被常量化了
2,const 修饰谁,谁就不能被更改,没有修饰谁,谁就可以被更改
代码演示const修饰
#include <stdio.h>
int main(int argc, const char *argv[])
{
/* const int a = 10;
//a = 100;
int *p = (int *)&a;
*p = 66;
printf("a = %d\n",a);
*/
char *pStr = "wangjia";
*pStr = 'K';
return 0;
}
const 修饰的指针分类:
(1)指向常量的指针:
const int p;//代表p即该指针所指向空间的内容不能被更改,但是可以更改p的指向,以及通过a去修改a的值
int const *p;
(2)指针常量
int const p;//代表p的指向不能被更改,但是可以通过p和a去修改值
验证const修饰指针分类
#include <stdio.h>
int main(int argc, const char *argv[])
{
//验证指向常量的指针
/*int a = 90;
const int *p = &a;
*p = 100;
//int b = 80;
// main(int argc, const char *argv[])
{
//验证指向常量的指针
/*int a = 90;
const int *p = &a;
*p = 100;
//int b = 80;
//p = &b;
a = 80;*/
//验证指针常量
int a = 90;
int b = 79;
p = &b;
a = 80;*/
//验证指针常量
int a = 90;
int b = 79;
int *const p = &a;
//p = NULL;
//*p = 190;
//printf("a = %d\n",a);
a = 77;
printf("a = %d\n",a);
return 0;
}
2,函数:为了实现一个独立的功能,提高代码的复用率
函数的分类:
(1)库函数:系统已经封装好很多的接口函数,只需要调用者正确传参即可
(2)自定义函数:程序员自己定义的函数接口,用于实现特定的功能
函数定义格式:
返回值类型1 函数名(数据类型2 形参名1,数据类型3 形参名2…)
{
函数体;//代码的实现过程
返回值;//注意:函数的返回值应该和返回值类型保持一致
}
分析:
返回值:需要反馈给调用者的一个结果。
函数名:一般见名知义。
数据类型2:就是调用者传递给子函数的参数的类型。
练习:自己声明一个函数初步认识
#include <stdio.h>
//函数的声明
int cal_add(int num1,int num2);
//定义一个函数:实现打印“哈哈哈哈哈”;
void print_haha()
{
//函数体
printf("hahahahha\n");
printf("hahahahha\n");
printf("hahahahha\n");
}
int func(int value)
{
printf("fun-----%d\n",value);
return value;
}
int main(int argc, const char *argv[])
{
//调用字函数实现打印
/*print_haha();
* */
int num1,num2;
printf("please input two numbers:\n");
scanf("%d%d",&num1,&num2);
//封装字函数实现两个数求和
int sum = cal_add(num1,num2,12,34,56);
printf("sum = %d\n",sum);
//printf("%d\n",cal_add(num1,num2));
//int value = 6;
//printf("%d\n",func(value));
//func(34);
//func(value*value);
return 0;
}
//封装加法函数
int cal_add(int num1,int num2)
{
return num1 + num2;
}
总结:
1,函数在传参时,参数个数和类型应该和形参类型以及个数保持一致
2,实参名和形参名可以重名,因为形参和实参是两块独立的内存空间
3,函数传参时可以传变量,常量,或者表达式(只要是一个确定的值就行)
4,当需要在子函数中修改形参值的同时起到修改实参的值,就需要将实参的地址作为参数传递给形参
传参的方式:
(1)值传递
(2)址传递
练习:
1.声明一个函数,调用来交换两个数据
#include <stdio.h>
void swap(int *A,int *B)
{
//交换
int Temp;
Temp = *A;
*A = *B;
*B = Temp;
}
int main(int argc, const char *argv[])
{
//实现两个数的交换
int num1,num2;
scanf("%d%d",&num1,&num2);
printf("交换之前: num1 = %d\tnum2 = %d\n",num1,num2);
swap(&num1,&num2);
printf("交换之后: num1 = %d\tnum2 = %d\n",num1,num2);
return 0;
}
2.写一个函数用来调用两数相加和
#include <stdio.h>
void add(int *argc1,int *argc2,int *pSum)
{
*pSum = *argc1 + *argc2;
}
int main(int argc, const char *argv[])
{
int num1,num2;
scanf("%d%d",&num1,&num2);
int value = 0;
add(&num1,&num2,&value);
printf("value = %d\n",value);
return 0;
}
注:这里两个联系题代码声明的函数都是无返回值的,且形参会将实参中的数据拷贝过去,进行交换时其实只交换了形参中的数据,程序运行出来的结果还是没有交换,为了避免这种问题采用指针方法,将地址传过去通过地址改变数据。
3,函数的声明
作用:帮助编译器进行语法检查(检查实参的个数和类型是否与形参的个数以及类型相匹配)
写法:直接拷贝函数头,在其末尾添加分号即可
4,指针作为参数传参
案例:封装子函数实现两个整形数的交换
5,一维数组的传参
数组的传参:
操作数组相当于是在操作一片连续的空间
操作连续空间的要素:
(1)什么时候开始—》首地址
(2)什么时候结束—》元素个数
对于一维数组的传参:
//int Input_arrValues(int *pArr)
int Input_arrValues(int pArr[])
//int Output_arrValues(int *pArr)
int Output_arrValues(int pArr[])
注意:当数组作为参数进行传参时,会被退化成一个指针来使用,这里的[]其实就是一个*
练习:
一维数组输入输出封装函数练习
#include <stdio.h>
#define N 5
//int Input_arrValues(int *pArr)
int Input_arrValues(int pArr[])
{
printf("sizeof(pArr) = %d\n",sizeof(pArr));
//入参检查
if(NULL == pArr)
{
printf("NULL_IN_ERROR!\n");
return -1;
}
int i;
for(i=0;i<N;i++)
{
scanf("%d",&pArr[i]);
//scanf("%d",pArr+i);
}
return 0;
}
//int Output_arrValues(int *pArr)
int Output_arrValues(int pArr[])
{
//检查
if(NULL == pArr)
{
printf("NULL_OUT_ERROR!\n");
return -1;
}
int i;
for(i=0;i<N;i++)
{
printf("%d ",pArr[i]);
//printf("%d ",*(pArr+i));
}
printf("\n");
return 0;
}
int main(int argc, const char *argv[])
{
//封装函数实现一维数组的输入和输出
int arr[N] = {0};
printf("sizeof(arr) = %d\n",sizeof(arr));
//输入
int op = Input_arrValues(arr);
if(-1 == op)
{
return -1;
}
printf("输入成功!\n");
//输出
op = Output_arrValues(arr);
if(-1 == op)
{
return -1;
}
printf("输出成功!\n");
return 0;
}
二维数组的传参:
//int Input_Arr_Values(int (*pArr)[N])
int Input_Arr_Values(int pArr[][N])
//int Output_Arr_Values(int (*pArr)[N])
int Output_Arr_Values(int pArr[][N])
练习:
二维数组输入输出封装函数练习
#include <stdio.h>
#define M 3
#define N 4
//int Input_Arr_Values(int (*pArr)[N])
int Input_Arr_Values(int pArr[][N])
{
//入参检查
if(NULL == pArr)
{
printf("NULL_IN_ERROR!\n");
return -1;
}
int i,j;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
//scanf("%d",*(pArr+i)+j);
//scanf("%d",&pArr[i][j]);
scanf("%d",pArr[i]+j);
}
}
return 0;
}
//int Output_Arr_Values(int (*pArr)[N])
int Output_Arr_Values(int pArr[][N])
{
//入参检查
if(NULL == pArr)
{
printf("NULL_OUT_ERROR!\n");
return -1;
}
int i,j;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
//printf("%d ",*(*(pArr+i)+j));
//printf("%d ",pArr[i][j]);
printf("%d ",*(pArr[i]+j));
}
printf("\n");
}
return 0;
}
int main(int argc, const char *argv[])
{
//封装函数实现二维数组的输入输出
int arr[M][N] = {0};
//输入
int op = Input_Arr_Values(arr);
if(-1 == op)
{
return -1;
}
printf("输入成功!\n");
//输出
op = Output_Arr_Values(arr);
if(-1 == op)
{
return -1;
}
printf("输出成功!\n");
return 0;
}
作业:
利用函数封装实现之前的作业(都尝试去封装(一维,二维));