C++函数复习、练习题(笔记一)

作为记录下本次c++学习过程

一、指针部分(因为涉及到指针函数,顺便复习一次指针

   何为指针:指针即是一个变量,该变量存放的是一个地址(来自:c++ Primer Puls)

   我个人是比较赞同这一个说法,下面我会通过代码来解释我是如何理解这个观点。

1.指针指向变量

    实现效果:a的值等于*p的值,&a的值等于p的值

#include <iostream>
//#include<string.h>
//#include<stdio.h>
using namespace std;
int main()
{
	int a = 10;
	int* p;
	//记住指针同样是变量,存放的是地址
	//p = a; //此写法错误,a是变量,此时p存放的是变量a,是一个数值
	p = &a;//此写法正确,“&”为运算符,获取该变量的地址,此时p存放的是a的地址

	cout << "a:" << a << endl;
	cout << "&a:" << &a << endl;
	cout << "p:" << p << endl;
	cout << "*p:" << *p << endl;
    //前面说指针其实就是一个变量,那么这个变量同样是有一个存放的地址
    cout << "&p: " << &p << endl; 
		return 0;

}

2.指针指向一维数组

#include <iostream>
//#include<string.h>
//#include<stdio.h>
using namespace std;
int main()
{
	int a[8] = {1,3,5,7,9,11,13,15};
	/*
	  首先要知道一点,当你初始化一个数组之后,该数组会按照初始化的大小,分配出一个对应大小的空间。
	  int类型的变量是4个字节,那对应此数组就有需要占用32个字节
	  */
	//在指针指向数组前,先看下数组a的信息,以第一个值作为演示
	cout << "(sizeof)a: " << sizeof(a) << endl;//数组a占用的长度
	cout << "(sizeof)int: " << sizeof(int) << endl;//一个int整型占用的长度
	//在一维数组中a和&a没有本质上的差别,都是数组的第一个元素,但是同样+1之后就会有本质上的差别
	cout << "a: " << a << endl;
	cout << "&a: " << &a << endl;
	cout << "a+1: " << a+1 << endl;//数组a的下一个整型的起始地址
	cout << "&a+1: " << &a+1 << endl;//与数组a相同大小(32个字节)的下一个数组的起始地址,也可以认为是数组a结束地址

	//cout << "&(a+1): " << &(a+1) << endl; //此写法不被允许
	cout << "a[0]: " << a[0] << endl;
	cout << "&a[0]: " << &a[0] << endl << endl;
	//对于一维数组要有本质上的理解,才可以更好的理解指针数组,当然也可以死记,不去追究
	// 
	//记住指针同样是变量,存放的是地址
	int* p1 = a;
	//int* p2 = &a;//此写法不被允许
	//int* p3 = a[0];//此写法不被允许
	int* p4 = &a[0];


	cout << "p1: " << p1 << endl;
	cout << "&p1: " << &p1 << endl;
	cout << "*(&p1): " << *(&p1) << endl;
	cout << "*(*(&p1)): " << *(*(&p1)) << endl;
	cout << "&p1+1: " << &p1+1 << endl;
	cout << "*(&p1+1): " << *(&p1 + 1) << endl;
	//cout << "&(p1+1): " << &(p1+1) << endl;//此写法不被允许
	cout << "*p1: " << *p1 << endl;
	cout << "*p1+1: " << *p1 + 1 << endl;
	cout << "*(p1+1): " << *(p1+1) << endl << endl;

	cout << "p4: " << p4 << endl;
	cout << "&p4: " << &p4 << endl;
	cout << "*(&p4): " << *(&p4) << endl;
	cout << "*(*(&p4)): " << *(*(&p4)) << endl;
	cout << "&p4+1: " << &p4 + 1 << endl;
	cout << "*(&p4+1): " << *(&p4 + 1) << endl;
	//cout << "&(p4+1): " << &(p4+1) << endl;//此写法不被允许
	cout << "*p4: " << *p4 << endl;
	cout << "*p4+1: " << *p4 + 1 << endl;
	cout << "*(p4+1): " << *(p4 + 1) << endl;

	return 0;
}

指针过程解释(从编译的角度进行理解)

①int* p1 = a;//指针p1指向数组a的首地址
    int* p4 = &a[0];//指针p4指向数组a的起始地址

②&p1、&p4//代表的是存放指针的地址(指针也是变量,是变量就要有地址存放),此处不深究

③*(&p1)、*(&p4

看到 可以认为是指针的效果,注意只是效果!!。他们指向的是&p1、&p4里面的内容,结合②,可知*(&p1)、*(&p4)的值等价于p1、p4的值

④*(*(&p1))、*(*(&p4)) 最终指向的就是数组a的第一个元素

这四个点要需要结合一些链表的思想才可以更好地理解

例如:

       我有8本书按照1-8的编号,并按顺序放在了图书馆的2号书架第1-8层的。这天小红问我,想拿我的1号书,我应该怎么告诉小红(这就相当于怎么取出数组a的第一个元素)??

        答:我在一张纸上写着图书馆2号书架第一层,那么小红想拿到那就首先需要拿到这一张纸,这一张纸在我这,找到我就相当于找到了这一张纸(我和纸是等价的),这就是第一个地址,即&p1=&我(纸张)。当小红拿到纸张后,就可以看到纸张内容(纸张内容等价图书馆2号书架第一层这就是第二个地址,*(&p1)=*(纸张内容)。最后根据纸张内容找到书籍,*(*(&p1))= *(图书馆2号书架第一层)。这里我觉着已经是很清楚的讲解,用普通一点的就是套娃,相当于中国广东佛山市一样,你要知道中国,才会知道广东,最后才可以知道佛山,不然是不可能一下子知道佛山的。

⑤&p1+1、&p4+1  代表存放指针的地址+1,增加的长度是指针类型的长度,此处不深究

⑥*(&p1+1)、*(&p4+1) 代表存放指针的地址+1后的值,因为我都没有初始化,所以是系统随意赋值,此处不深究

在一维数组中无论是a还是&a[0],都指向数组的首地址,所以*p1和*p4、*p4+1和*p1+1、*(p1+1)和*(p4+1)三者相互之间等价。

3.指针指向二维数组(与一维数组同解)

#include <iostream>
//#include<string.h>
//#include<stdio.h>
using namespace std;
int main()
{
	int a[4][3] = {
				   {1,3,5,},
				   {9,11,13},
				   {2,4,6},
				   {10,12,14}
	              };

	
	//二维数组赋值同样,指针存储的是第一个元素(是二维元素里的)的地址,如下
	int* p1 = a[0];
	int* p4 = &a[0][1];


	cout << "p1: " << p1 << endl;
	cout << "&p1: " << &p1 << endl;
	cout << "*(&p1): " << *(&p1) << endl;
	cout << "*(*(&p1)): " << *(*(&p1)) << endl;
	cout << "&p1+1: " << &p1 + 1 << endl;
	cout << "*(&p1+1): " << *(&p1 + 1) << endl;
	//cout << "&(p1+1): " << &(p1+1) << endl;//此写法不被允许
	cout << "*p1: " << *p1 << endl;
	cout << "*p1+1: " << *p1 + 1 << endl;
	cout << "*(p1+1): " << *(p1 + 1) << endl << endl;

	cout << "p4: " << p4 << endl;
	cout << "&p4: " << &p4 << endl;
	cout << "*(&p4): " << *(&p4) << endl;
	cout << "*(*(&p4)): " << *(*(&p4)) << endl;
	cout << "&p4+1: " << &p4 + 1 << endl;
	cout << "*(&p4+1): " << *(&p4 + 1) << endl;
	//cout << "&(p4+1): " << &(p4+1) << endl;//此写法不被允许
	cout << "*p4: " << *p4 << endl;
	cout << "*p4+1: " << *p4 + 1 << endl;
	cout << "*(p4+1): " << *(p4 + 1) << endl;

	return 0;
}

4.指针指向结构体   

结构体指针算是比较好理解的,就是注意const的用法,修饰谁,谁就无法通过指针改变

#include <iostream>
#include<string.h>
//#include<stdio.h>
using namespace std;
struct student
{
	char name[10];
	char gender[10];
	int age;
};

//结构体指针,结合const一起使用
void s2_message_change(const student S1,student *S2)
{
	strcpy_s(S2->name,S1.name);
	strcpy_s(S2->gender,S1.gender);
	S2->age = S1.age;
}


int main()
{
	//定义两个结构体
	struct student s1;
	struct student s2;

	student* p; //定义结构体指针
	p = &s2; //指针一定是存放地址!!

	//结构体赋值
	strcpy_s(s1.name, "张三");
	strcpy_s(s1.gender, "男");
	s1.age = 18;

	strcpy_s(p->name, "李四");
	strcpy_s(p->gender, "女");
	p->age = 20;

	cout << "s1.name: " << s1.name << endl;
	cout << "s1.gender: " << s1.gender<< endl;
	cout << "s1.age: " << s1.age << endl << endl;

	cout << "s2.name: " << s2.name << endl;
	cout << "s2.gender: " << s2.gender << endl;
	cout << "s2.age: " << s2.age << endl << endl;

	cout << "p->name: " << p->name << endl;
	cout << "p->gender: " << p->gender << endl;
	cout << "p->age: " << p->age << endl << endl;

	s2_message_change(s1, p);

	cout << "p->name_change: " << p->name << endl;
	cout << "p->gender_change: " << p->gender << endl;
	cout << "p->age_change: " << p->age << endl << endl;
	return 0;
}

 5.指针指向函数 

#include <iostream>
//#include<string.h>
//#include<stdio.h>
using namespace std;

double betsy(int);
double pam(int);
void estimate(int line, double (*pf)(int));

//定义两个返回函数
double betsy(int lns)
{
	return 0.05 * lns; 
}

double pam(int lns)
{
	return 0.03 * lns + 0.0004 * lns * lns;
}

void estimate(int line, double (*pf)(int))
{
   //*pf 代表传入的函数,(int)代表传入该函数的值,要与返回函数定义的相匹配
	cout << line << "lines will take\n";
	cout << (*pf)(line) << "hour(s)\n";
}

void main()
{
	int code;
	while (1)
	{

	cout << "How much lines of code do you need?\n";
	cin >> code; //输入一个整型值计算
	cout << "Here is Betsy's estimate:\n";
	estimate(code, betsy); //指针函数传入并返回输出
	cout << "Here is Pam's estimate:\n";
	estimate(code, pam); //指针函数传入并返回输出

	}

}

    

            

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个关于C函数指针的练习题的示例代码: ```cpp #include <iostream> using namespace std; // 定义一个函数指针类型 typedef void (*FuncPtr)(int); // 定义一个函数,将传入的整数加1并打印 void addOne(int num) { cout << num + 1 << endl; } // 定义另一个函数,将传入的整数乘以2并打印 void multiplyByTwo(int num) { cout << num * 2 << endl; } int main() { int choice; int num; FuncPtr funcPtr; cout << "请选择操作:1.加1 2.乘以2" << endl; cin >> choice; // 根据用户选择设置函数指针 if (choice == 1) { funcPtr = addOne; } else if (choice == 2) { funcPtr = multiplyByTwo; } else { cout << "无效的选择" << endl; return 0; } cout << "请输入一个整数:" << endl; cin >> num; // 调用函数指针指向的函数 funcPtr(num); return 0; } ``` 这段代码定义了一个函数指针类型 `FuncPtr`,然后根据用户的选择设置函数指针的值。根据选择的不同,函数指针指向不同的函数,然后通过函数指针调用相应的函数。用户输入一个整数,然后根据选择的操作,对该整数进行相应的处理并打印结果。 请注意,这只是一个示例代码,实际的练习题可能会有所不同。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C++函数、指针、结构体(黑马程序员教程笔记)](https://blog.csdn.net/anlihuaer/article/details/120686223)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++指针题](https://blog.csdn.net/qq_62637200/article/details/126795026)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值