V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  RDF  ›  全部回复第 1 页 / 共 2 页
回复总数  28
1  2  
2023-01-14 15:21:54 +08:00
回复了 BiteDXH 创建的主题 Windows Win10 21h1 远程 RDP 10bit 花屏问题
AMD 显卡 有这个问题, 驱动开了 10bit , RDP 异常花屏, 改成 8bit 后正常, 显示器是 8 抖 10
2020-12-14 23:25:02 +08:00
回复了 zhoudaiyu 创建的主题 问与答 Bilibili 上有哪些技术类的 UP 主/视频值得关注/收藏?
MIT 6.824 分布式系统 可以观看 https://www.simviso.com 的译制课程。

simviso 有很强的 CS 专业功底和研发经验,想尽一些绵薄之力,通过组合各个顶级国外高校的课程,构建一整个计算机从本科到研究生的学习体系。也在尽最大的努力,做好每一点翻译,每一点知识分享。


~在哔哩哔哩 https://www.bilibili.com/video/BV1x7411M7Sf 已经有前 20 集译制课程免费分享~
[MIT 6.824 Distributed Systems Spring 2020 分布式系统 中文翻译版合集]

~~ https://www.simviso.com 官网体验更佳~~
2020-12-07 00:01:21 +08:00
回复了 neochen13 创建的主题 程序员 非计算机科班出身想要提高自己,请问有适合的路线吗?
2020-12-06 23:59:43 +08:00
回复了 neochen13 创建的主题 程序员 非计算机科班出身想要提高自己,请问有适合的路线吗?
MIT 6.824 分布式系统 可以观看 https://www.simviso.com 的译制课程。

simviso 有很强的 CS 专业功底和研发经验,想尽一些绵薄之力,通过组合各个顶级国外高校的课程,构建一整个计算机从本科到研究生的学习体系。也在尽最大的努力,做好每一点翻译,每一点知识分享。


~在哔哩哔哩 https://www.bilibili.com/video/BV1x7411M7Sf 已经有前 20 集译制课程免费分享~
[MIT 6.824 Distributed Systems Spring 2020 分布式系统 中文翻译版合集]

~~ https://www.simviso.com 官网体验更佳~~
2017-12-28 10:09:25 +08:00
回复了 RDF 创建的主题 程序员 写了个 char 辨析的玩具 :)
const int ArSize = 2;

//为了对 char 数组仅含'a' 和'\0'进行查看,故仅允许单个字符。
这样细节就拦清了 :)
补充:

为了测试阈限,
const int ArSize = 2;
输入为 a




字符串存的字符分别为‘ a ’和‘\0 ’

可以检查得更为仔细:


ASCIIized: a
ASCIIized:
打印 ASCII-10 进制-数组第 i 位字符所在地
a: 97

打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转
a: 00000061
a: 00000062

打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符

a: a
a:

打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出

a: 0113F998
a: 0113F999


打印整个数组的内存地址的开始位置-将 char 类型的地址-转 int 以使其由 cout 正常输出--对 char 类型的内存地址

: 0113F998
: 0113F99A

打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
解除引用,得整个的 char 内存地址的指针--cout 对 char 指针由开始位置进行输出,直到\0

: a
到达了 char 数组的外部,所以值为未定义
: 烫烫烫坉 X N;

打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
解除引用,得整个的 char 内存地址的指针-转 int 以使其由 cout 正常输出-直到\0

: 0113F998
对整个数组内存地址+1-偏移量为整个数组的长度+1
解除引用,得整个偏移后的 char 内存地址的 char 指针--将 char 指针转 int 指针由 cout 正常输出
: 0113F99A
@gnaggnoyil
重新修订并补全说明:
#include "stdafx.h"
#include <iostream>
const int ArSize = 20;
int main()
{
using std::cin;
using std::endl;
using std::cout;
char name[ArSize];

cout << "ASCIIized: ";
cin.getline(name, ArSize);
cout << "ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << "打印 ASCII-10 进制-数组第 i 位字符所在地" << endl;
//打印 ASCII-10 进制-数组第 i 位字符所在地
cout << name[i] << ": " << int(name[i]) << endl << endl;

cout << "打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转" << endl;
//打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转
cout << name[i] << ": " << (int *)(char *)(name[i]) << endl;
cout << name[i] << ": " << (int*)(char *)(name[i] + 1) << endl << endl;

cout << "打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符" << endl;
//打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符
cout << endl << name[i] << ": " << (&name[i]) << endl;
cout << name[i] << ": " << (&name[i] + 1) << endl << endl;

cout << "打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出" << endl;
//打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出
cout << endl << name[i] << ": " << (int*)(&name[i]) << endl;
cout << name[i] << ": " << (int*)(&name[i] + 1) << endl << endl;

i++;
}
cout << "" << endl;

cout << "打印整个数组的内存地址的开始位置-将 char 类型的地址-转 int 以使其由 cout 正常输出--对 char 类型的内存地址" << endl;
//打印整个数组的内存地址的开始位置-将 char 类型的地址-转 int 以使其由 cout 正常输出--对 char 类型的内存地址
cout <<endl<< name[i] << ": " << (int*)(&name) << endl;
cout << name[i] << ": " << (int*)(&name + 1) << endl << endl;

cout << "打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址" << endl;
cout << "解除引用,得整个的 char 内存地址的指针--cout 对 char 指针由开始位置进行输出,直到\\0" << endl;
//打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
//解除引用,得整个的 char 内存地址的指针--cout 对 char 指针由开始位置进行输出,直到\0
cout << endl << name[i] << ": " << (char *)(&name) << endl;
cout << "到达了 char 数组的外部,所以值为未定义" << endl;
//到达了 char 数组的外部,所以值为未定义
cout << name[i] << ": " << (char *)(&name + 1) << endl << endl;

cout << "打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址" << endl;
cout << "解除引用,得整个的 char 内存地址的指针-转 int 以使其由 cout 正常输出-直到\\0" << endl;
//打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
//解除引用,得整个的 char 内存地址的指针-转 int 以使其由 cout 正常输出-直到\0
cout << endl << name[i] << ": " << (int*)(char *)(&name) << endl;
cout << "对整个数组内存地址+1-偏移量为整个数组的长度+1" << endl;
cout << "解除引用,得整个偏移后的 char 内存地址的 char 指针--将 char 指针转 int 指针由 cout 正常输出" << endl;
//对整个数组内存地址+1-偏移量为整个数组的长度+1
//解除引用,得整个偏移后的 char 内存地址的 char 指针--将 char 指针转 int 指针由 cout 正常输出
cout << name[i] << ": " << (int*)(char *)(&name + 1) << endl << endl;

cin.get();
}


对应输出:

ASCIIized: abc
ASCIIized:
打印 ASCII-10 进制-数组第 i 位字符所在地
a: 97

打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转
a: 00000061
a: 00000062

打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符

a: abc
a: bc

打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出

a: 004FFCA4
a: 004FFCA5

打印 ASCII-10 进制-数组第 i 位字符所在地
b: 98

打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转
b: 00000062
b: 00000063

打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符

b: bc
b: c

打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出

b: 004FFCA5
b: 004FFCA6

打印 ASCII-10 进制-数组第 i 位字符所在地
c: 99

打印 ASCII-16 进制-数组第 i 位-char 指针-int 指针转
c: 00000063
c: 00000064

打印数组第 i 位字符所在地-内存地址-cout 对 char 内存地址-直接输出其字符

c: c
c:

打印数组第 i 位字符所在地-内存地址-将 char 内存地址以 int 形式输出

c: 004FFCA6
c: 004FFCA7


打印整个数组的内存地址的开始位置-将 char 类型的地址-转 int 以使其由 cout 正常输出--对 char 类型的内存地址

: 004FFCA4
: 004FFCB8

打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
解除引用,得整个的 char 内存地址的指针--cout 对 char 指针由开始位置进行输出,直到\0

: abc
到达了 char 数组的外部,所以值为未定义
: 烫烫 4栽麿

打印整个数组的内存地址的开始位置-将 char 类型的地址-对 char 类型的内存地址
解除引用,得整个的 char 内存地址的指针-转 int 以使其由 cout 正常输出-直到\0

: 004FFCA4
对整个数组内存地址+1-偏移量为整个数组的长度+1
解除引用,得整个偏移后的 char 内存地址的 char 指针--将 char 指针转 int 指针由 cout 正常输出
: 004FFCB8



应该说明完善了。
第二次修订:

// 5.13 print name with while.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
const int ArSize = 20;
int main()
{
using std::cin;
using std::endl;
using std::cout;
char name[ArSize];

cout << "ASCIIized: ";
cin.getline(name, ArSize);
cout << "ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl;
cout << name[i] << ": " << (int *)(char *)(name[i]) << endl;
cout << name[i] << ": " << (int*)(char *)(name[i] + 1) << endl;
i++;
}
cout <<endl<< name[i] << ": " << (int*)(name) << endl;
cout << name[i] << ": " << (int*)(name + 1) << endl;


cin.get();
}


有:

ASCIIized: abc
ASCIIized:
a: 97
a: 00000061
a: 00000062
b: 98
b: 00000062
b: 00000063
c: 99
c: 00000063
c: 00000064

: 005AFA54
: 005AFA55
上文的表述形式少做修改,并显式表达:


#include "stdafx.h"
#include <iostream>
const int ArSize = 20;
int main()
{
using std::cin;
using std::endl;
using std::cout;
char name[ArSize];

cout << "ASCIIized: ";
cin >> name;
cin.get();
cout << "ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl;
cout << name[i] << ": " << (int *)(char *)(name[i]) << endl;
cout << name[i] << ": " << (int*)(char *)(name[i] + 1) << endl;
i++;
}
cout <<endl<< name[i] << ": " << (int*)(name) << endl;
cout << name[i] << ": " << (int*)(name + 1) << endl;


cin.get();
}

有:

ASCIIized: abc
ASCIIized:
a: 97
a: 00000061
a: 00000062
b: 98
b: 00000062
b: 00000063
c: 99
c: 00000063
c: 00000064

: 0135FD7C
: 0135FD7D
@gnaggnoyil

即,对:
#include "stdafx.h"
#include <iostream>
const int ArSize = 20;
int main()
{
using std::cin;
using std::endl;
using std::cout;
char name[ArSize];

cout << "ASCIIized: ";
cin >> name;
cin.get();
cout << "ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl;

cout << name[i] << ": " << (int *)*name << endl;
cout << name[i] << ": " << (int*)(*name + 1) << endl;

cout << name[i] << ": " << (int *)name<< endl;
cout << name[i] << ": " << (int*)(name+1) << endl;

i++;
}
cin.get();
}


有:

ASCIIized: abc
ASCIIized:
a: 97
a: 00000061
a: 00000062
a: 0053FB6C
a: 0053FB6D
b: 98
b: 00000061
b: 00000062
b: 0053FB6C
b: 0053FB6D
c: 99
c: 00000061
c: 00000062
c: 0053FB6C
c: 0053FB6D
@gnaggnoyil
即,对:
#include "stdafx.h"
#include <iostream>
const int ArSize = 20;
int main()
{
using namespace std;
char name[ArSize];

cout << "ASCIIized: ";
cin >> name;
cin.get();
cout << "ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl;

cout << name[i] << ": " << (int *)*name << endl;
cout << name[i] << ": " << (int*)(*name + 1) << endl;

cout << name[i] << ": " << (int *)name<< endl;
cout << name[i] << ": " << (int*)(name+1) << endl;

i++;
}
cin.get();
}


有:

ASCIIized: abc
ASCIIized:
a: 97
a: 00000061
a: 00000062
a: 0053FB6C
a: 0053FB6D
b: 98
b: 00000061
b: 00000062
b: 0053FB6C
b: 0053FB6D
c: 99
c: 00000061
c: 00000062
c: 0053FB6C
c: 0053FB6D
@gnaggnoyil
即有:
cout << "a"<< endl; 打印 a
cout << *"a"<< endl; 打印 a [此时为 char 指针]
cout << (int *) "a" << endl; 打印"a"字符串( a 和'\0' )中第一个字符的地址。

-----------------------------------------
cout << (int *)*"a" << endl;对 a 的地址解除引用得到 a 的值,由于上文, [此时为 char 指针] ,对其再次给一个强制转换的指针,以直接打印 a 在 ASCII 系统上的 ASCII 编码,61
@gnaggnoyil
数组名被解释为其第一个元素的地址。
对数组名应用地址运算符时,得到的是整个数组的地址
对于,cout<<"statement"<<endl; cout 对象对所认为的字符串地址,直接打印该地址处的字符,强制*解除引用 则得到地址的值,但是由于
{
在 cout 和多数 C++表达式中,char 数组名,char 指针,以及用引号括起的字符串常量都被解释为 字符串第一个字符的地址。
}

因此
{
如果给 cout 提供一个指针,它将打印地址,如果指针类型为 char *,则显示指向的字符串
而 int* 便是将字符串指针*强制转换为另一种类型来进行显示。
}
C++11
对 cout <<"Home of the jolly bytes"<<endl;
读取字符串"Home of the jolly bytes"所在内存,开始位置的内存地址(即字符 H 存储的内存的地址),cout 读取到字符串地址时,直接打印由该地址处开始的字符,直到\0;
打印 Home of the jolly bytes

对于
cout << (int *)"Home of the jolly bytes"<<endl;
则是对字符串"Home of the jolly bytes"中,开始字符 H 的内存地址进行解除引用,以打印出其所在内存的内存地址,而非‘由字符串内存地址开始打印字符’。 但疑惑的是, 这个地址,在数值上, [字符串的开始的内存地址的值] 和 [字符串首字符的内存地址的值] 在数值上相同。如果是直接声明的字符串 short ccc [8] ,可以
cout<<ccc <<endl; 即&ccc[0],其指向一个 short 内存块地址( 2bit ),形如* short
cout<<ccc+1 <<endl;

cout<<&ccc <<endl;直接指向了含有 16bit 的 short 数组,+1 使其向后指了 16bit
cout<<&ccc+1 <<endl;
借由+1 进行

但疑惑的是,对字符串取( int*) 查看到的内存地址, 实际表述为 [字符串的开始的内存地址的值] 还是 [字符串首字符的内存地址的值] 。不超 int 范围的前提下, 取法没问题, 但是这个对象没有找到清晰的解释。
@gnaggnoyil
The expression "Home of the jolly bytes" is a string constant;
hence it evaluates as the address of the beginning of the string.The cout object
interprets the address of a char as an invitation to print a string, but the type cast
(int *) converts the address to type pointer-to-int, which is then printed as an
address. In short, the statement prints the address of the string, assuming the int
type is wide enough to hold an address.

对于,(int *) ,不存在未定义的问题。 只是讨论其定义的实际区间问题。
@gnaggnoyil 就是 c++11 修订的明确定义
@gnaggnoyil 不可能是未定义,因为这在 c11 的概念中是有明确定义的:双引号内的为字符串。cout 打印时读取字符串第一个字符的内存地址。并将其认成字符串进行输出。这是一般情况下直接用双引号进行输出时的明确定义。( int*)是对地址的转义进行强制的格式转换。使其可以输出首字符所在内存的内存地址。而不是直接将字符串的首字符内存地址认成字符串输出而进行字符串输出。
这是有明确定义的行为。
@gnaggnoyil 参考 C++11 核心定义
@gnaggnoyil c++ 指针可以直接以数组形式使用。
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2282 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 16ms · UTC 01:46 · PVG 09:46 · LAX 17:46 · JFK 20:46
Developed with CodeLauncher
♥ Do have faith in what you're doing.