当我编写以下程序并使用GNU C++编译器时,1我认为输出是由编译器执行的旋转操作引起的.
#include <iostream>
int main()
{
int a = 1;
std::cout << (a << 32) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但从逻辑上讲,正如所说的那样,如果位溢出位宽就会丢失,输出应为0.发生了什么?
代码在ideone上,http: //ideone.com/VPTwj .
指针的值是变量的地址.为什么int pointerint指针增加1后增加4个字节的值.
在我看来,我认为指针(变量的地址)的值仅在指针递增后增加1个字节.
测试代码:
int a = 1, *ptr;
ptr = &a;
printf("0x%X\n", ptr);
ptr++;
printf("0x%X\n", ptr);
Run Code Online (Sandbox Code Playgroud)
预期产量:
0xBF8D63B8
0xBF8D63B9
Run Code Online (Sandbox Code Playgroud)
实际输出:
0xBF8D63B8
0xBF8D63BC
Run Code Online (Sandbox Code Playgroud)
编辑:
另一个问题 - 如何访问4个字节并int逐个占用?
我可以使用迭代器进行正常计算,即只需通过添加数字来增加它吗?
例如,如果我想删除元素vec[3],我可以这样做:
std::vector<int> vec;
for(int i = 0; i < 5; ++i){
vec.push_back(i);
}
vec.erase(vec.begin() + 3); // removes vec[3] element
Run Code Online (Sandbox Code Playgroud)
它适用于我(g ++),但我不确定它是否可以保证工作.
我在类中声明了一个布尔变量bool abc;,并认为默认情况下它是假的.我的程序中的if条件if (abc)结果为true,所以我输出abc的值,并看到它包含值55.这是正常的吗?我们是否总是要指定'bool abc = false'以确保它是假的?
我和一些人说过这个论点,即C出界指针会导致未定义的行为,即使它们没有被解除引用.例:
int a;
int *p = &a;
p = p - 1;
Run Code Online (Sandbox Code Playgroud)
这里的第三行将导致未定义的行为,即使p永远不会被解除引用(*p从未使用过).
在我看来,如果没有指针被使用,C会检查指针是否超出界限听起来有点不合逻辑(就像有人会检查街上的人,看看他们是否携带枪支以防他们进入他的房子.理想的做法是在人们即将进入房屋时对他们进行检查.我认为如果C检查,那么会发生很多运行时开销.
另外,如果C真的检查OOB指针那么为什么这不会导致UB:
int *p; // uninitialized thus pointing to a random adress
Run Code Online (Sandbox Code Playgroud)
在这种情况下,即使p指向OOB地址的机会很高,为什么也不会发生任何事情.
加:
int a;
int *p = &a;
p = p - 1;
Run Code Online (Sandbox Code Playgroud)
说&a是1000. p评估第三行后的价值是:
p可能在其他地方取消引用并导致真正的问题.因为我认为"第三行被称为未定义的行为"首先是因为未来可能会使用该OOB指针(解除引用),随着时间的推移,人们将其视为一种未定义的行为.现在,值p是100%996还是未定义的行为或其值将是未定义的?
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
virtual int area ()
{ return (0); }
};
class CRectangle: public CPolygon {
public:
int area () { return (width * height); }
};
Run Code Online (Sandbox Code Playgroud)
有汇编警告
Class '[C@1a9e0f7' has virtual method 'area' but non-virtual destructor
Run Code Online (Sandbox Code Playgroud)
如何理解这个警告以及如何改进代码?
[编辑]这个版本现在正确吗?(试图回答用这个概念来阐明自己)
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
virtual ~CPolygon(){};
virtual int area ()
{ return (0); }
};
class CRectangle: public CPolygon {
public: …Run Code Online (Sandbox Code Playgroud) 我有一个关于C中静态变量初始化的问题.我知道如果我们声明一个全局静态变量,默认情况下该值是0.例如:
static int a; //although we do not initialize it, the value of a is 0
Run Code Online (Sandbox Code Playgroud)
但是以下数据结构如何:
typedef struct
{
int a;
int b;
int c;
} Hello;
static Hello hello[3];
Run Code Online (Sandbox Code Playgroud)
是所有成员中的每一个结构hello[0],hello[1],hello[2]初始化为0?
在 K&R(C 编程语言第 2 版)第 5 章中,我阅读了以下内容:
首先,在某些情况下可以比较指针。如果
p和q指向同一个数组的成员,则关系一样==,!=,<,>=,等正常工作。
这似乎意味着只能比较指向同一数组的指针。
但是,当我尝试此代码时
char t = 't';
char *pt = &t;
char x = 'x';
char *px = &x;
printf("%d\n", pt > px);
Run Code Online (Sandbox Code Playgroud)
1 被打印到屏幕上。
首先,我认为我会得到 undefined 或某种类型或错误,因为pt和px没有指向同一个数组(至少在我的理解中)。
也是pt > px因为两个指针都指向存储在栈上的变量,栈向下增长,所以内存地址t大于x?为什么pt > px是真的?
当 malloc 被引入时,我变得更加困惑。 同样在第 8.7 章的 K&R 中写到以下内容:
然而,仍然存在一种假设,即
sbrk可以有意义地比较指向由 返回的不同块的指针。仅允许在数组内进行指针比较的标准并不能保证这一点。因此,这个版本的malloc仅在一般指针比较有意义的机器之间是可移植的。
将指向堆上 malloced …
我今天接受系统编程课程的教授告诉我们,最后定义一个零长度数组的结构:
struct array{
size_t size;
int data[0];
};
typedef struct array array;
Run Code Online (Sandbox Code Playgroud)
这是一个有用的结构,用于定义或初始化带有变量的数组,即如下所示:
array *array_new(size_t size){
array* a = malloc(sizeof(array) + size * sizeof(int));
if(a){
a->size = size;
}
return a;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,使用malloc(),我们还为大小为零的数组分配内存.这对我来说是全新的,而且看起来很奇怪,因为从我的理解来看,结构不必在连续的位置上有它们的元素.
为什么代码在array_new内存中分配data[0]?那么,为什么要访问它是合法的
array * a = array_new(3);
a->data[1] = 12;
Run Code Online (Sandbox Code Playgroud)
?
从他告诉我们的内容来看,似乎在结构的末尾定义为长度为零的数组确保在结构的最后一个元素之后立即出现,但这看起来很奇怪,因为再次,根据我的理解,结构可能有填充.
我也看到这只是gcc的一个特性,并没有任何标准定义.这是真的?