24 / 07 / 11
#include <stdio.h> int main(int argc, char *argv[]) { int i = 0; // go through each string in argv // why am I skipping argv[0]? for(i = 1; i < argc; i++) { printf("arg %d: %s\n", i, argv[i]); } // let's make our own array of strings char *states[] = { "California", "Oregon", "Washington", "Texas" }; int num_states = 4; for(i = 0; i < num_states; i++) { printf("state %d: %s\n", i, states[i]); } return 0; }
⮞ make ex10 cc -Wall -g -c ex10.c -o ex10.o cc -o ex10 ex10.o ⮞ ./ex10 aaaa bbbb cccc dddd arg 1: aaaa arg 2: bbbb arg 3: cccc arg 4: dddd state 0: California state 1: Oregon state 2: Washington state 3: Texas ⮞
将
i
初始化为0看看会发生什么。是否也需要改动argc
,不改动的话它能正常工作吗?为什么下标从0开始可以正常工作?
⮞ ./ex10 a b c d arg 0: ./ex10 arg 1: a arg 2: b arg 3: c arg 4: d state 0: California state 1: Oregon state 2: Washington state 3: Texas
argc
的第一项是 ./ex10
本身哈哈哈哈哈。
将
num_states
改为错误的值使它变大,来看看会发生什么。
⮞ ./ex10 a b c d arg 0: ./ex10 arg 1: a arg 2: b arg 3: c arg 4: d state 0: California state 1: Oregon state 2: Washington state 3: Texas Segmentation fault ⮞ state 4: (null) ==5228== Invalid read of size 1 ==5228== at 0x4851E56: strlen (vg_replace_strmem.c:505) ==5228== by 0x48DFD30: __vfprintf_internal (vfprintf-internal.c:1517) ==5228== by 0x48C979E: printf (printf.c:33) ==5228== by 0x109235: main (ex10.c:21) ==5228== Address 0x9579af4c8feb2d00 is not stack'd, malloc'd or (recently) free'd ==5228== ==5228== ==5228== Process terminating with default action of signal 11 (SIGSEGV) ==5228== General Protection Fault ==5228== at 0x4851E56: strlen (vg_replace_strmem.c:505) ==5228== by 0x48DFD30: __vfprintf_internal (vfprintf-internal.c:1517) ==5228== by 0x48C979E: printf (printf.c:33) ==5228== by 0x109235: main (ex10.c:21) ==5228== ==5228== HEAP SUMMARY: ==5228== in use at exit: 1,024 bytes in 1 blocks ==5228== total heap usage: 1 allocs, 0 frees, 1,024 bytes allocated
不要越界喔。
弄清楚在
for
循环的每一部分你都可以放置什么样的代码。
查询如何使用
','
(逗号)字符来在for
循环的每一部分中,';'
(分号)之间分隔多条语句。
在 C 语言中,for
循环具有以下语法结构:
for (initialization; condition1, condition2; increment) { // Loop body }
在这个结构中:
**初始化部分 (initialization)**:在循环开始前执行一次,通常用于声明和初始化控制变量。
**条件部分 (condition)**:在每次迭代前进行检查,如果条件为真,继续执行循环体;如果条件为假,退出循环。
**增量部分 (increment)**:在每次循环体执行后执行一次,用于更新控制变量。
**循环体 (loop body)**:在每次迭代中执行的代码块。
查询
NULL
是什么东西,尝试将它用做states
的一个元素,看看它会打印出什么。
在 C 语言中,NULL
是一个宏,它通常定义为一个指向地址为 0 的指针。它表示一个空指针,即不指向任何对象或函数的指针。使用 NULL
可以避免指针指向未初始化或无效的地址,减少了程序出错的风险。
char *states[] = { "California", "Oregon", "Washington", NULL, "Texas" }; int num_states = 5; for(i = 0; i < num_states; i++) { printf("state %d: %s\n", i, states[i]); }
⮞ ./ex10 arg 0: ./ex10 state 0: California state 1: Oregon state 2: Washington state 3: (null) state 4: Texas
看看你是否能在打印之前将
states
的一个元素赋值给argv
中的元素,再试试相反的操作。
有点不理解题目的表述,如果直接在打印 argv
前将 states
赋值给它,那么必然会报错,因为此时 states
还没有被申明。如果将申明移动到打印前,尝试如下:
⮞ ./ex10 state 0: California state 1: Oregon state 2: Washington state 3: Texas ⮞ ⮞ ./ex10 a b c d arg 1: California arg 2: b arg 3: c arg 4: d state 0: California state 1: Oregon state 2: Washington state 3: Texas
相反操作如下:
⮞ make ex10 cc -Wall -g -c ex10.c -o ex10.o cc -o ex10 ex10.o ⮞ ./ex10 state 0: California state 1: (null) state 2: Washington state 3: Texas ⮞ ./ex10 aa bb cc arg 1: aa arg 2: bb arg 3: cc state 0: California state 1: aa state 2: Washington state 3: Texas ⮞