24 / 07 / 11

「一生一芯」Learn C the hard way - Ex 12

练习 12:While 循环和布尔表达式

#include <stdio.h> int main(int argc, char *argv[]) { // go through each string in argv int i = 0; while(i < argc) { printf("arg %d: %s\n", i, argv[i]); i++; } // let's make our own array of strings char *states[] = { "California", "Oregon", "Washington", "Texas" }; int num_states = 4; i = 0; // watch for this while(i < num_states) { printf("state %d: %s\n", i, states[i]); i++; } return 0; }

附加题 1

让这些循环倒序执行,通过使用i--argc开始递减直到0。你可能需要做一些算数操作让数组的下标正常工作。

int i = argc - 1; while(i >= 0) { printf("arg %d: %s\n", i, argv[i]); i--; } // let's make our own array of strings char *states[] = { "California", "Oregon", "Washington", "Texas" }; int num_states = 4; i = num_states - 1; // watch for this while(i >= 0) { printf("state %d: %s\n", i, states[i]); i--;

附加题 2

使用while循环将argv中的值复制到states

i = 0; while(i < num_states) { states[i] = argv[i]; i++; }

附加题 3

让这个复制循环不会执行失败,即使argv之中有很多元素也不会全部放进states

num_states 为界可以有效避免越界访问 states,但是需要添加对 argv 的限制来避免不属于输入的内容被写入 states (例如你的 PATH 变量)。以下是不加限制的结果:

⮞ ./ex11_2 aa arg 0: ./ex11_2 arg 1: aa state 0: California state 1: Oregon state 2: Washington state 3: Texas state 0: ./ex11_2 state 1: aa state 2: (null) state 3: SHELL=/bin/bash

添加限制的复制

i = 0; while(i < num_states) { if(i > argc) states[i]=NULL; else states[i] = argv[i]; i++; }

诶呀 用 if 好像超纲了,但无所谓了……

⮞ ./ex11_2 aa arg 0: ./ex11_2 arg 1: aa state 0: California state 1: Oregon state 2: Washington state 3: Texas state 0: ./ex11_2 state 1: aa state 2: (null) state 3: (null

附加题 4

研究你是否真正复制了这些字符串。答案可能会让你感到意外和困惑。

states[i] = argv[i]; 只是将 argv[i] 中的字符串指针赋值给 states[i],两者指向的是同一个内存地址,并没有真正复制字符串。