前言:
在上章及其上上章中练习了整形和字符串的计算
那么在本章中给大家提供有关指针和二维数组的习题计算
首先先进行二维数组的计算
复习一下定义:大家还记得吗?
二维数组
二维数组的定义:
在C语言中,二维数组可以被视为一维数组的数组。例如,定义一个3行4列的二维数组a
,可以这样写:
int a[3][4];
这里的a
是一个包含3个一维数组的数组,每个一维数组包含4个整数。
欧克
上习题
一
1.
#include <stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof(a[0][0]));
printf("%zd\n", sizeof(a[0]));
printf("%zd\n", sizeof(a[0] + 1));
printf("%zd\n", sizeof(*(a[0] + 1)));
printf("%zd\n", sizeof(a + 1));
printf("%zd\n", sizeof(*(a + 1)));
printf("%zd\n", sizeof(&a[0] + 1));
printf("%zd\n", sizeof(*(&a[0] + 1)));
printf("%zd\n", sizeof(*a));
printf("%zd\n", sizeof(a[3]));
return 0;
}
1. 48 : a是数组名,单独放在sizeof内部,表示整个数组, 计算的是整个数组的大小,单位是字节3*4*4 = 48
2. 4 a[0][0]是第一行第一个元素,也就是4个字节大小。
3. 16 a[0]是第一行这个一维数组的数组名,数组名单独放在sizeof内部,计算的是第一行这个一维数组的大小,也就是 4*4=16个
4. 4 / 8
a[0]是数组名,这里表示数组首元素的地址,是第一行第一个元素的地址
a[0] + 1就是第一行第二个元素的地址,是地址大小就是 4 / 8
5. 4 *(a[0] + 1))是第一行第二个元素-大小是4个字节
6. 4 / 8 a+1就是第二行的地址,是地址就是4/8个字节,a是二维数组的数组名,在这里表示首元素的地址,也就是第一行的地址, a+1就是第二行的地址
7. 16
a + 1是第二行的地址,*(a+1)得到的就是第二行, int(*)[4] 对数组指针解引用,放一个数组,就是一行的一维数组,*(a+1) == a[1], a[1]是第二行的数组名,sizeof(arr[1])计算的是第二行的大小
8. 4 / 8:
a[0]是第一行的数组名,&a[0]取出的是第一行这个一维数组的地址,&a[0]+1就是第二行的地址
9. 16 *(&a[0] + 1)是第二行,计算的是第二行的大小,16个字节
10.16 a是二维数组的数组名,a是首元素的地址,就是第一行的地//址,*a就是第一行, 计算的是第一行的大小,16个字节,*a == *(a+0) == a[0]
11.16: 没有越界访问,sizeof内部的表达式是不计算的. sizeof(int) - 4 sizeof(4+3);--4
strlen
那strlen函数呢,可以用来计算数组嘛?
答案是不可以的。
strlen
是一个用于计算字符串长度的函数,若用来计算数组,则程序会奔溃的。
指针变量
指针变量的定义
在C语言中,指针变量用于存储另一个变量的内存地址。指针变量的定义格式如下:
类型名 *指针变量名;
例如:
- 声明一个整型指针:
int *p;
- 声明一个字符型指针:
char *cptr;
- 声明一个浮点型指针:
float *fptr;
const
- 修饰一般变量:
const int n = 5;
或int const n = 5;
。这两种写法等价,表示变量n
的值不能被改变。
- 修饰指针:
const int *p;
或int const *p;
:指针p
可以改变,但p
指向的内容不能改变。int *const p;
:指针p
不能改变,但p
指向的内容可以改变。const int *const p;
:指针p
不能改变,且p
指向的内容也不能改变。
习题一如下:
#include <stdio.h>
int main()
{
const char* p = "abcdef";
printf("%zd\n", sizeof(p));
printf("%zd\n", sizeof(p + 1));
printf("%zd\n", sizeof(*p));
printf("%zd\n", sizeof(p[0]));
printf("%zd\n", sizeof(&p));
printf("%zd\n", sizeof(&p + 1));
printf("%zd\n", sizeof(&p[0] + 1));
return 0;
}
1. 4 / 8 p是一个指针变量,大小就是 4 / 8个字节。
2. 4 / 8 p中存放的是'a'的地址,p+1是'b'的地址,大小就是4/8个字节。
3. 1 *p=='a'。
4. 1 p[0]==*(p+0)==*p,结果就同上,也就是第一个元素 'a'。
5. 4 / 8 &p是指针变量p的地址是地址大小就是 4 / 8个字节。
6. 4 / 8 &p + 1还是地址大小是4/8个字节,&p+1是指向p变量的后边,&a+n 后仍是地址。
7. 4 / 8 &p[0] + 1是'b'的地址,大小是4/8个字节。
习题二:
int main()
{
char* p = "abcdef";
printf("%zd\n", strlen(p));
printf("%zd\n", strlen(p + 1));
//printf("%zd\n", strlen(*p));
//printf("%zd\n", strlen(p[0]));
printf("%zd\n", strlen(&p));
printf("%zd\n", strlen(&p + 1));
printf("%zd\n", strlen(&p[0] + 1));
return 0;
}
1. 6: p里边存放是'a'的地址,也就是计算 abcdef
2. 5: p+1是'b'的地址,也就是计算 bcdef
3.非法访问, *p是'a'
4.非法访问,效果同上
5. 随机值
&p是p这个变量的地址,strlen就是从p这块空间的起始地址开始向后找\0的
p中存放的地址是不确定的,所有有没有\0,什么时候会遇到\0都不确定
6. 随机值
&p+1是p变量后边的地址,从这个位置向后的内存数据不知道
什么时候会遇到\0都不确定7. 5