怎么requestWindowFeature()
办?我用它来创建一个自定义标题栏,但我真的不明白它的用途是什么.
该SDK文档中提供的说明这里就没有意义了.
我有一个关于指针差异和结果类型的问题ptrdiff_t
.
C99§6.5.6(9)说:
当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异.结果的大小是实现定义的,其类型(有符号整数类型)
ptrdiff_t
在头文件中定义.如果结果在该类型的对象中无法表示,则行为未定义.换句话说,如果表达式P和Q分别指向数组对象的第i和第j个元素,则表达式(P) - (Q)具有值i-j,条件是该值适合于对象类型ptrdiff_t
.
§7.18.3(2)要求ptrdiff_t
的范围至少为[-65535,+ 65535]
我感兴趣的是如果结果太大则未定义的行为.我无法在标准版本中找到任何与签名版本size_t
或类似内容相同的范围.所以,现在我的问题是:符合标准的实现是否可以生成ptrdiff_t
带符号的16位类型但size_t
64位?[编辑:正如Guntram Blohm指出的那样,16位签名最多为32767,所以我的例子显然不符合]据我所知,我不能在严格符合代码甚至超过65535个元素的数组上做任何指针减法如果实现支持比这大得多的对象.此外,该程序甚至可能崩溃.
理由(V5.10)§6.5.6说:
重要的是要对这个类型[
ptrdiff_t
]进行签名,以便在处理同一数组中的指针时获得适当的代数排序.但是,指针差异的大小可以与可以声明的最大对象的大小一样大; 由于这是一个无符号类型,两个指针之间的差异可能会导致某些实现溢出.
这可以解释为什么不需要指定每个指针差异(对同一个数组的元素),但它不能解释为什么PTRDIFF_MAX
至少没有限制SIZE_MAX/2
(使用整数除法).
为了说明,假设T
是任何对象类型和编译时未知n
的对象size_t
.我想为n
对象分配空间T
,我想用指定范围内的地址进行指针减法.
size_t half = sizeof(T)>1 ? 1 : 2; // (*)
if( SIZE_MAX/half/sizeof(T)<n ) /* do some error handling */;
size_t size = n * sizeof(T);
T *foo = malloc(size);
if(!foo) /* ... */; …
Run Code Online (Sandbox Code Playgroud) C99§6.5 表达式
(1)表达式是操作符和操作数的序列,其指定值的计算,或指定对象或函数,或者生成副作用,或执行其组合.
(2)在前一个和下一个序列点之间,一个对象的存储值最多只能通过表达式的评估来修改一次.72)此外,先前值应只读以确定要存储的值.73)
用脚注
72)浮点状态标志不是对象,可以在表达式中多次设置.
73)此段落呈现未定义的语句表达式,如
Run Code Online (Sandbox Code Playgroud)i = ++i + 1; a[i++] = i;
允许的同时
Run Code Online (Sandbox Code Playgroud)i = i + 1; a[i] = i;
C11§6.5改为((1)的文本有附录):
(1)[...]运算符的操作数的值计算在运算符的结果的值计算之前被排序.
(2)如果对标量对象的副作用相对于对同一标量对象的不同副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义.如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的.84)
C11中的脚注84与C99中的73相同.
我有点困惑......我把C11(2)读作"[...](对同一标量对象的不同副作用)或(使用相同标量对象的值进行值计算)[...]"似乎甚至不允许foo = ++i
(有副作用,我们根据更改的对象使用值).不过,我不是母语人士,所以如果能告诉我这句话应该如何"解析"会更好.我理解C99,但我不太明白C11的措辞.
无论如何,实际问题:这是从C99到C11的变化,还是这些措辞相当?如果是这样,为什么它会被改变?如果没有,有人可以给出一个表达式的例子,这个表达式在C99中是UB而在C11中不是,反之亦然?
请考虑以下代码:
void doesnt_modify(const int *);
int foo(int *n) {
*n = 42;
doesnt_modify(n);
return *n;
}
Run Code Online (Sandbox Code Playgroud)
其中定义对doesnt_modify
编译器不可见.因此,它必须假定,doesnt_modify
将对象n
指向更改并且必须*n
在return
(最后一行不能被替换return 42;
)之前读取.
假设,doesnt_modify
不修改*n
.我考虑了以下内容以允许优化:
int foo_r(int *n) {
*n = 42;
{ /* New scope is important, I think. */
const int *restrict n_restr = n;
doesnt_modify(n_restr);
return *n_restr;
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是调用者doesnt_modify
必须告诉编译器*n
没有被修改,而不是函数本身可以通过其原型告诉编译器.简单地restrict
将参数限定doesnt_modify
在声明中是不够的,参见 "是顶级volatile
还是restrict
重要的?".
当与编译gcc -std=c99 …
假设我想将一个数字分成许多.
a /= x;
b /= x;
c /= x;
...
Run Code Online (Sandbox Code Playgroud)
由于乘法更快,诱惑就是这样做
tmp = 1.0f / x;
a *= tmp;
b *= tmp;
c *= tmp;
...
Run Code Online (Sandbox Code Playgroud)
1)这保证会产生相同的答案吗?我怀疑不是,但一些确认会很好.
2)如果 x
非常大或非常小,我预计这会导致精度的显着降低.有没有一个公式可以告诉我我会牺牲多少精确度?
3)也许没有方便的公式,但我们至少可以说出数值不稳定性成为问题时的经验法则吗?它与操作数的大小有关,也可能与操作数的大小有什么关系?
tl; dr可以asprintf
天真地用于连接而无需调用临时指针?
asprintf
GNU引入并在其他几个clib实现中采用的函数是使用类似方案在c中进行任意连接的诱人解决方案
int i=0;
char *str = strdup(argv[i]);
while (argv[++i]) {
asprintf(&str,"%s %s",argv[i],str); // <=== This line
}
asprintf(&str,"%s\n",str);
Run Code Online (Sandbox Code Playgroud)
当包裹在主要和必要的包含,这对我来说运行良好.
是否在整个地方泄漏记忆?Valgrind说它在我的盒子上.这是一个错误吗?
我面前的那个人页说
asprintf()和vasprintf()函数将*ret设置为指向缓冲区的指针,该缓冲区足以容纳格式化的字符串.应该将此指针传递给free(3)以在不再需要时释放已分配的存储.如果无法分配足够的空间,asprintf()和vasprintf()将返回-1并将ret设置为NULL指针.
在这句话中由于缺少"设置*ret
为指向一个新的缓冲[...]",我很想假设函数使用realloc
的getline
一样.
使用签名int asprintf(char **ret, const char *format, ...);
具体.
asprintf
跑得太快realloc
了.
想象一下,我们实现了这个函数,我们可以realloc(*ret)
在它取消引用其中一个混淆原始缓冲区的变量之前运行.该缓冲区已被释放,这在技术上是未定义的行为.这将代表一个错误.
asprintf
在读取之前写入缓冲区.在上面的代码就可以成像功能拷贝的内容argv[1]
到*ret
之前的每va_arg
对str
参数.我引用的联机帮助页似乎并不排除这种情况.
asprintf
不free *ret
直接或通过使用realloc
.这将避免问题编号(1),但如果如上所述使用会泄漏内存.再一次,该手册页似乎不排除它.
通过将单个调用替换为asprintf
with,可以避免上述所有操作
{
char …
Run Code Online (Sandbox Code Playgroud) 使用宏而不是静态内联方法有什么显着的好处吗?特别是,如何使用静态内联方法在调用链中进一步实现可变参数的传递,而这可以通过宏一步完成?
#define myprintf(fmt, args...) printf (fmt, args)
Run Code Online (Sandbox Code Playgroud)
这只是一个简单的示例,但我仍然很好奇是否有一种等效的方法可以使用静态内联而不使用 va_args 步骤来执行此操作。
编译器是否总是内联静态内联方法?它们的尺寸又如何呢?调用任意子方法怎么样?如果我使用多个宏,所有宏都会编译成单个表达式,因此编译器可能更容易优化。编译器是否总是足够聪明,可以将多个级别的静态内联调用转换为单个表达式?
如果在声明中删除了单引号,则显示 11
class Sample
{
public static void main(String ar[])
{
char v1='5';
char v2='6';
System.out.println(v1 + v2);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:107
我正在使用gcc 4.8.1,我无法理解以下程序的输出.
#include<stdio.h>
int main()
{
char* a, b, c;
int* d, e, f;
float* g, h, i;
printf("Size of a %zu and b %zu and c %zu \n", sizeof(a), sizeof(b), sizeof(c));
printf("Size of d %zu and e %zu and f %zu and int is %zu \n", sizeof(d), sizeof(e), sizeof(f), sizeof(int*));
printf("Size of g %zu and h %zu and i %zu and float is %zu \n", sizeof(g), sizeof(h), sizeof(i), sizeof(float));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Size of a 4 and b …
Run Code Online (Sandbox Code Playgroud) 我正在重构一个c ++代码,有一些我无法理解的东西.代码在头文件中声明一组数组,然后在需要时在源文件中包含该头文件.除了一个"const char*[]"数组之外,所有数组都是"const unsigned char []".后者被#ifdef SOMETHING所包围.如果没有定义SOMETHING,则代码构建成功,否则我只会为此"char*[]"获得多个定义的链接器错误.
作为修复,我可以通过将"static"添加到"const char*XX [3] = {"X","Y","Z"}"来消除这些链接器错误.这将使定义保持特定于翻译单元.
但是,我无法理解为什么"多个定义"错误只发生在"const char*[]"数组而不是其他"const unsigned char []",尽管它们之前没有"static"关键字?有人可以向我解释一下吗?