将指针视为数组合法吗? void uc(字符*s) { int i; 对于(i=0;i
将指针视为数组合法吗? void uc(字符*s) { int i; 对于(i=0;i,c,arrays,pointers,C,Arrays,Pointers,s是一个指针,因此如果分配了它,我们可以将其用作数组 以下两个选项类似: void uc(char* s) { int i; for( i=0; i < strlen(s); i++ ) if (97 <= s[i] && s[i] <= 122) s[i] = s[i] - 32; return; } 及 因为内存地址是十六进制格式的整数(对吗?) 不,用户使用十六进制格式来显示内存地址。如
s
是一个指针,因此如果分配了它,我们可以将其用作数组
以下两个选项类似:
void uc(char* s)
{
int i;
for( i=0; i < strlen(s); i++ )
if (97 <= s[i] && s[i] <= 122)
s[i] = s[i] - 32;
return;
}
及
因为内存地址是十六进制格式的整数(对吗?)
不,用户使用十六进制格式来显示内存地址。如果使用二进制数来描述内存地址,它太长了。char*s
复制数组-不,它不复制
此函数的参数是指向char
的指针。就是这样。指针的取消引用语法可以有两种形式:*(p+n)
,和p[n]
。这两种形式是等效的。在这两种情况下,p
中的地址都是按值获取的,并使用元素类型的跨距进行调整,然后根据使用上下文取消对结果地址的引用以进行读取或存储
你的函数可以用一种更加明显的方式编写,作为奖励,每次迭代都要避免strlen
调用(这可能会很昂贵)
将在符合ascii标准的平台上打印LOWER
。我恳请您在调试器中运行上述代码,并注意以下事项:
main()中
的基址s[]
- 初始进入时,
的参数列表中uc
的值s
- 循环迭代时,
中的uc
会发生什么变化s
- 在各种上下文中使用时,
的值出现在*s
uc
老实说,这是我能做的最好的解释了。祝你好运。首先要做的事,而且要完全直言不讳: 你的思维模式是错误的!在你陷入太深的思维模式之前,现在纠正你的错误观念是势在必行的
char*s
复制数组
这是一种误解。s
是指向char
的指针。它可以是单个char
或整个数组。获取地址时,底层对象的确切类型将丢失
不过,没有复制任何东西!它只是一个指向“where”(挥舞手臂)的指针,所有相关人员(您、编译器、其他程序员)都达成了一个默契和不成文的协议,即友好而不做愚蠢的事情。比如传入一个指针,该指针稍后将在函数中以无效方式使用
这是正常的,因为数组名是它的第一个元素内存地址
数组没有名称!符号有名称。数组的符号将衰减为指向构成数组的基本类型的指针。这就是为什么您可以编写char-somearray[123];char*p=somearray
,而无需获取其地址
为什么我们在for循环中将指针s视为数组
因为我们可以。更具体地说是因为这个叫做“指针算术”的东西。expressions+1
将产生一个指针,指向一个元素,超过指针指向的元素的地址。它适用于任何数字(在ptrdiff\u t
的值范围内)
当你用C写a_指针[i]
时,它会逐字翻译成*(a_指针+i)
。因此,通过写a_指针[i]
你告诉编译器:*“假设a_指针
指向数组对象,并且a_指针+i
仍在该数组对象的边界内:根据该假设,取消对该位置的引用并在该位置生成值。”
但是仅当生成的指针位于对象的边界内时,才定义指针算法的结果
对不是从数组中获取的指针执行指针算术吗?未定义
生成超出数组边界的指针?未定义
我的问题是,我认为它们是“int变量”,
它们不是!从技术上讲,指针可能是由unicorn dust和magic实现的。当它们与数字混合时,有一些非常具体的规则。在C编程语言中,这些规则是(简化的):
- 指针可以转换为大小为
的整数,反之亦然sizeof(uintpttr\u t)
- 数值0转换为空指针,空指针转换为数值0
- 空指针无效,因此不能取消引用
- 指针可以相互相减,得到一个与
兼容的整数,并且得到的整数的值是这两个指针之间的元素距离,假设两个指针引用同一个对象。用“类型”编写ptrdiff\u t
⟪ptrdiff\t⟫ = ⟪指针A⟫ - ⟪指针B⟫代码>,仅此的算术有效重排有效
- 不能添加指针
- 你不能增加指针
- 没有规定指针的数字表示可以用于指针算术。也就是说,对于
的任何值,都不能假定k
(指针A-指针B)=k*((uintptr\t)指针A-(uintptptr\t)指针B))
s[i] = s[i] - 32;
*(s+i) = *(s+i) -32
void uc(char* s)
{
for (; *s; ++s)
{
if (97 <= *s && *s <= 122)
*s -= 32;
}
}
#include <stdio.h> // for puts
void uc(char* s)
{
for (; *s; ++s)
{
if (97 <= *s && *s <= 122)
*s -= 32;
}
}
int main()
{
char s[] = "lower";
uc(s);
puts(s);
return 0;
}
char foo[] = "hello";
+–––+
0x1000: |'h'|
+–––+
0x1001: |'e'|
+–––+
0x1002: |'l'|
+–––+
0x1003: |'l'|
+–––+
0x1004: |'o'|
+–––+
0x1005: | 0 |
+–––+
uc( foo );
void uc( char *s ) { ... }
a[i] == *(a + i)
int vector[N]; // for some value of N
void foo( T x ) // for any type T
{
x = new_value;
}
void bar( void )
{
T var;
foo( var );
}
void foo( T *ptr )
{
*ptr = new_value; // write a new value to the thing ptr *points to*
}
void bar( void )
{
T var;
foo( &var ); writes a new value to var
}
*ptr == var // T == T
ptr == &var // T * == T *
int x;
int *ptr = &x; // ptr is *not* being dereferenced
int y = 5;
*ptr = y; // ptr *is* being dereferenced