我目前正在从C++ Primer学习C++,它解释了引用如何是另一个变量名的别名.它还解释了指针如何指向另一个变量.它指出指针和引用之间的区别在于指针可以重新分配而引用不能.
在下面的代码示例中,我可以用指针或引用做什么,而我不能用另一个做?
double pi = 3.14;
double &piRef = pi;
double *const piPnt = π
//both of these examples are valid and do the same thing
piRef = 3.14159;
*piPnt = 3.14159;
//however, if I attempt to reassign what the pointer points to, it is illegal.
//this is the same as with a reference, as a reference can't be reassigned either
double tau = 6.28;
piPnt = τ
Run Code Online (Sandbox Code Playgroud)
我知道每个的内部差异(例如指针是一个对象,一个引用不是).我感兴趣的是这些差异对程序员的影响如何超出略有不同的语法.因此,这不是这个问题的重复,其中接受的答案仅涉及内部差异.
我目前正在尝试用Java中的按位和移位运算符来解决问题。尽管在简化的玩具示例(基本上是正整数)中它们对我有意义,但一旦涉及负数,在其他情况下,我的理解就会瓦解。我尝试使用两个搜索引擎在Internet上进行搜索,甚至检查了Java规范。我找不到任何能正确描述Java中按位和移位运算符工作方式的资料。
Java标准库中令我特别困惑的一个功能是java.lang.Integer.toUnsignedLong(int)。这里显示了来自OpenJdk的源(带有类路径异常的LGPLv2),以及Javadoc中的摘录:
/**
* Converts the argument to a {@code long} by an unsigned
* conversion. In an unsigned conversion to a {@code long}, the
* high-order 32 bits of the {@code long} are zero and the
* low-order 32 bits are equal to the bits of the integer
* argument.
*/
public static long toUnsignedLong(int x) {
return ((long) x) & 0xffffffffL;
}
Run Code Online (Sandbox Code Playgroud)
根据上面复制的官方文档,“ long的高阶32位为零,lower-order 32位等于integer参数的位。” 但是,我从方法主体内部的代码中看不出这是怎么回事。
阅读该方法时,以下是我对正x的思路:
0xffffffff在最低4字节中具有全1,并且由于只有这些字节中将包含数据,因此此掩码无效,并且将返回正确的结果。x但是,如果在否定的语境下阅读它,我的理解就会破裂:
0xffffffff …我目前正在从 C++ Primer 5th edition 学习 C++。由于看似相互矛盾的信息,我对检查流状态的方法的行为感到困惑。在第 312 页它指出
如果有任何的
badbit,failbit或eofbit设定,然后一个条件,评估该流将失败。
在下一页,它说s.fail()是
如果
failbit或badbit在流中设置,则为真
然后
当我们使用流作为条件时执行的代码相当于调用
!fail().
这是没有意义的,因为任何表达式使用fail()应该只知道failbit和badbit(因为这些是什么弥补fail()的值),但!fail()等同于所有3的badbit,failbit以及eofbit是假的。
这些看似矛盾的陈述是如何结合在一起的?
我目前正在尝试学习C ++ 11线程API,并且发现各种资源没有提供必要的信息:如何处理CPU缓存。现代CPU的每个内核都有一个缓存(这意味着不同的线程可能使用不同的缓存)。这意味着一个线程有可能将一个值写入内存,而另一个线程可能看不到该值,即使它看到第一个线程也进行了其他更改。
当然,任何好的线程API都提供了解决此问题的方法。但是,在C ++的线程API中,尚不清楚它是如何工作的。我知道,std::mutex例如,a 以某种方式保护内存,但尚不清楚它的作用:是否清除了整个CPU缓存,是否仅清除了当前线程缓存中互斥对象内部访问的对象,或其他?
同样,显然,只读访问不需要互斥锁,但是如果线程1和仅线程1持续写入内存以修改对象,其他线程可能不会看到该对象的过时版本,从而使需要某种缓存清除吗?
原子类型是否只是绕过缓存并使用一条CPU指令从主存储器中读取值?他们是否保证访问内存中的其他位置?
在CPU缓存的上下文中,C ++ 11的线程化api中的内存访问如何工作?
有些问题,比如这一个讲内存栅栏,以及一个内存模式,但没有源似乎是在CPU缓存的情况下,这是什么这个问题问到解释这一点。
我到处寻找我的问题的答案,但找不到。基本上我想做的是获取 php 脚本后的路径。前任。“ http://www.example.com/index.php/arg1/arg2/arg3/etc/ ” 并获取数组中的 arg1、arg2、arg3 等。我如何在 php 中执行此操作,一旦执行此操作,“ http://www.example.com/arg1/arg2/arg3/etc ”仍会返回相同的结果。如果不是那么我怎样才能实现这一目标?
从下面的屏幕截图中可以看出,Netbeans C / C ++项目允许添加资源文件。当我按照“ Netbeans C / C ++'资源文件”进行搜索时,没有发现有用的信息。因此,我在这里问:它们是什么以及如何使用它们?仅仅是应用程序可以在运行时使用常规fstreams 使用的逻辑文件夹,还是允许将文件嵌入类似于Java getClass().getResourceAsStream()机制的最终可执行文件中?
注意:如果它们以任何方式独立于平台,我将在Ubuntu 16.04 LTS x64上使用g ++ 5.4.0(在这种情况下,我想知道如何在Windows和其他版本的Linux上使用它们)。
我目前正在使用标准¹C ++ 17中的OpenGl开发RAII系统,同时大量使用模板。现在,我正在研究的系统部分是通过一个通用模板来绑定和解除绑定各种OpenGl对象,然后使用声明为每种类型创建简单的别名。以下是我的头文件的相关摘录,演示了一般技术:
template<typename T, void *bind, void *unbind, typename ... Args>
class RaiiGlBinding{
public:
explicit RaiiGlBinding(const T &t, Args... args) : m_unbindArgs(std::make_tuple(t, args...)) { bind(t, args...); }
~RaiiGlBinding() { if(m_isDestructable) std::apply(unbind_typed, m_unbindArgs); }
private:
static constexpr auto bind_Vaotyped = static_cast<void (*)(T, Args...)>(bind);
static constexpr auto unbind_typed = static_cast<void (*)(T, Args...)>(unbind);
bool m_isDestructable = true;
std::tuple<T, Args...> m_unbindArgs;
};
Vao
namespace glraiidetail{
inline void bindBuffer(GLuint buffer, GLenum target) { glBindBuffer(target, buffer); }
inline void unbindBUffer(GLuint buffer, GLenum target) { glBindBuffer(target, …Run Code Online (Sandbox Code Playgroud) 我正在查看GCC的C++手册,我看到了以下引用:
版本0指的是与C++ ABI规范最接近的版本.因此,使用版本0获得的ABI将在不同版本的G ++中发生变化,因为ABI错误是固定的.(来源)
可以看出,上面的段落引用了某种看似标准的C++ ABI.但据我所知,没有这样的ABI存在.这篇文章在谈论什么?一个好的答案将给出尽可能详尽的解释.将"C++ ABI规范"放入我首选的搜索引擎并没有什么用处.
Javadocs条目getDeclaredAnnotations说明如下:
返回直接出现在该元素上的注释。此方法忽略继承的注释。如果此元素上没有直接存在注释,则返回值是长度为 0 的数组。此方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。
所以,我希望这个函数在 上返回一个长度为 1 的数组doSometing,然而,它返回一个长度为 0 的数组。为什么?getAnnotation对于相关类型也返回null.
MCVE:
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class AnnotationTest{
public static void main(String[] args){
Class<?> clazz = AnnotationTest.class;
for(Method method : clazz.getMethods()){
System.out.println(method.getName() + ":");
for(Annotation annotation : method.getDeclaredAnnotations()){
System.out.println(" - " + annotation.annotationType().getName());
}
System.out.println();
}
}
@ExampleAnnotation
public void doSomething(){}
public @interface ExampleAnnotation{}
}
Run Code Online (Sandbox Code Playgroud)
实际 MCVE 输出:
main:
doSomething:
wait:
wait:
wait:
equals:
toString:
hashCode:
- jdk.internal.HotSpotIntrinsicCandidate
getClass:
- jdk.internal.HotSpotIntrinsicCandidate …Run Code Online (Sandbox Code Playgroud) 我目前正在研究一个更复杂的程序,我遇到了一个非常奇怪的语法错误,最好用以下最小例子来证明:
#include <iostream>
int main(int argc, char *argv[]){
char c = 1 + '0';
std::cout << 1 + '0' << std::endl;
std::cout << c << std::endl;
std::cout << '0' + 1 << std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
此示例生成以下输出:
$ ./program
49
1
49
Run Code Online (Sandbox Code Playgroud)
这里似乎发生的事情是,当从单个数字整数表达式到字符的转换发生在流语句之外时,它会成功,但是当它在这样的语句中发生时,它会产生垃圾回答.
我试图找到其他人在谷歌上问类似的东西,但我找不到任何相关的东西.
我(Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609在Ubuntu 16.04 LTS x64上使用g ++ ,但问题也出现在clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)中,这排除了编译器错误.