char *string = "This is a string";
printf("%s\n", string);
What is string when it is defined and initialized? Is it a pointer? And if it is, why don’t you dereference it when printing it in the printf function? There are many examples like this that confuse me.
首先,简要介绍一下背景:
除非它是sizeof
或一元&
运算符的操作数,或者是一个字符串字面值用于声明中初始化另一个数组,类型为 "N个元素的T
数组" 的表达式将被转换("衰减")为类型为 "指向T
的指针" 的表达式,并且表达式的值是数组的第一个元素的地址。
字符串字面值"This is a string"
是类型为 "17个元素的char
数组" (16个字符加上0终止符)的表达式。由于它既不是sizeof
或一元&
运算符的操作数,也没有用于初始化char
数组,因此表达式的类型被转换为 "指向char
的指针",并且表达式的值是第一个元素的地址。
变量string
声明为类型 "指向char
的指针" (char *
),并使用字符串字面值的地址进行初始化。
在
printf
函数调用中,转换说明符
%s
期望其对应的参数具有类型
char *
;它将打印从指定地址开始的字符,直到遇到0终止符。这就是为什么变量在
printf
函数调用中不被解引用的原因。
int i;
scanf("%d", &i);
How does this function update the value of integer i, when the ampersand is supposed to reference the location in memory of the variable, not the value? It gets even more complicated with arrays and structs, which is where I stopped and decided I needed to find some advice.
C通过值传递所有函数参数,这意味着函数定义中的形式参数和函数调用中的实际参数是内存中的两个不同对象。更新形式参数对实际参数没有影响。例如,想象一个简单的swap函数:
void swap( int a, int b ) { int tmp = a; a = b; b = tmp; return; }
...
int x = 0, y = 1;
printf( "before swap: x = %d, y = %d\n", x, y );
swap( x, y );
printf( " after swap: x = %d, y = %d\n", x, y );
如果您编译并运行此代码,则在两个输出语句中将看到
x
和
y
的相同值;
a
和
b
与
x
和
y
在内存中是不同的对象,更改
a
和
b
的值不会影响
x
和
y
的值。
由于我们想要修改
x
和
y
的值,因此我们必须向函数传递这些变量的
指针,如下所示:
void swap( int *a, int *b ) { int tmp = *a; *a = *b; *b = tmp; return; }
...
int x = 0, y = 1;
printf( "before swap: x = %d, y = %d\n", x, y );
swap( &x, &y );
printf( " after swap: x = %d, y = %d\n", x, y );
我们不是交换a
和b
的值,而是交换a
和b
所指向的值;表达式*a
和*b
引用内存中与x
和y
相同的对象。
这就是为什么在scanf
调用中必须传递一个指向i
的指针(scanf
转换说明符%d
期望相应的参数具有类型int *
);否则,您将无法更新i
的值。
我对"Learn C The Hard Way"并不是很印象深刻;然而,几乎所有的C参考书都有一些致命的缺陷。Kernighan和Ritchie的The C Programming Language虽然有点老了(它没有涵盖最近两个标准修订中引入的任何内容),但仍然可能是最好的介绍该语言的总体书籍。我也听说过King的C Programming: A Modern Approach不错。我的首选桌面参考书是Harbison & Steele的C: A Reference Manual,尽管它正是所说的 - 一个参考手册,并因此对解释基本概念不太重视。
scanf
和printf
接受什么以及它们在处理数字和字符串时所做的事情呢? - Uchia Itachi