例子一
#include<iostream>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5};
int* ptr = (int*)(a+1);
printf("%d",*(ptr-1));
return 0;
}
输出结果是:1,这个很好理解,数组名即数组的首地址,(a+1)等价于a[1],然后取ptr-1的值,则是a[0]
例子二
#include<iostream>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5};
int* ptr = (int*)(&a+1);
printf("%d",*(ptr-1));
return 0;
}
输出结果是:5,这个我有点疑惑,经过研究,原因是这样的:
将数组 a 的地址加上 1,这会使指针 ptr 指向数组 a 的末尾之后的位置。因为数组 a 的类型是 int[5],所以 (&a+1) 指向的是整个数组 a 之后的位置,即指向的是一个越界的内存地址(未定义行为)。
接着,将指针 ptr 指向的地址减去 1,即指向数组 a 的最后一个元素的地址。最后,通过解引用指针 ptr-1 来访问该地址的值,即 5。
例子三
5、定义int a[8];问下面哪些不可以表示a[1]的地址
1、(int*)(&a+1) //相当于a[last]+1
2、(int*)( (char*) &a+sizeof (int))
3、&a[0]+1 //a[1]
4、a+sizeof (int) //a[4]
答案:1和4
四个选项中,第2个我不理解,经过研究,原理是:
把&a被强制转换成char类型的指针,即指向一个字节的地址,即指向第一个元素的首地址,往下偏移4个单位(一个int,4个单位),就是a[1]的起始地址,再把这个指针强制转换成int类型,就是完全指向a[1]的指针,所以这个也是a[1]的地址。
谨记:指针即地址,题目可解
(char*)&a指向的位置是①,
(char*)&a+4指向的是②
例子四
#include <iostream>
using namespace std;
int main() {
int a =5;
float b;
cout<<sizeof(++a + b)<<' ';//4
cout << a;//5
return 0;
}
答案是4 5,sizeof(++a + b)是4能理解,相当于转换成sizeof(int)了,但是,为什么a还是5?a不是自加了吗?
于是,进行了如下实验:
#include <iostream>
using namespace std;
int main() {
int a =5;
cout << a<<' ';
cout<<sizeof(++a)<<' ';
cout << a<<' ';
++a;
cout << a<<' ';
return 0;
}
答案是: 5 4 5 6 ,这说明sizeof比较特殊,在sizeof()这个运算符中自加不算数文章来源:https://www.toymoban.com/news/detail-508302.html
补充:sizeof 接受的参数可以是对象也可以是表达式,但是 sizeof(expression) 在运行时不会对接受的表达式进行计算,编译器只会推导表达式的类型从而计算占用的字节大小;而 strlen 是一个函数,如果接受表达式则会对表达式进行运算。
strlen 本身是库函数,因此在程序运行过程中,计算长度;而 sizeof 是在编译时计算长度;sizeof 的参数可以是类型,也可以是变量,且必须是完整类型;strlen 的参数必须是 char * 类型的变量。
strlen 是头文件 <cstring> 中的函数,sizeof 是 C++ 中的运算符。strlen 测量的是字符串的实际长度,以 \0 结束;而 sizeof 测量的是对象或者表达式类型占用的字节大小。文章来源地址https://www.toymoban.com/news/detail-508302.html
到了这里,关于c语言查漏补缺的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!