我想做一些看似相当简单的事情.我得到了结果,但问题是,我无法知道结果是否正确.
我在C工作,我有两个指针; 我想打印指针的内容.我不想取消引用指针来获取指向的值,我只想要指针存储的地址.
我写了下面的代码,我需要知道的是,如果它是正确的,如果没有,我该如何纠正它.
/* item one is a parameter and it comes in as: const void* item1 */
const Emp* emp1 = (const Emp*) item1;
printf("\n comp1-> emp1 = %p; item1 = %p \n", emp1, item1 );
Run Code Online (Sandbox Code Playgroud)
虽然我发布这个(以及重要的是它是正确的)是我最终需要这样做一个指针到指针.那是:
const Emp** emp1 = (const Emp**) item1;
Run Code Online (Sandbox Code Playgroud) 普通的民间传说说:
类型系统存在是有原因的.整数和指针是不同的类型,它们之间的转换在大多数情况下是一种弊端,可能表示设计错误,应该避免.
即使执行了这样的强制转换,也不应该对整数和指针的大小做出任何假设(强制void*转换int是使代码在x64上失败的最简单方法),而不是int应该使用intptr_t或uintptr_t来自stdint.h.
知道什么时候执行这样的演员表真的有用吗?
(注意:可移植性价格的代码稍微短一点并不算"实际上有用".)
我知道一个案例:
更多的东西?
我可以使用NULL指针代替 的值0吗?
或者这样做有什么问题吗?
比如,例如:
int i = NULL;
Run Code Online (Sandbox Code Playgroud)
作为替代:
int i = 0;
Run Code Online (Sandbox Code Playgroud)
作为实验,我编译了以下代码:
#include <stdio.h>
int main(void)
{
int i = NULL;
printf("%d",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
Run Code Online (Sandbox Code Playgroud)
事实上,它给了我这个警告,这本身是完全正确的:
warning: initialization makes integer from pointer without a cast [-Wint-conversion]
Run Code Online (Sandbox Code Playgroud)
但结果仍然是等价的。
NULL吗?NULL在算术表达式中用作数值有什么问题吗?我已阅读的答案是什么NULL之间的区别,“\ 0”和0大约之间的区别是什么NULL,\0以及0是的,但我没有从那里简洁的信息,如果是很允许的,也是正确的使用NULL作为在赋值和其他算术运算中使用的值。
我知道它提高了可读性并使程序不易出错,但它提高了多少性能?
在旁注中,参考和const指针之间的主要区别是什么?我会假设它们以不同的方式存储在内存中,但是如何呢?
我试着理解我是如何std::unique_ptr工作的,并且我找到了这个文件.作者从以下示例开始:
#include <utility> //declarations of unique_ptr
using std::unique_ptr;
// default construction
unique_ptr<int> up; //creates an empty object
// initialize with an argument
unique_ptr<int> uptr (new int(3));
double *pd= new double;
unique_ptr<double> uptr2 (pd);
// overloaded * and ->
*uptr2 = 23.5;
unique_ptr<std::string> ups (new std::string("hello"));
int len=ups->size();
Run Code Online (Sandbox Code Playgroud)
令我困惑的是,在这一行
unique_ptr<int> uptr (new int(3));
Run Code Online (Sandbox Code Playgroud)
我们使用整数作为参数(在圆括号之间)和这里
unique_ptr<double> uptr2 (pd);
Run Code Online (Sandbox Code Playgroud)
我们使用指针作为参数.它有什么不同吗?
对我来说还不清楚的是,以这种方式声明的指针将如何与以"正常"方式声明的指针不同.
假设我定义了一些类:
class Pixel {
public:
Pixel(){ x=0; y=0;};
int x;
int y;
}
Run Code Online (Sandbox Code Playgroud)
然后使用它编写一些代码.我为什么要这样做?
Pixel p;
p.x = 2;
p.y = 5;
Run Code Online (Sandbox Code Playgroud)
来自Java世界我总是写:
Pixel* p = new Pixel();
p->x = 2;
p->y = 5;
Run Code Online (Sandbox Code Playgroud)
他们基本上做同样的事情,对吗?一个在堆栈上而另一个在堆上,所以我将在以后删除它.两者之间有什么根本区别吗?为什么我更喜欢一个呢?
指针的目的是保存特定变量的地址.那么下面代码的内存结构应如下所示:
int a = 5;
int *b = &a;
Run Code Online (Sandbox Code Playgroud)
......内存地址......值 a ... 0x000002
................... 5
b ... 0x000010 ..... .............. 0x000002
好的.然后假设现在我想保存指针*b的地址.然后我们通常定义一个双指针,**c,as
int a = 5;
int *b = &a;
int **c = &b;
Run Code Online (Sandbox Code Playgroud)
然后内存结构看起来像:
......内存地址......值 a ... 0x000002
................... 5
b ... 0x000010 ..... ............... 0x000002
c ... 0x000020 ................... 0x000010
所以**c指的是*b的地址.
现在我的问题是,为什么这种类型的代码,
int a = 5;
int *b = &a;
int *c = &b;
Run Code Online (Sandbox Code Playgroud)
产生警告?
如果指针的目的只是为了保存内存地址,我认为如果我们要保存的地址是指变量,指针,双指针等,那么应该没有层次结构,所以下面的代码类型应该是有效.
int a = 5;
int *b = &a;
int *c = &b; …Run Code Online (Sandbox Code Playgroud) 假设我有两个指针:
int *a = something;
int *b = something;
Run Code Online (Sandbox Code Playgroud)
如果我想比较它们并看它们是否指向同一个地方(a == b)工作?
我正在通过为GAE编写应用程序来学习Go,这是处理函数的签名:
func handle(w http.ResponseWriter, r *http.Request) {}
Run Code Online (Sandbox Code Playgroud)
我是指针新手,所以为什么Request对象是一个指针,但ResponseWriter不是?有没有必要这样做或者这只是为了使某种基于高级指针的代码成为可能?
volatile是告诉编译器不要优化引用,这样每次读/写都不会使用存储在寄存器中的值,而是进行实际的内存访问.我可以理解它对一些普通变量有用,但不明白如何volatile影响指针.
volatile int *p = some_addr;
int a = *p; // CPU always has to load the address, then does a memory access anyway, right?
Run Code Online (Sandbox Code Playgroud)
如果它被宣布为有什么区别int *p = some_addr?