大一C语言查缺补漏1 12.21

2023-12-21 21:55:17

对于指针p来说,p的值和p所指存储单元的值有什么不同

对于指针变量p来说,主要有以下两个概念:

  1. p的值:指针p本身是一个变量,它在内存中有一个自己的地址。p的值就是这个地址,通常是一个数字,代表了p指向的内存位置。换句话说,p的值就是它所存储的内存地址。

  2. p所指存储单元的值:当指针p指向一个内存地址时,那个内存地址对应的存储单元里存放着某个数据值。这个数据值就是我们所说的“p所指存储单元的值”。通过解引用操作符 *,我们可以访问这个存储单元的值。例如,*p 就表示 p 指向的内存地址中存储的数据值。

简而言之,p的值是存储在指针变量p本身的内存地址,而p所指存储单元的值是p指向的内存地址中存储的实际数据。一个是地址,一个是地址中存储的数据。


int Fun(int *p){int x =5; p = &x ; return *p}请解释每一步,C语言

这个C语言函数Fun的定义和操作可以分解为以下几步:

int Fun(int *p) 
{ 
int x = 5; // Step 1 
p = &x; // Step 2 
return *p; // Step 3 
}
  1. int x = 5;: 在函数内部创建了一个名为x的整型变量,并初始化其值为5。这个变量x在函数的栈帧中分配了内存。

  2. p = &x;: 这一行将传入函数的指针参数p的值改变为变量x的地址。注意,这里只是改变了指针p本身存储的地址,而不是p原来指向的地址中的值。也就是说,现在p不再指向调用者提供的那个地址,而是指向了函数内部的局部变量x

  3. return *p;: 这一行返回了指针p所指向的存储单元的值,由于我们在上一步中已经将p指向了变量x,所以*p就是变量x的值,即5。因此,这个函数最终返回的是5。

需要注意的是,由于这个函数改变了传入的指针参数p的值,所以在函数调用后,调用者看到的p的值可能会与调用前不同。但是,由于x是函数的局部变量,当函数返回时,x会被销毁,所以如果调用者在函数返回后尝试通过修改后的p访问x,结果将是未定义的。


第三步的p中的? ?*? ?相当于解指针吗

是的,第三步中的 *p 中的 * 符号在这里表示解指针(dereferencing)操作。

在 C 语言中,当一个指针变量前面使用 * 运算符时,它表示获取该指针变量所指向的内存地址中的值。也就是说,*p 就是访问通过指针 p 指向的内存位置中的数据。

在这个函数 Fun 的上下文中,由于在第二步中已经将指针 p 的值改为变量 x 的地址,所以第三步的 *p 实际上就是访问变量 x 的值。因此,return *p; 返回的是变量 x 的值,即 5。


int Fun (char *s){char *p = s ; while (*p != '\0') p++;return p-s; printf("%d\n",Fun("goodbye!"))}请解释每一步,C语言

这个C语言函数`Fun`的定义和操作可以分解为以下几步:

```c
int Fun(char *s) {
? ? char *p = s; // Step 1
? ? while (*p != '\0') p++; // Step 2
? ? return p - s; // Step 3
}

printf("%d\n", Fun("goodbye!")); // Step 4 (outside the function)
```

1. `char *p = s;`:
? ?在函数内部创建了一个新的指针变量`p`,并将它的值初始化为传入的字符串指针`s`的值。现在,`p`和`s`都指向同一个字符串的首字符。

2. `while (*p != '\0') p++;`:
? ?这是一个循环,它会一直执行直到遇到字符串的结束标记(null字符`\0`)。在每次循环迭代中,`*p`会先获取当前`p`指向的字符,然后判断是否等于`\0`。如果不等于`\0`,则将`p`向前移动一位(指向下一个字符)。这个过程实际上是遍历整个字符串,直到找到结束标记。

3. `return p - s;`:
? ?这一行计算并返回从字符串开始到结束标记之间的字符数量。通过减法`p - s`,我们可以得到字符串中字符的数量(包括空格和标点符号),因为`p`现在指向字符串的结束位置(即结束标记`\0`后面的位置),而`s`指向字符串的开始位置

4. `printf("%d\n", Fun("goodbye!"));`:
? ?这一行在函数外部调用`Fun`函数,并传入一个字符串字面量"goodbye!"作为参数。`Fun`函数返回该字符串的字符数量,然后`printf`函数将这个数字输出到控制台,并在数字后添加一个换行符`\n`。

所以,对于给定的输入"goodbye!",`Fun`函数会计算并返回其字符数量(不包括结束标记`\0`),即7。然后`printf`函数将这个数字7输出到控制台。


若使用一维数组名作为函数实参,形参数组可以不指定大小


合法的声明方式:

void Fun (int array =[ ]);

void Fun (int array [ ][10]);


在32位编译系统中,若有变量定义“int?a?,*p?=&a;”当执行p++后,为什么p向高地址移了4个字节,而不是向低地址?

在32位编译系统中,整型变量`int`的大小通常是4个字节。当您声明一个指针`*p`并让它指向一个整型变量`a`的地址,即`p?=?&a;`时,指针`p`存储的是变量`a`的内存地址。

当执行`p++`操作时,根据C语言的规则,指针会向更高的内存地址移动。移动的量等于指针所指向的数据类型的大小。由于`p`指向一个`int`类型的变量,而在32位系统中`int`占用4个字节,所以`p++`会让指针`p`向高地址移动4个字节。

这是因为`p++`实际上是进行了如下操作:

1.?先获取当前`p`指向的地址。
2.?然后将`p`的值增加`sizeof(int)`,在32位系统中就是增加4。
3.?最后`p`就指向了新的地址,即原地址加4。

这就是为什么在执行`p++`后,指针`p`向高地址移了4个字节的原因。

如果要让指针向低地址移动,可以使用`p--`操作,这会使得指针向低地址移动相应数据类型大小的字节数。


为什么char?a[?]?={"string"}为什么是错的

因为没有表明数组的长度。而且,如果是字符串的数组,要包含终止符的长度。

字符串数组长度一定需要预留终止符的位置吗?

在C语言中,字符串数组的长度通常需要预留终止符('\0')的位置。这是因为C语言中的字符串是以空字符'\0'作为结束标志的。当你在字符数组中存储一个字符串时,你需要确保数组有足够的空间来存储所有的字符以及这个终止符。

例如,如果你有一个字符串"Hello",你不能简单地定义一个大小为5的字符数组:

```c
char?str[5]?=?"Hello";?//?错误:没有空间存储终止符'\0'
```

而是需要定义一个大小为6的字符数组,以容纳所有字符和终止符:

```c
char?str[6]?=?"Hello";?//?正确:预留了空间存储终止符'\0'
```

这样,当你使用诸如`strlen()`之类的函数来计算字符串长度,或者使用某些字符串处理函数时,它们会通过查找这个终止符来确定字符串的结尾。

然而,在一些高级编程语言如Java或C#中,字符串是以对象的形式存在,它们内部已经包含了表示字符串长度的信息,因此在这些语言中,你不需要手动预留终止符的位置。?


为什么char?a[?]={0,1,2,3,4,5}是对的?

在C或C++中,`char?a[]?=?{0,?1,?2,?3,?4,?5}`是正确的,因为它是在初始化一个字符数组。这里的数组`a`被定义为包含6个元素的字符数组,并且这些元素被显式地初始化为对应的数字值。

在字符数组中,每个元素都可以存储一个字符或一个整数(因为字符在计算机中通常用整数表示)。在这个例子中,虽然数组中的元素看起来像整数,但它们实际上被解释为字符编码。在ASCII编码系统中,这些数字对应于以下字符:

-?0?对应于?'\0'(空字符或null?terminator)
-?1?对应于控制字符?START?OF?HEADING
-?2?对应于控制字符?START?OF?TEXT
-?3?对应于控制字符?END?OF?TEXT
-?4?对应于控制字符?END?OF?TRANSMISSION
-?5?对应于?ENQ?(Enquiry)

所以,这个初始化实际上是创建了一个包含特殊字符和控制字符的字符数组。如果你打算用这个数组来存储字符数据,需要注意这些字符可能不是你预期的可打印字符。如果你打算用它来存储整数数据,可能更合适的做法是使用整数数组(如?`int?a[]?=?{0,?1,?2,?3,?4,?5}`)。


strlen会记空字符吗

`strlen()`?函数不会计算字符串中的空字符(或称为空格字符,ASCII值为32)。`strlen()`?的作用是计算从给定字符串的起始地址到第一个终止符?`\0`(ASCII值为0)之间的字符数。终止符?`\0`?是字符串的结束标志,它标志着字符串的实际内容的结束。

因此,如果一个字符串中包含空格字符(例如?`"Hello?World"`),`strlen()`?会将这些空格字符计入字符串的长度,因为它们是字符串实际内容的一部分。但是,终止符?`\0`?不会被计入字符串的长度,它是字符串的结尾标记,`strlen()`?在遇到它时就会停止计数。


枚举格式

enum a {a1,a2,a3};

而且只能放int类型?


在定义一个结构体变量时,系统分配给该变量的内存大小是:各成员所需内存量的总和


函数不能嵌套定义,但可以嵌套调用。?


typeof是用于将已存在的类型用一个新的名字来代表。而数据类型是早已经定下来的那几个,因此,typeof是不可以增加新的类型。?


%f默认保留6位小数。



昨天一些疑惑解答:?

在C语言中,如果未指定存储类别,则变量隐含的存储类别有两种:局部变量是auto,全局变量是extern?


在C语言中,索引越界不是语法错误,它输出的结果是一个随机数。因为访问的是未知的内存单元,而我们未知单元里面保存了上面,所以是随机数。

文章来源:https://blog.csdn.net/2301_80185446/article/details/135129012
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。