您的位置:首页 > 财经 > 产业 > 什么是新媒体运营_比较好的营销网站_栾城seo整站排名_西安seo公司哪家好

什么是新媒体运营_比较好的营销网站_栾城seo整站排名_西安seo公司哪家好

2024/12/25 11:01:54 来源:https://blog.csdn.net/weixin_52342399/article/details/144366043  浏览:    关键词:什么是新媒体运营_比较好的营销网站_栾城seo整站排名_西安seo公司哪家好
什么是新媒体运营_比较好的营销网站_栾城seo整站排名_西安seo公司哪家好

说明:

         这是个人对该在Linux平台上的C语言学习网站笨办法学C上的每一个练习章节附加题的解析和回答

ex9:

  • 将一些字符赋给numbers的元素,之后用printf一次打印一个字符,你会得到什么编译器警告?

    没有任何警告,列入给numbers的元素赋值字符'A'其实是赋给int类型变量字符'A'的ASCII码值65。
     
  • names执行上述的相反操作,把names当成int数组,并一次打印一个intValgrind会提示什么?

    只要赋值在char类型变量的范围之内也不会报错。
     
  • 有多少种其它的方式可以用来打印它?

    可以使用循环来实现逐个打印元素:
    for (int i = 0; i < 4; i++) {printf("%c ", name[i]);
    }
    printf("\n");
    
    可以直接以字符串类型来自动全部打印出来:
    printf("%s\n", name);
    
    可以使用指针遍历打印:
    char *ptr = name;
    for (int i = 0; i < 4; i++) {printf("%c ", *(ptr + i));
    }
    printf("\n");
    
    或者:
     
    char *p = name;
    while (*p!= '\0') {putchar(*p);p++;
    }
  • 如果一个字符数组占四个字节,一个整数也占4个字节,你可以像整数一样使用整个name吗?你如何用黑魔法实现它?
    可以使用memcpy函数来复制:
     
    char name[] = "Zed";
    int name_as_int = 0;memcpy(&name_as_int, name, sizeof(name));printf("name as integer: %d\n", name_as_int);
    结果为:
    name as integer: 6579546
    name as hex: 0x64655a
    可以用name_as_int变量重新打印出Zed:
     
    printf("name_as_int is %c%c%c",name_as_int&0xff,name_as_int>>8&0xff,name_as_int>>16&0xff);
           这里涉及到一点知识点:数据的低位字节存于低地址,高位字节存于高地址。对于给定的字符数组name[4] = {'Z', 'e', 'd', '\0'},'Z'(ASCII 码值为 90,十六进制 0x5A)、'e'(ASCII 码值为 101,十六进制 0x65)、'd'(ASCII 码值为 100,十六进制 0x64)、'\0'(十六进制 0x00)。
           而对于'\0'空字符来说(ASCII 码值为 0,十六进制 0x00),int变量将其存在最高位所以导致了其自然消失了
     
  • 拿出一张纸,将每个数组画成一排方框,之后在纸上画出代码中的操作,看看是否正确。

    跳过
     
  • name转换成another的形式,看看代码是否能正常工作。
     
    void *ptr = name;
    printf("name as pointer: %p\n", ptr);
    

    可以正常工作

 ex10:

先做一个对指针内容的总结回顾:

char *states[] = { "California", "Oregon", "Washington", "Texas" };
char states[4][20] = {"California", "Oregon","Washington", "Texas"
};

        其中char *states[] 是一个指针数组,数组中的每个元素是一个指向 char 的指针(即 char*)。而states 是一个二维数组,每一行固定分配了 20 个字符的空间。区别是:指针数组每个元素是一个指针,指向字符串的首地址;不需要为每个字符串分配固定长度的内存;字符串常量存储在只读区域;更灵活,可以指向不同大小的字符串或动态分配内存。而二维数组每个元素是一个固定大小的字符数组;每行占用固定大小的内存即便字符串较短);所有字符串存储在一个连续的内存块中;内存分配固定,不能指向其它字符串。


        对于指针指向类型的不同有:在计算机中,int *pointerchar *pointer 本质上都是指针,它们的大小只取决于系统的架构

  • 在 32 位系统中,指针占用 4 字节
  • 在 64 位系统中,指针占用 8 字节

        因此,无论是 int *pointer 还是 char *pointer,它们的大小通常是一样的,均为系统指针大小。 

//指向的数据类型不同
int *pointer //表示一个指针,它指向一个 int 类型的变量。
char *pointer //表示一个指针,它指向一个 char 类型的变量。
int *pointer //:步长为 sizeof(int)(通常是 4 字节或 8 字节)。
char *pointer //:步长为 sizeof(char)(始终是 1 字节)。

(步长不同)示例代码:

#include <stdio.h>int main(){int int_var = 42;char char_var = 'A';int *int_ptr = &int_var;char *char_ptr = &char_var;printf("int_ptr: %p, int_ptr + 1: %p\n", int_ptr, int_ptr + 1);printf("char_ptr: %p, char_ptr + 1: %p\n", char_ptr, char_ptr + 1);return 0;
}/*输出:
int_ptr: 00000030ac7ffc1c, int_ptr + 1: 00000030ac7ffc20
char_ptr: 00000030ac7ffc1b, char_ptr + 1: 00000030ac7ffc1c
*/

(指针解引用不同)示例代码:

//*int_ptr 读取一个 int 类型的值,占用 sizeof(int) 字节。
//*char_ptr 读取一个 char 类型的值,占用 1 字节。#include <stdio.h>int main(){int int_var = 16909060; // 0x01020304 in memorychar *char_ptr = (char *)&int_var;printf("char_ptr[0]: %d\n", char_ptr[0]); // 输出最低字节printf("char_ptr[1]: %d\n", char_ptr[1]); // 输出次低字节return 0;
}/*输出结果
char_ptr[0]: 4
char_ptr[1]: 3
*/
  • 弄清楚在for循环的每一部分你都可以放置什么样的代码。

    for (initialization; condition; increment) 是标准格式,其中每一部分可以放置以下内容: Initialization:可以放置任何类型的变量初始化或赋值语句
    Condition:可以是任何返回布尔值的表达式
    Increment:可以放置任何更新语句
     
  • 查询如何使用','(逗号)字符来在for循环的每一部分中,';'(分号)之间分隔多条语句
    例如
     
    for (int i = 0, j = 10; i < 5; i++, j--) {printf("i: %d, j: %d\n", i, j);
    }
    
  • 查询NULL是什么东西,尝试将它用做states的一个元素,看看它会打印出什么。

    NULL 是一个宏,表示空指针(即值为 0 的指针),用来指示某个指针未指向任何有效地址。
    在数组中使用 NULL:如果 states 数组中包含 NULL,表示该元素不指向任何字符串。
    示例:
    char *states[] = {"California", "Oregon",NULL, "Texas"
    };for (int i = 0; i < 4; i++) {printf("state %d: %s\n", i, states[i]);
    }/*输出结果
    state 0: California
    state 1: Oregon
    state 2: (null)
    state 3: Texas
    */
  • 看看你是否能在打印之前将states的一个元素赋值给argv中的元素,再试试相反的操作。
    // 修改 states 的元素为 argv 的元素
    states[0] = argv[1]; // 如果有命令行参数,将第一个参数赋值给 states[0]// 打印修改后的 states
    for (int i = 0; i < 4; i++) {printf("state %d: %s\n", i, states[i]);
    }// 反向操作:修改 argv 的元素为 states 的元素
    argv[1] = states[2]; // 将 states[2] 的值赋给 argv[1]
    printf("arg 1 after modification: %s\n", argv[1]);
    

ex11:

  • 让这些循环倒序执行,通过使用i--argc开始递减直到0。你可能需要做一些算数操作让数组的下标正常工作。
     
    int i = argc - 1;
    while (i >= 0) {printf("arg %d: %s\n", i, argv[i]);i--;
    }i = num_states - 1;  // 初始化为最后一个索引
    while (i >= 0) {printf("state %d: %s\n", i, states[i]);i--;
    }
    
  • 使用while循环将argv中的值复制到states
     
    i = 0;
    while (i < argc && i < num_states) {  // 确保不超出 states 数组范围states[i] = argv[i];i++;
    }
    
  • 让这个复制循环不会执行失败,即使argv之中有很多元素也不会全部放进states
     
    char **states = malloc(argc * sizeof(char *));  // 动态分配数组大小
    if (!states) {perror("Failed to allocate memory for states");return 1;
    }i = 0;
    while (i < argc) {  // 将所有 argv 元素复制到 statesstates[i] = argv[i];  // 将指针直接赋值i++;
    }
    
  • 研究你是否真正复制了这些字符串。答案可能会让你感到意外和困惑。

    在上述代码中,states[i] = argv[i]; 只是复制了指针,而不是字符串本身。
    这意味着 statesargv 的某些元素会指向相同的内存地址。
    要真正复制字符串,需要分配新内存并拷贝内容:
    #include <string.h> states[i] = malloc(strlen(argv[i]) + 1);  // 为每个字符串分配内存,+1为了分配空间存储字符串末尾的空字符 \0
    if (states[i]) {strcpy(states[i], argv[i]);  // 复制字符串内容
    }
    

e12: 

  • 我已经向你简短地介绍了&&,它执行“与”操作。上网搜索与之不同的“布尔运算符”。

    其他常见的布尔运算符: ||:逻辑或,若任意一个条件为真,结果为真。 !:逻辑非,将条件取反。 &:按位与。 |:按位或。 ^:按位异或。

     
  • 回到练习10和11,使用if语句使循环提前退出。你需要break语句来实现它,搜索它的有关资料。

    例如:
    for(i = 1; i < argc; i++) {if(strcmp(argv[i], "stop") == 0) {printf("Found 'stop', exiting loop.\n");break;}printf("Argument %d: %s\n", i, argv[i]);
    }
    
  • 第一个判断所输出的话真的正确吗?由于你的“第一个参数”不是用户输入的第一个参数,把它改正。
     if(argc == 1) {printf("You only have no argument. You suck.\n");} else if(argc > 1 && argc < 4) {printf("Here's your arguments:\n");for(i = 1; i < argc; i++) {if(strcmp(argv[i], "stop") == 0) {printf("Found 'stop', exiting loop.\n");break;}printf("%s ", argv[i]);}printf("\n");} else {printf("You have too many arguments. You suck.\n");}
    

ex14:

  • 编写另一个程序,在字母上做算术运算将它们转换为小写,并且在switch中移除所有额外的大写字母。
     
    //添加
    letter = letter + 32;
  • 使用','(逗号)在for循环中初始化letter
     
     for(int i = 0, letter = argv[arg][i]; letter != '\0'; i++, letter = argv[arg][i])

     
  • 使用另一个for循环来让它处理你传入的所有命令行参数。
     
    //在原来的for循环之前在添加一个for循环
    for(int arg = 1; arg < argc; arg++) {printf("Processing argument %d: %s\n", arg, argv[arg]);//.....
    }
  • 将这个switch语句转为if语句,你更喜欢哪个呢?

    if-else if的可读性更强,我会更喜欢使用if-else if
     
  • 在“Y”的例子中,我在if代码块外面写了个break。这样会产生什么效果?如果把它移进if代码块,会发生什么?自己试着解答它,并证明你是正确的。

    写在 if 外: 无论 if 条件是否满足,break 都直接跳出 switch 或 for,可能导致意外行为。 写在 if 内: 更精准,只有在条件满足时退出特定块。这里的 break 控制 Y 的特殊处理逻辑。

    修改后完整代码为:
    #include <stdio.h>int main(int argc, char *argv[]) {if(argc < 2) {printf("ERROR: You need at least one argument.\n");return 1;}// Process all argumentsfor(int arg = 1; arg < argc; arg++) {printf("Processing argument %d: %s\n", arg, argv[arg]);for(int i = 0, letter = argv[arg][i]; letter != '\0'; i++, letter = argv[arg][i]) {// Convert to lowercaseif(letter>=65&&letter<=90){letter = letter+32;}if(letter == 'a') {printf("%d: 'A'\n", i);} else if(letter == 'e') {printf("%d: 'E'\n", i);} else if(letter == 'i') {printf("%d: 'I'\n", i);} else if(letter == 'o') {printf("%d: 'O'\n", i);} else if(letter == 'u') {printf("%d: 'U'\n", i);} else if(letter == 'y' && i > 2) {printf("%d: 'Y'\n", i);// Moving 'break' inside the condition limits its impact to this case only.break;} else {printf("%d: %c is not a vowel\n", i, letter);}}}return 0;
    }
    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com