C++中一些散碎的知识点_int **指针与二维数组问题_memset()和memcpy()

目录

1、int **指针与二维数组问题

2、memset()和memcpy()

1、int **指针与二维数组问题

01)定义二维数组方法:

int matrix[ROWS][COLUMNS];  //定义一个二维数组,其中ROWS和COLUMNS为常数

02)加入有如下声明的子函数:

void printMatrix(int ** numbers,int rows,int columns);

03)如果直接使用如下方法调用,是错误的;

printMatrix(matrix,ROWS,COLUMNS);  //直接这样调用时错误的

原因在于matrix是 int (*)[COLUMNS]类型的,但是函数printMatrix需要的是int **类型的,这两者明显不匹配。

int **从类型上讲是一个指向整型指针的指针,那么如果想要用它来表示一个矩阵需要怎么做呢?因为它的元素是一个指针,如果如果它的每一个元素都表示矩阵的一行,那么它就可以用来表示一个矩阵了。实现代码如下:

 1 //生成矩阵  
 2 int ** generateMatrix(int rows,int columns)  
 3 {  
 4     int **numbers=new int*[rows];  
 5     for(int i=0;i<rows;i++){  
 6         numbers[i]=new int[columns];  
 7         for(int j=0;j<columns;j++)  
 8                 numbers[i][j]=i*columns+j;  
 9     }  
10     return numbers;   
11 }
用int **来表示一个矩阵

把int*当做一个整体。它表示创建了一个大小为rows的数组,这个数组的每一个元素代表一个指针。内存布局如下:

这里numbers是一个指向指针的指针,能够用numbers用来表示矩阵的关键就在于使用new关键字分配的内存是连续的,这样number[i]的地址就可以根据numbers的地址计算出来,因为指针变量占据4个字节的内存区域(32位机器)。如果不使用上面的方式分配内存,numbers就真的只是一个指向指针的指针了

04)正确使用printMatrix(matrix,ROWS,COLUMNS)的测试代码:

 1 #include <stdlib.h>  
 2 #include <stdio.h>  
 3 #include <iostream>  
 4 //打印矩阵  
 5 void printMatrix(int ** numbers,int rows,int columns){  
 6     for(int i=0;i<rows;i++)  
 7     {  
 8             for(int j=0;j<columns;j++)  
 9                     std::cout<<numbers[i][j]<<" ";  
10         std::cout<<std::endl;  
11     }  
12 }  
13   
14 //生成矩阵  
15 int ** generateMatrix(int rows,int columns)  
16 {  
17     int **numbers=new int*[rows];  
18     for(int i=0;i<rows;i++){  
19         numbers[i]=new int[columns];  
20         for(int j=0;j<columns;j++)  
21                 numbers[i][j]=i*columns+j;  
22     }  
23     return numbers;   
24 }  
25 int main(){  
26     int **numbers=generateMatrix(4,5);  
27     printMatrix(numbers,4,5);  
28     //释放内存  
29     for(int i=0;i<4;i++)  
30             delete [] numbers[i];  
31     delete numbers;  
32     return 0;
View Code

 参考博客:

https://www.cnblogs.com/lpxblog/tag/C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98/

2、memset()和memcpy()

一、memset()用法

void *memset(void *s,int c,size_t n)

作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c(给空间初始化)

C语言需要包含头文件string.h;C++需要包含cstring  或  string.h

 1 #include <string.h>
 2  
 3   #include <stdio.h>
 4  
 5   #include <memory.h>
 6  
 7   int main(void)
 8  
 9   {
10  
11   char buffer[] = "Hello world\n";
12  
13   printf("Buffer before memset: %s\n", buffer);
14  
15   memset(buffer, '*', strlen(buffer) );
16  
17   printf("Buffer after memset: %s\n", buffer);
18  
19   return 0;
20  
21   }
示例

输出结果:

  Buffer before memset: Hello world

  Buffer after memset: ***********

memset() 函数常用于内存空间初始化。如:

  char str[100];

  memset(str,0,100);

memset()错误用法:

 1 int main(void)
 2  
 3   {
 4  
 5   char *buffer = "Hello world\n";
 6  
 7   printf("Buffer before memset: %s\n", buffer);
 8  
 9   memset(buffer, '*', strlen(buffer) );
10  
11   printf("Buffer after memset: %s\n", buffer);
12  
13   return 0;
14  
15   }
memset()错误用法

报错原因:char * buffer = "Hello world\n";    字符串"Hello world\n"存在于只读存储区,其内容不能被随意更改!!!!

二、memcpy()函数用法

void *memcpy(void *dest, const void *src, size_t n);

C语言需要包含头文件string.h;C++需要包含cstring  或  string.h。

用法:用来将src地址处的内容拷贝n个字节的数据至目标地址dest指向的内存中去。函数返回指向dest的指针。

示例1:

作用:将s中的字符串复制到字符数组d中

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5 char *s="Golden Global View";
 6 char d[20];
 7 clrscr();
 8 memcpy(d,s,( strlen(s)+1) );
 9 printf("%s",d);
10 getchar();
11 return 0;
12 }
13 输出结果:Golden Global View
View Code

示例2:

作用:将s中第14个字符开始的4个连续字符复制到d中。(从0开始)

 1 #include <string.h>
 2 int main(
 3 {
 4 char *s="Golden Global View";
 5 char d[20];
 6 memcpy(d,s+14,4); //从第14个字符(V)开始复制,连续复制4个字符(View) //memcpy(d,s+14*sizeof(char),4*sizeof(char));也可
 7 d[4]='\0';
 8 printf("%s",d);
 9 getchar();
10 return 0;
11 }
12 输出结果: View
View Code

示例3:

作用:复制后覆盖原有部分数据;

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main(void)
 4 {
 5 char src[] = "******************************";
 6 char dest[] = "abcdefghijlkmnopqrstuvwxyz0123as6";
 7 printf("destination before memcpy: %s\n", dest);
 8 memcpy(dest, src, strlen(src));
 9 printf("destination after memcpy: %s\n", dest);
10 return 0;
11 }
12 输出结果:
13 destination before memcpy:abcdefghijlkmnopqrstuvwxyz0123as6
14 destination after memcpy: ******************************as6
View Code

三、注意事项:
    memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存溢出。

    另外:strcpy只能拷贝字符串,它遇到'\0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存溢出。会造成缓冲区溢出,轻者程序崩溃,重者系统会出现问题!!

 

转载于:https://www.cnblogs.com/YiYA-blog/p/11456085.html

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个代码的问题在于,邻接表的构造,使用了数组list来存储每个节点的链表头指针,但是在为链表头指针赋值时,使用的是list[u-1]而不是list[u],这样会导致最后输出邻接表时,每个节点的链表头指针都是空指针。 修改方法很简单,只需要将list[u-1]改成list[u]即可。 以下是修改后的代码: ```cpp #include <iostream> #include <cstring> using namespace std; const int MAXN = 10; int main() { int n, m, s; cin >> n >> m >> s; // 邻接矩阵 int matrix[MAXN][MAXN]; memset(matrix, 0, sizeof(matrix)); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; matrix[u - 1][v - 1] = matrix[v - 1][u - 1] = 1; } // 输出邻接矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << matrix[i][j] << " "; } cout << endl; } // 邻接表 struct Node { int val; Node *next; }; Node *list[MAXN]; memset(list, 0, sizeof(list)); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; Node *node1 = new Node{v - 1, list[u]}; list[u] = node1; if (!s) { Node *node2 = new Node{u - 1, list[v]}; list[v] = node2; } } // 输出邻接表 for (int i = 0; i < n; i++) { cout << i << ":"; Node *p = list[i]; while (p) { cout << " " << p->val; p = p->next; } cout << endl; } return 0; } ``` 注意这里对list数组的声明方式,我们使用了C++11的新特性,即可以在声明数组时初始化数组元素,这样可以让代码更加简洁,同时也可以避免忘记初始化数组元素的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值