这是一个问题:
在"计算机系统:程序员的视角"一书中2.2.5
它表示如果无符号值与有符号值进行比较,则将以非换行格式比较所有值.像这样
if(-1 < 0u)
{
// will not print this line because -1 will be translated to 255.
printf("all changed to unsigned format");
}
Run Code Online (Sandbox Code Playgroud)
我在VC6 SP6中尝试了这个代码,字符串没有输出.一切看起来都很好,因为我们都知道-1被翻译为255.
但是当我读到"Expert C Programming Deep C Secrets"一书1.10时
它说如果我的编译器使用ANSI C标准,则此代码将打印"-1 <(unsigned char)1:ANSI":
if(-1 < (unsigned char)1)
{
printf("-1 < (unsigned char)1: ANSI");
}
else
{
printf("-1 NOT Less than (unsigned char)1: K&R");
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:-1 <(unsigned char)1:ANSI.
我正在使用VC6 SP6编译器.
为什么会这样?
根据"计算机系统:程序员的视角"一书
-1 <(unsigned char)1将-1转换为无符号值.所以它会变成这样的:
255 <1
这不应该打印出行-1 <(unsigned char)1:ANSI.
任何人都可以告诉我为什么会这样吗?
我在 C# 中有一个应用程序,它使用 RijndaelManaged加密我的部分文件(因为它们是大文件)。所以我将我的文件转换为字节数组并只加密其中的一部分。
然后我想使用Java解密文件。所以我只需要解密用 C# 加密的文件的一部分(意味着那些字节)。
问题来了。因为在 C# 中我们有无符号字节,而在 Java 中我们有有符号字节。所以我的加密和解密没有按照我想要的方式工作。
在 C# 中,我将加密字节和普通字节连接在一起,并使用File.WriteAllBytes. 所以我不能在这里使用sbyte或者我不知道该怎么做:
byte[] myEncryptedFile = new byte[myFile.Length];
for (long i = 0; i < encryptedBlockBytes.Length; i++)
{
myEncryptedFile[i] = encryptedBlockBytes[i];
}
for (long i = encryptedBlockBytes.Length; i < myFile.Length; i++)
{
myEncryptedFile[i] = myFileBytes[i];
}
File.WriteAllBytes(@"C:\enc_file.big", myEncryptedFile);
Run Code Online (Sandbox Code Playgroud)
(并且在 Java 中有一个完全相同的解密代码)
所以我的问题是:
我有一个Android项目(使用Android Studio和Gradle)和一个构建此项目的Jenkins CI服务器.
我要做的是生成一个完全未签名的证书.
事实上,当服务器构建的应用程序,它会产生一个-unsigned.apk但似乎这个APK 是由签署developper证书.
事实上,我通过下载apk并运行以下命令检查了这一点(阅读后如何验证Android apk是否与发布证书签名?)
jarsigner -verify -verbose -certs app-unsigned.apk | grep Android
Run Code Online (Sandbox Code Playgroud)
所以输出就像
X.509, CN=Android Debug, O=Android, C=US
Run Code Online (Sandbox Code Playgroud)
(有很多行)
为了它的价值,我构建了运行gradle任务的应用程序:
clean assemble lint
Run Code Online (Sandbox Code Playgroud)
之后,我通过运行来压缩所有的apks
zipalign -f -v 4 *.apk
Run Code Online (Sandbox Code Playgroud)
我的build.gradle不包含任何签名选项
android {
compileSdkVersion 19
buildToolsVersion '19.0.1'
defaultConfig {
minSdkVersion 10
targetSdkVersion 19
}
buildTypes {
debug {
// proguard
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
// ZipAlign
zipAlign false
}
release {
// …Run Code Online (Sandbox Code Playgroud) 我使用unsigned char作为迭代器时遇到问题.使用以下代码会导致卡在FOR循环中.输出看起来像这样.
unsigned char i;
char * arr;
int * freq;
arr = (char *)(malloc(256*sizeof(char)));
freq = (int *)(malloc(256*sizeof(int)));
for (i=0; i<=255;i++){
arr[i]=i;
freq[i]=0;
printf("%c",i);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么会这样?是否因为使用unsigned char作为迭代器?
我阅读了 Kip IRVINE 的著作《x86 处理器汇编语言》,他写道:
将较小的值复制到较大的值
尽管 MOV 不能直接将数据从较小的操作数复制到较大的操作数,但程序员可以创建变通方法。假设计数(无符号,16 位)必须移动到 ECX(32 位)。我们可以将 ECX 设置为零并将计数移动到 CX:
Run Code Online (Sandbox Code Playgroud).data count WORD 1 .code mov ecx,0 mov cx,count如果我们用一个等于 -16 的有符号整数尝试相同的方法会发生什么?
Run Code Online (Sandbox Code Playgroud).data signedVal SWORD -16 ; FFF0h (-16) .code mov ecx,0 mov cx,signedVal ; ECX = 0000FFF0h (+65,520)ECX 中的值 (+65,520) 与 -16 完全不同。另一方面,如果我们先用 FFFFFFFFh 填充 ECX,然后将 signedVal 复制到 CX,则最终值将是正确的:
Run Code Online (Sandbox Code Playgroud)mov ecx,0FFFFFFFFh mov cx,signedVal ; ECX = FFFFFFF0h (-16)
我的问题是最后一部分。我认为我们应该在上面的代码中写第一行mov ecx,FFFFFFFFFh,而不是 0FFFFFFFFh。换句话说,什么是前导零?
如何无符号的字符,例如,从取值-128到+127?根据我的理解,最重要的位用于表示数字的符号,而字符的剩余位用于表示数字的大小.现在,7位的最大可能幅度是127,所以范围不应该从?-127到+127?怎样才能-128有一个结果?
其次,以下行为背后的位级逻辑是什么
#include <stdio.h>
int main()
{
signed char x = 127;
x += 1;
printf("%i", x);
}
Run Code Online (Sandbox Code Playgroud)
输出:
-128
Run Code Online (Sandbox Code Playgroud)
人们可以看到,x成为-128,但为什么呢?这种行为背后的算法是什么?
我错过了什么吗?我运行了以下内容:
$ uname -a
Linux archlinux 4.16.6-1-ARCH #1 SMP PREEMPT Mon Apr 30 12:30:03 UTC 2018 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
然后在C程序中:
long l;
printf("sizeof long: %d\n", sizeof l);
Run Code Online (Sandbox Code Playgroud)
哪个输出:
sizeof long: 8
Run Code Online (Sandbox Code Playgroud)
这是不是意味着每个long包含64位?但是当我执行以下代码行时:
printf("2^64: %ld\n", 1UL<<64);
Run Code Online (Sandbox Code Playgroud)
我从gcc收到以下警告:
sizeof.c:14:29:警告:左移计数> =类型宽度[-Wshift-count-overflow]
如果我将左移位减少到63,则警告消失,但输出:
2 ^ 64:-9223372036854775808
这让我相信我的无符号长度为64个可用位的假设是不正确的,但为什么呢?
我想反转一个数字,但它是一个unsigned long. 但是,我不熟悉 的品质unsigned long。
这是代码:
#include <stdio.h>
int main(void)
{
unsigned long num, reversed = 0;
scanf_s("%lu", &num);
while(num > 0)
{
reversed *= 10;
reversed = reversed + num % 10;
num /= 10;
}
printf("%lu", reversed);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如,如果输入是888888888889,则输出是不同的。
我认为这是因为它确实接近,如果这是正确的词的话。
我也不确定%lu。
我怎样才能反转 a 的数字unsigned long?
我找到了一个 C++ 代码,我们将初始化为最大值的 unsigned int 32 转换为有符号 int 并期望它是-1. 它在经过测试的编译器上运行良好,但它真的可移植吗?
int GetBusinessDataID()
{
u32_t id = ~0;
// Some code that may return a valid ID.
return id; // Here we expect to return -1.
}
Run Code Online (Sandbox Code Playgroud)