数组部分
数组知识注意
数组的长度测量办法
Len = sizeof(a)/sizeof(a[0]);
sizeof()函数的具体
sizeof 运算符的语法形式为 sizeof(expression),其中 expression 可以是类型名、变量名、数组名或指针名。它返回一个 size_t 类型的值,表示给定表达式的大小。
例如,sizeof(int) 返回整型 int 的大小(通常为 4 字节),sizeof(float) 返回浮点型 float 的大小(通常为 4 字节)。
sizeof和size区别
- `sizeof` 是 C 语言的运算符,用于计算对象的大小。
- `sizeof` 返回一个 `size_t` 类型的值,表示对象的大小。
数组在函数传递过程问题
出现以上问题的原因:
指针的sizeof大小为8
指针[]索引的类型为int其sizeof的大小为4
因此得到len=2
指正不能用sizeof()的办法求出指针指向的数组的长度
数组的索引
类字典方法
调用:
i属于0,1,2,3,4
coins[i].amount
调用第一列的数字
coins[i].*name
调用第二列的字符串
指针部分
指针的基础内容
&运算符
&获得变量的地址
获得的位置大小取决于编译器
获得的变量要是一个明确的变量名称
如不能取(i++)、(i+p)
间接运算符*
其实表示指针所指向的值
如:a = *p;
就是将p地址所对应的值赋值给a
[ ]运算符
获得所储存的值与*运算符类似
主要用于索引一个指针或者数组储存的值
数组
整个数组的位置就是a[0]的位置
其他数组的位置依次相差固定单位
指针
保存变量地址的一个变量
定义:
int *p;
int *p=&i;
*是定义指针的特殊字符,同时也是指针指向的地址所对应的值的运算符号
各个数据结构在不同机子中的值
windows操作系统,
32位机中
- char: 1个字节
- short: 2个字节
- int: 4个字节
- long: 4个字节
- long long: 8个字节
windows操作系统,
64位机中
- char: 1个字节
- short: 2个字节
- int: 4个字节
- long: 8个字节
- long long: 8个字节
malloc函数
malloc () :定义变长数组
Int *ptr=(int*)malloc(n*sizeof(int));定义一维变长数组
Int *ptr=(int**)malloc(n*sizeof(int**); 内部储存的是指针的空间 可以用来定义二维数组
具体操作:
Int *ptr = (int**) malloc (n*sizeof(int*));
for(i=0;i++;i<n)
ptr[0]=Int *ptr=(int*)malloc(n*sizeof(int));
三维四维以上的可以叠加循环来进行
ps:运用完动态内存后要记得用free函数进行释放内存
关于指针传入参数的一些问题
函数中数组的传递
实质上传递的数组是指针
scanf为什么不报错问题
编译器以为传入i的是i的地址再拿这个地址所对应的值进行运算字符的处理(char)
字符部分
字符的输入
- 用scanf函数%d输入其所对应的ASCII值
- 用scanf函数%c直接输入所需要的字符类型
注意:scanf中当是以%d%c形式输入%c会读入空格
当以%d %c形式读入%c是读入非空格的元素
字符串的计算
实质上是所对应的字符的ascll码值的运算
相减:得到的结果是ascll码值
相加:得到的是字符结果
逃逸字符
t:是下一个制表位(每四个字符一个制表位)
字符串类型:
c语言在两个相邻的字符串中,如若没有其他符号相连接编译器会自动将其连接成一个字符串
字符串的输入
scanf 函数可以用%s进行(同理printf也可以用%s进行输出)
scanf读入单词读到:空格 回车 Tap为止输入12345678
大于八个
如若有另一个scanf函数8给予这个scanf函数进行赋值操作
定义了指针,没给予指针初始化会导致其指向随机地址所对应的随机值。
字符串数组和字符串指针问题
字符串数组:
字符串常量的值复制到字符串数组中,字符串数组建立新的内存空间,与字符串常量的地址不同,字符串数组因为其数组的特性,a[0]作为该数组的地址,导致数组的位置不能随意改变,如若改变会造成数组a[1]、a[2]等数据混乱。因此字符串数组从建立起就是一个指针常量,其地址是个常量,但是可以改变其包含的字符串的内容(因为字符串没有储存在字符串常量区),可以适用于需要对字符串修改的地方
字符串指针:
字符串指针与字符串常量的位置相同,实际上从字符串指针建立起,字符串指针就是指向字符串常量的地址。字符串指针是指针变量,但是由于其指向的值为字符串常量,其值不能改变,但是字符串指针指向的值可以改变,适用于对字符串的排序问题上。
字符串的比较问题:
字符串比较大小的原理是基于字符的按字典顺序进行比较。字符串比较函数(如`strcmp`)会逐个比较字符串中对应位置的字符,直到找到不同的字符或遇到字符串结束符(`\0`)为止。比较的规则如下:
1. 如果两个对应位置的字符相等,则继续比较下一个位置的字符。
2. 如果找到不同的字符,则根据它们的ASCII码值来判断大小关系。较小的字符被认为是小于较大的字符。
3. 如果一个字符串已经到达结束符(`\0`),而另一个字符串还有剩余字符,则较短的字符串被认为是小于较长的字符串。
优先级依次递减
两个字符数组的比较永远不可能相等(==)
原因:数组的地址不可能相同导致他们不可能相等
指针字符串比较问题
因为指针字符串所指向的是字符串常量,所在的地址相同所以会相等
两个指针具有相同的地址时,它们被认为是相等的。
缓存问题
getchar () 和 putchar() 通过缓存获取或输出用户输入的数据所以可以在输入时随时删除修改 输入完成后 将缓存内的数据输入或输出到终端 并不是一步将所获得的数据输入或者输出
getchar只输入一个且多余的给其他的输入函数中
具体原理是把用户输入的数据储存在shell中直到用户按下回车键,shell中的缓存传入计算机中进行与运算。
输入问题:
输入函数的优先级是程序运行中最先运行的无论在哪个位置
因此输入的多余的内容会传给下一个输入函数,直到没有输入函数为止。
如果scanf输入异常,用户输入的数据将会保留在输入队列之中传递给下一个输入函数的运行
在使用"%s"格式控制符输出指针和数组时,需要注意以下几点:
1. 指针输出:在这个特定的printf语句中,使用"*str"作为"%s"的参数是错误的,会导致编译错误。这是因为"%s"期望一个字符串的地址作为参数,而不是一个单个字符的值。当我们使用"*str"时,它实际上是解引用了指针str,获取了指针指向的字符的值。这个字符值无法被解释为有效的地址,因此导致了编译错误。
2. 字符数组输出:"%s"格式控制符用于输出字符数组时,要确保数组以null结尾,即具有正确的字符串终止符。否则,输出的结果可能是未定义的,因为"%s"控制符会继续输出字符,直到遇到null终止符。
```c
char arr[5] = {'H', 'e', 'l', 'l', 'o'};
printf("%s\n", arr); // 错误的方式,没有null终止符,结果不确定
char arr2[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("%s\n", arr2); // 正确的方式,输出字符串 "Hello"
```
3. 字符串长度限制:使用"%s"输出字符数组时,要确保目标数组长度足够容纳字符串,并防止溢出。如果输出的字符串超过了数组的长度,可能会导致未定义的行为,包括缓冲区溢出和内存损坏。
```c
char arr[10] = "Hello, world!";
printf("%s\n", arr); // 正确的方式,数组长度足够
char arr2[5] = "Hello";
printf("%s\n", arr2); // 错误的方式,数组长度不足,可能导致溢出
```
总之,当使用"%s"格式控制符输出指针和数组时,需要确保指针指向的字符串以null结尾,字符数组具有正确的字符串终止符,并确保数组长度足够容纳字符串,以避免潜在的错误和未定义行为。
字符串的排序
/* sort_str.c -- reads in strings and sorts them */
#include <stdio.h>
#include <string.h>
#define SIZE 81 /* string length limit, including \0 */
#define LIM 20 /* maximum number of lines to be read */
#define HALT "" /* null string to stop input */
void stsrt(char* strings[], int num);/* string-sort function */
char* s_gets(char* st, int n);
int main(void)
{
char input[LIM][SIZE]; /* array to store input */
char* ptstr[LIM]; /* array of pointer variables */
int ct = 0; /* input count */
int k; /* output count */
printf("Input up to %d lines, and I will sort them.\n", LIM);
printf("To stop, press the Enter key at a line's start.\n");
while (ct < LIM && s_gets(input[ct], SIZE) != NULL
&& input[ct][0] != '\0')
{
ptstr[ct] = input[ct]; /* set ptrs to strings */
ct++;
}
stsrt(ptstr, ct); /* string sorter */
puts("\nHere's the sorted list:\n");
for (k = 0; k < ct; k++)
puts(ptstr[k]); /* sorted pointers */
return 0;
}
/* string-pointer-sorting function */
void stsrt(char* strings[], int num)//冒泡排序
{
char* temp;
int top, seek;
for (top = 0; top < num - 1; top++)
for (seek = top + 1; seek < num; seek++)
if (strcmp(strings[top], strings[seek]) > 0)
{
temp = strings[top];
strings[top] = strings[seek];
strings[seek] = temp;
}
}
char* s_gets(char* st, int n)
{
char* ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else // must have words[i] == '\0'
while (getchar() != '\n')
continue;
}
return ret_val;
}
注意:
排序排的是指向字符串的指针,而不是字符串本身。