C Primer Plus阅读--章节9-10

C Primer Plus阅读–章节9-10

函数原型

函数原型指明了函数的返回值类型和函数接受的参数类型,这些信息称为该函数的名。
对形式参数使用const

  • 如果函数的意图不是修改数组中的数据内容,那么在函数原型和函数定义中声明的形式参数时应使用关键字const。
	int sum(const int ar[], int n);

C99的指定数组初始化器

//该语句会初始化数组中第一个、第三个和第四个位置的的值,剩下位置为0
int arr[4] = {6, [2] = 212, [3] = 70};
//且arr为常量,不能做自增自减运算,如arr++不可以。

//未指定数组大小的,以下语句数组的大小为9,arr[7] = 7, arr[8] = 8
int arr[] = {3, [6] = 231, 7, 8};

int *ptr;
int torf[2][2] = {12,14,16};
ptr = torf[0];
//以上代码*(ptr + 2)的值为16
复合字面量
(int [2]){10, 20};
(int []){50, 20, 90} //内含3个元素

//使用方法
int * ptr1;
ptr1 = (int [2]){10, 20};

变长数组(VLA)

通过变量替代常量,声明数组

int m = 8;
int arr[m];

变长数组在声明的过程中也可以使用

int sum(int, int, int arr[*][*]);

二维数组

初始化

int arr[2][3] = {
	{0, 3, 5},
	{1, 2, 4}
};
或者
int arr[2][3] = {
	0, 3, 5,
	1, 2, 4
};

//数量能对应上就可以

数组和指针

int arr[8] = {0};
=>
arr == arr[0] == &arr[0][0]

int ar[]只能用于声明函数的形式参数,可以替代 int * ar
  • *和++两个运算符的优先级相同,一般为从右至左的顺序进行计算
1.指针和多维数组
int i = 0;
int arr[2][4]= {
       {0,1, 2, 3},
       {4, 5, 6, 7}
};
printf("*(arr[0] + 1) = %d\n", *(arr[0] + 1));
printf("*(arr + 1) = %d\n", **(arr + 1));
printf("i:%p\n", &i);
printf("arr:%p\n", arr);
printf("arr[0]:%p\n", arr[0]);
printf("arr[0][0]:%p\n", arr);
printf("(arr + 1):%p\n", arr + 1);
printf("arr[1]:%p\n", arr[1]);
printf("arr[1][0]:%p\n", &arr[1][0]);
printf("arr[1][3]:%p", &arr[1][3]);
return 0;

//输出;
*(arr[0] + 1) = 1
*(arr + 1) = 4
i:000000000061FE1C
arr:000000000061FDF0
arr[0]:000000000061FDF0
arr[0][0]:000000000061FDF0
(arr + 1):000000000061FE00
arr[1]:000000000061FE00
arr[1][0]:000000000061FE00
arr[1][3]:000000000061FE0C


//实验二
    int i = 0;
    int b = 0;
    int c = 0;
    int d = 0;

    int arr[2][4]= {
            {0,1, 2, 3},
            {4, 5, 6, 7}
    };
    printf("i:%p\n", &i);
    printf("b:%p\n", &b);
    printf("c:%p\n", &c);
    printf("d:%p\n", &d);

    printf("arr[0][0]:%p\n", &arr[0][0]);
    printf("arr[0][1]:%p\n", &arr[0][1]);
    printf("arr[0][2]:%p\n", &arr[0][2]);
    printf("arr[0][3]:%p\n", &arr[0][3]);
    printf("arr[1][0]:%p\n", &arr[1][0]);
    printf("arr[1][1]:%p\n", &arr[1][1]);
    printf("arr[1][2]:%p\n", &arr[1][2]);
    printf("arr[1][3]:%p", &arr[1][3]);
    return 0;

//结果:
i:000000000061FE1C
b:000000000061FE18
c:000000000061FE14
d:000000000061FE10
arr[0][0]:000000000061FDF0
arr[0][1]:000000000061FDF4
arr[0][2]:000000000061FDF8
arr[0][3]:000000000061FDFC
arr[1][0]:000000000061FE00
arr[1][1]:000000000061FE04
arr[1][2]:000000000061FE08
arr[1][3]:000000000061FE0C
  • 由于栈空间是由高地址到低地增长的,所以变量i在栈的高地址:“61FE1C”, 由于本人的电脑是64位的,前面的0就补不了。
  • 随后分析数组的存储方式,可以看到数组的最后一个元素的地址为"61FE0C",与变量i的地址相差了"10000",这数值的大小会随具体情况变化,在定义了四个变量之后,第四个变量与arr[1][3]相差4字节,也就是一个int类型的大小,在这个过程中arr的地址不会变。在增加为5个变量的时候,arr的地址开始变化。以上这个实验可以得出变量之间的距离不一定是固定的,同时数组进入栈空间的时候是先将高位写入高地址。
2.指向多维数组的指针

定义一个指向二维数组的指针

int (*pz)[2]; //指向内涵两个元素的数组
int * pax[2]; //一个包含两个int型指针的数组
3.注意事项

进行两级解引用的情况下是不安全的

const的其他内容

  • 在前面提到的内容是const是用作define的替代,const可以使用的更加灵活。可以创建const数组、const指针和指向const的指针。
  • 指向const的指针可以改变指向的位置,但不能改变指向位置中的值的内容。
double rates[5] = {88.99, 100.12, 56.0, 78,8, 66,8};
const double locked[4] = {0.08, 0.075, 0.0725, 0.07};
const double * pc = rates;  //合法
pc = locked;   //合法
pc = &rates[3];  //合法

可以将非const的数据赋值给const数据,但是不能把const数据赋值给非const数据。(书中提到,只能把非const数据的地址赋值给普通指针)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想考北航的小刺猬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值