当我遇到计算立方体体积的函数时,我正在阅读我的C++书籍(Deitel).代码如下:
double cube (const double side){
return side * side * side;
}
Run Code Online (Sandbox Code Playgroud)
使用"const"限定符的解释是这样的:"const限定应该用于强制执行最小特权原则,告诉编译器函数不修改变量端".
我的问题:这里不是使用"const"冗余/不必要的,因为变量是通过值传递的,所以函数无论如何都不能修改它?
我听说(可能来自老师)应该在程序/函数之上声明所有变量,并且在语句中声明新变量可能会导致问题.
但后来我正在阅读K&R,我发现了这句话:"变量的声明(包括初始化)可能会在左括号后面引入任何复合语句,而不仅仅是开始函数的语句".他举了一个例子:
if (n > 0){
int i;
for (i=0;i<n;i++)
...
}
Run Code Online (Sandbox Code Playgroud)
我玩了一下这个概念,它甚至可以用于数组.例如:
int main(){
int x = 0 ;
while (x<10){
if (x>5){
int y[x];
y[0] = 10;
printf("%d %d\n",y[0],y[4]);
}
x++;
}
}
Run Code Online (Sandbox Code Playgroud)
那么当我不允许声明变量时呢?例如,如果我的变量声明不在开括号之后呢?像这儿:
int main(){
int x = 10;
x++;
printf("%d\n",x);
int z = 6;
printf("%d\n",z);
}
Run Code Online (Sandbox Code Playgroud)
这可能导致麻烦,具体取决于程序/机器吗?
我需要一个匹配任何三个大写字母的正则表达式,所以AAA或ABC或DKE.但它不能匹配四个或更多,如AAAA或ABCDEF或aBBB.
我的解决方案 ^([A-Z][A-Z][A-Z])$
问题:
据我所知,当你在C中使用左移位运算符时,它保证空位将用0填充.但是,我已经读到右移是依赖于实现的,这意味着在一些机器中空位将填充0,而在其他机器中它们将填充1.
我正在程序中使用右移,事实上我的机器用1填充空位.问题是我需要用0填充0.
有没有办法迫使0在右移?
在应用右移之后,一种解决方案是创建像011111111这样的掩码,然后应用按位AND,这将改变插入到0的最左边的1.
但这很麻烦,浪费时间.如果有办法告诉我的机器用1s填充正确的班次,那将更容易.
谢谢
我相信如果你使用C,我理解在内存中如何表示正常的变量和指针.
例如,很容易理解指针Ptr将具有一个地址,并且它的值将是一个不同的地址,这是它指向的内存空间.以下代码:
int main(){
int x = 10;
int *Ptr;
Ptr = &x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将在内存中具有以下表示:
+---------------------+-------------+---------+
| Variable Name | Address | Value |
+---------------------+-------------+---------+
| x | 3342 | 10 |
+---------------------+-------------+---------+
| Ptr | 5466 | 3342 |
+---------------------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)
但是我发现很难理解数组如何在内存中表示.例如代码:
int main(){
int x[5];
x[0]=12;
x[1]=13;
x[2]=14;
printf("%p\n",(void*)x);
printf("%p\n",(void*)&x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出相同的地址两次(为简单起见10568).意思是x ==&x.然而,*x(或数组符号中的x [0])等于12,*(x + 1)(或数组符号中的x [1])等于13,依此类推.怎么能代表这个?一种方法可能是这样的:
+---------------------+-------------+----------+----------------------+
| Variable Name | Address | Value | Value IF array |
+---------------------+-------------+----------+----------------------+
| x | 10568 …
Run Code Online (Sandbox Code Playgroud) 每当你研究进程的内存分配时,你通常会看到它如下所示:
到现在为止还挺好.
但是你有sbrk()系统调用,允许程序改变其数据部分的上限,它也可以用来简单地检查sbrk(0)的限制.使用该功能,我发现了以下模式:
模式1 - 小malloc
我在Linux机器上运行以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int globalVar;
int main(){
int localVar;
int *ptr;
printf("localVar address (i.e., stack) = %p\n",&localVar);
printf("globalVar address (i.e., data section) = %p\n",&globalVar);
printf("Limit of data section = %p\n",sbrk(0));
ptr = malloc(sizeof(int)*1000);
printf("ptr address (should be on stack)= %p\n",&ptr);
printf("ptr points to: %p\n",ptr);
printf("Limit of data section after malloc= %p\n",sbrk(0));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
localVar address (i.e., stack) = 0xbfe34058
globalVar address (i.e., data section) = 0x804a024 …
Run Code Online (Sandbox Code Playgroud) 如果您在Android 上使用SQLite rawQuery()
或execSQL()
方法,何时应使用分号来结束语句?
例如,在本教程中,作者在create table语句中使用分号(通过execSQL),但不在select语句上使用分号(通过rawQuery).例如:
创建表语句:
private static final String DATABASE_CREATE = "create table "
+ TABLE_COMMENTS + "(" + COLUMN_ID
+ " integer primary key autoincrement, " + COLUMN_COMMENT
+ " text not null);";
database.execSQL(DATABASE_CREATE);
Run Code Online (Sandbox Code Playgroud)
选择声明:
Cursor cursor = getReadableDatabase().
rawQuery("select * from todo where _id = ?", new String[] { id });
Run Code Online (Sandbox Code Playgroud)
是否使用该execSQL()
方法的语句最后需要分号,但使用该rawQuery()
方法的语句不是?
我知道我需要在函数调用开始时推送链接寄存器,并在返回之前将该值弹出到Program Couter,以便执行可以从函数调用之前的位置执行.
我不明白的是为什么大多数人通过在push/pop中添加一个额外的寄存器来做到这一点.例如:
push {ip, lr}
...
pop {ip, pc}
Run Code Online (Sandbox Code Playgroud)
例如,这是ARM的官方ARM博客提供的ARM Hello世界:
.syntax unified
@ --------------------------------
.global main
main:
@ Stack the return address (lr) in addition to a dummy register (ip) to
@ keep the stack 8-byte aligned.
push {ip, lr}
@ Load the argument and perform the call. This is like 'printf("...")' in C.
ldr r0, =message
bl printf
@ Exit from 'main'. This is like 'return 0' in C.
mov r0, #0 @ Return 0. …
Run Code Online (Sandbox Code Playgroud) 据我所知,大多数编译器会通过乘法然后向右移位进行快速除法.例如,如果你检查这个SO线程,它会说当你要求Microsoft编译器除以10时,它会将被除数乘以0x1999999A(即2 ^ 32/10),然后将结果除以2 ^ 32(使用32向右移动).
到现在为止还挺好.
但是,一旦我使用GCC在ARM上测试了相同的除法,但编译器做了一些略微不同的事情.首先,它将被除数乘以0x66666667(2 ^ 34/10),然后将结果除以2 ^ 34.到目前为止,除了使用更高的乘数之外,它与Microsoft相同.然而,在那之后,它从结果中减去(被除数/ 2 ^ 31).
我的问题:为什么在ARM版本上有额外的减法?你能给我一个数字例子,如果没有减法,结果会出错吗?
如果你想检查生成的代码,它在下面(带我的评论):
ldr r2, [r7, #4] @--this loads the dividend from memory into r2
movw r3, #:lower16:1717986919 @--moves the lower 16 bits of the constant
movt r3, #:upper16:1717986919 @--moves the upper 16 bits of the constant
smull r1, r3, r3, r2 @--multiply long, put lower 32 bits in r1, higher 32 in r3
asr r1, r3, #2 @--r3>>2, then store in r1 (effectively …
Run Code Online (Sandbox Code Playgroud) 根据Google Custom Search API的说明,您可以使用REST界面的GET动词调用它,例如:
GET https://www.googleapis.com/customsearch/v1?key=INSERT-YOUR-KEY&cx=017576662512468239146:omuauf_lfve&q=lectures
Run Code Online (Sandbox Code Playgroud)
我设置了我的API密钥和自定义搜索引擎,当我的测试查询直接粘贴到我的浏览器上时,它运行正常,我将JSON文件显示给我.
然后我尝试使用以下命令从我的PHP代码调用API:
$json = file_get_contents("$url") or die("failed");
Run Code Online (Sandbox Code Playgroud)
其中$ url与浏览器上的相同,但我的PHP代码在尝试打开时死亡.
之后我尝试了curl,它起作用了.代码是这样的:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$body = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)
问题: