C++ Primer Plus 第七章

函数通过将返回值复制到指定的CPU寄存器或内存单元来将其返回。随后,调用方通过查看该内存单元来确定返回值。调用方与返回方在需在返回值的类型上达成一致

函数原型指出了函数的返回值类型,编译器就明白了调用方将在指定内存单元读取多少值

void show_array(const double ar[], int n);
void show_array(const double *ar, int n);
PS:这样在函数内部就不能修改ar指向的数组了
PS:同时声明这两个原型会出错,因为C++将const double ar[]解释为const double *ar
PS:但是可以在函数内部改变ar指向的数组,不过这不会改变调用方的数组,因为其实指针本身仍然是一个形参
例如:
#include <iostream>
void show_array(const double ar[], int n){
     const double arr[5] = {-1, 2};
     ar =arr;
     printf("%d\n", ar);
}
int main(){
     double arr[5] = {1, 2, 3, 4, 5};
     show_array(arr, 5);
     printf("%d\n", arr);
}
输出为:
2686446
2686716
地址并不相同,只是指向的地址相同

也可以使用指针区间来设计函数
int sun_arr(const int *begin, const int *end); //分别为数组的起始指针 中止指针

指针与const
int age = 39;
const int *pt = &age; //*pt 是一个指向 const int 的指针,所以不能用pt来修改const的值
*pt = 20; //错误,应为pt是一个指向 const int 的指针,所以不能修改指向目标的值
age=20;  //可行,因为age不是一个const int变量 (╯‵□′)╯︵┻━┻

const float g_earth = 9.8;
const float *pe = &g_earth;     //可行

const float g_earth = 9.8;
float *pe = &g_earth;         //错误,因为无法预知pe的行为
即C++不允许将const地址赋值给非const指针(可以通过类型转换来突破)

int age = 39;               //age++ 可行
int *pd = &age;               //(*pd)++ 可行
const int *pt = pd;          //(*pt)++ 错误

const int **pp2;
int *p1;
const int n = 123;
pp2 = &p1;                    //不可行,因为无法预料到p1的行为,如下
*pp2 = &n                    //可行
*p1 = 10;                    //由于pp2 = &p1,使得此操作可行
把握住一点:C++不允许将const地址赋值给非const指针

const int* const finger //第一个const表示指向的int为const,第二个const表示指针本身为const

函数与二维数组
PS:二维数组的初始化
int data[2][2] = {{1,2},{1,2}};     //普通初始化
int data[2][2] = {1,2,1,2};          //顺序初始化    
int data[][2] = {{1,2},{1,2},{1,2},{1,2}};     //省略第一维初始化    
int data[][2] = {1,2,1,2,1,2,1,2};               //省略第一维顺序初始化    

int data[3][4] = {{1,2,3,4},{5,6,7,8},{2,4,5,8}}
int sum(data,3)     //这里3是行数,因为二维数组可以省略第一维,也就是行来初始化
原型
int sum(int arr2[][4], int size);
int sum(int (*arr)[4], int size);     //指向一个长度为4的数组的指针, int *arr[4] 则为一个指针数组,长度为4,相当于int *(arr[4])
PS:
如果有
double array[5] = {1, 2, 3, 4, 5};
void test(double array[4]);
test(array);                         //这是可以的,因为C++会将double array[4]视为double *ar;,对二维数组的函数参数一样

ar2[r][c] == *(*(ar2+r) + c) //两者同义
arr2                    //指向第一行的地址
arr2 + r                //指向第r行的地址
*(arr2 + r)               //指向第r行第一列的地址
*(arr2 + r) + c          //指向第r行第c列的地址
*(*(arr2 + r) + c)     //取得第r行第c列的值


char str1[3] = {'1','1','1'};     //正确  strlen(str2) -> ?; sizeof(str2) -> 3
char str2[3] = "111";               //错误,缺少\0的位置    
char str2[3] = "11";               //正确  strlen(str2) -> 2; sizeof(str2) -> 3


struct travel_time
{
     int hours;
     int mins;
};
travel_time sum(travel_time t1, travel_time t2)     //这样会进行结构复制
{
     travel_time total;
     total = ...
     return total;               //这里会进行拷贝,所以可以直接return total!但是如果直接返回地址就会出警告,因为返回了函数临时变量!
}
travel_time sum(const travel_time *t1, const travel_time *t2);     //这样就不会进行结构复制
travel_time sum(const travel_time &t1, const travel_time &t2);     //这样似乎更为流行

函数也有地址
double pam(int);          //原型
double (*pt)(int);          //指向原型的函数指针
double * pt(int);          //返回一个double指针的函数
调用时
pf(5) 与 (*pf)(5)          //都可以!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值